Saving Siri INCreateNoteIntent in coredata - swift3

I know Siri is setup correctly, hence the image below. But the content is not saving in core data. Siri said it created the note, but it's not showing in coredata. This is what I tried so far, any help would be appreciated.
class IntentHandler: INExtension, INCreateNoteIntentHandling {
func handle(intent: INCreateNoteIntent, completion: #escaping (INCreateNoteIntentResponse) -> Void) {
let context = Context.shared.persistentContainer.viewContext
let newNote = Notes(context: context)
newNote.textView = intent.content?.description
// newNote.textView = intent.title?.spokenPhrase
// Save the context
do {
try context.save()
let response = INCreateNoteIntentResponse(code: INCreateNoteIntentResponseCode.success, userActivity: nil)
response.createdNote = INNote(title: intent.title!, contents: [intent.content!], groupName: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil)
completion(response)
} catch {
completion(INCreateNoteIntentResponse(code: INCreateNoteIntentResponseCode.failure, userActivity: nil))
}
}
func confirm(intent: INCreateNoteIntent, completion: #escaping (INCreateNoteIntentResponse) -> Void) {
completion(INCreateNoteIntentResponse(code: INCreateNoteIntentResponseCode.ready, userActivity: nil))
}
public func resolveContent(for intent: INCreateNoteIntent, with completion: #escaping (INNoteContentResolutionResult) -> Swift.Void) {
let result: INNoteContentResolutionResult
if let content = intent.content {
result = INNoteContentResolutionResult.success(with: content)
} else {
result = INNoteContentResolutionResult.needsValue()
}
completion(result)
}
}
Whenever I tried to save a note

Related

How can i set profile pic against firebase user authentication with email?

i am developing an employee management app thats why i need to save profile picture against employee id or email .In firebase database what is the process and how can i design database through source code.In swift 3,xcode 8.3.2,ios 10.
You need to store the profile Image on the firebase storage,
after that imageURL will be retrieved. After the imageURL is retrieved you need to save it on the firebase database as a child of the userId.
Refer the code below
func handleRegister() {
guard let email = self.emailTextField.text, let password = self.passwordTextField.text, let name = self.nameTextField.text else {
print("Form is not valid")
return
}
Auth.auth().createUser(withEmail: email, password: password) { (user: User?, error) in
if error != nil {
print(error!)
return
}
guard let uid = user?.uid else {
return
}
//success
let imageName = NSUUID().uuidString
let storageRef = Storage.storage().reference().child("\(imageName).png")
if let uploadData = UIImageJPEGRepresentation(self.profileImageView.image!, 0.1) {
storageRef.putData(uploadData, metadata: nil, completion:
{ (metadata, error) in
if error != nil {
print(error!)
return
}
print(metadata!)
if let progileImageURL = metadata?.downloadURL()?.absoluteString {
let values = ["name": name, "email": email, "profileImageUrl": progileImageURL]
self.registerUserIntoDatabaseWithUID(uid: uid, values: values as [String : AnyObject])
}
})
}
}
}
func registerUserIntoDatabaseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference()
let userRef = ref.child("users").child(uid)
userRef.updateChildValues(values, withCompletionBlock: { (err, ref) in
if err != nil {
print(err!)
return
}
print("Saved user successfully into Firebase db")
self.messagesController1?.checkIfUseLoggedin()
self.dismiss(animated: true, completion: nil)
})
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
print(editedImage)
}
else if let orignalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = orignalImage
print(orignalImage)
}
if let selectedImage = selectedImageFromPicker {
self.profileImageView.image = selectedImage
}
self.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("picker cancled")
self.dismiss(animated: true, completion: nil)
}

My Image stop animation when I do a request in swift 3

I've got a UImage, that needs to rotate until my call to the server ends.
But my image rotates only one time and stops after that.
My code:
#IBOutlet var imgLoader: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global(qos: .userInitiated).async {
self.getSalons()
}
self.launchLoaderDesign()
NotificationCenter.default.addObserver(forName:NSNotification.Name("LoadAllShowNotification"), object: nil, queue: nil, using: notificationFinish)
}
func getSalons() -> Void {
let api:ApiSvain = ApiSvain()
api.getHeartStrokeSalon()
api.getSalonForHomePage()
}
func launchLoaderDesign() -> Void {
var posImg:Int = 0
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: { () -> Void in
self.imgLoader.transform = self.imgLoader.transform.rotated(by: CGFloat(M_PI_2))
})
{ (finished) -> Void in
self.launchLoaderDesign()
}
}
func getSalonForHomePage(){
let url = "MY_URL"
Alamofire.request(url, method: .get).validate().responseJSON
{ response in
if (response.error == nil)
{
let json = JSON(response.result.value!)
for (index, element) in json
{
let show:Show = Show(json: element, index: index)
StaticData.arrayOfShow.append(show)
}
NotificationCenter.default.post(name:NSNotification.Name("LoadAllShowNotification"), object: nil, userInfo: nil)
}
else
{
print(response.error!)
}
}
}
My function getSalonForHomePage sends a notification, and when I catch it I use performSegue to move to my new page.
I think my problem came from my misunderstanding of multi-threading.
Ps: I am using alamofire 4, for send request to my server.

How to save variable in closure to external variable?

I'm trying to create a custom PickerView that gets it's data from an API call to a web-server. The problem I'm having is saving the parsed data into an external variable so that the PickerView protocol methods can access it.
// API Call / Parsing using Alamofire + Unbox
static func makeApiCall(completionHandler: #escaping (CustomDataStructure) -> ()) {
Alamofire.request(webserverUrl, method: .get).responseObject { (response: DataResponse<Experiment>) in
switch response.result {
case .success:
if var configParams = response.result.value {
let inputConfigs = removeExtrasParams(experiment: response.result.value!)
let modifiedViewModel = modifyViewModel(experiment: &configParams, inputConfigs: inputConfigs)
completionHandler(modifiedViewModel)
}
case .failure(_):
break
}
}
}
// Custom PickerClass
class CustomPickerView: UIPickerView {
fileprivate var customDS: CustomDataStructure?
override init() {
super.init()
dataSource = self
delegate = self
SomeClass.makeApiCall(completionHandler: { customds in
self.customDS = customds
})
}
...
}
extension CustomPickerView: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if let customds = customDS {
if let customDSValues = customds.inputs.first?.value {
return customDSValues[row]
}
}
return "apple"
}
}
extension CustomPickerView: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if let customds = customDS {
return customds.inputs.values.count
} else {
return 0
}
}
}
The problem I'm having is that customDS returns nil everytime.
What am I doing wrong here?
In the completion block of makeApiCall simply reload your pickerView's component on main thread and you all set to go.
SomeClass.makeApiCall(completionHandler: { customds in
self.customDS = customds
DispatchQueue.main.async {
self.reloadComponent(0)
}
})

api youtube in swift 3 error 403

I am trying to use youtube api in ios swift, and following this tutorial
http://www.appcoda.com/youtube-api-ios-tutorial/
HTTP Status Code = 403
Error while loading channel details: nil
I'm using swift 3
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(textField.text)&type=\(type)&key=\(apiKey)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
// Create a NSURL object based on the above string.
let targetURL = URL(string: urlString)
// Get the results.
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
// Convert the JSON data to a dictionary object.
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<String, AnyObject>
// Get all search result items ("items" array).
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
// Loop through all search results and keep just the necessary data.
for i in 0 ..< items.count {
let snippetDict = items[i]["snippet"] as! Dictionary<String, AnyObject>
// Gather the proper data depending on whether we're searching for channels or for videos.
if self.segDisplayedContent.selectedSegmentIndex == 0 {
// Keep the channel ID.
self.desiredChannelsArray.append(snippetDict["channelId"] as! String)
}
else {
// Create a new dictionary to store the video details.
var videoDetailsDict = Dictionary<String, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<String, AnyObject>)["videoId"]
// Append the desiredPlaylistItemDataDict dictionary to the videos array.
self.videosArray.append(videoDetailsDict)
// Reload the tableview.
self.tblVideos.reloadData()
}
}
} catch {
print(error)
}
// Call the getChannelDetails(…) function to fetch the channels.
if self.segDisplayedContent.selectedSegmentIndex == 0 {
self.getChannelDetails(true)
}
}
else {
print("HTTP Status Code = \(HTTPStatusCode)")
print("Error while loading channel videos: \(error)")
}
// Hide the activity indicator.
self.viewWait.isHidden = true
})
return true
}
// MARK: Custom method implementation
func performGetRequest(_ targetURL: URL!, completion: #escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: NSError?) -> Void) {
// let request = NSMutableURLRequest(url: targetURL)
// request.httpMethod = "GET"
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
/* let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data, (response as! HTTPURLResponse).statusCode, error)
})
} as! (Data?, URLResponse?, Error?) -> Void)*/
/* let task = session.dataTask(with: request, completionHandler: ({ (data: Data?, response: URLResponse?, error: NSError?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data as Data?, (response as! HTTPURLResponse).statusCode, error)
})
} as! (Data?, URLResponse?, Error?) -> Void))*/
let task = session.dataTask(with: request) { data, response, error in DispatchQueue.main.async { completion(data, (response as! HTTPURLResponse).statusCode, error as? NSError) } }
task.resume()
}
First of all the JSON dictionary representation in Swift 3 is [String:Any] (aka Dictionary<String,Any>)
Second of all in Swift 3 all parameter labels in closures have been removed
func performGetRequest(_ targetURL: URL, completion: #escaping (Data?, Int, NSError?) -> Void) {
Do not use implicit unwrapped optionals for method parameter types. Either use regular optional (?) or non-optional.
Error 403 means Forbidden Access. Make sure you have the correct apiKey from google/youtube developer.
I also used the appcoda youtube api tutorial (which is in Swift 2 I think) and this is a working version of mine for swift 3.
func getVideosForChannelAtIndex() {
let urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=\(playlistID)&maxResults=\(maxResults)&key=\(apiKey)"
// Create a NSURL object based on the above string.
let targetURL = URL(string: urlString)
// Fetch the playlist from Google.
performGetRequest(targetURL!) { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
do {
self.videos = []
// Convert the JSON data into a dictionary.
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<AnyHashable, Any>
// Get all playlist items ("items" array).
let items:Array<Dictionary<AnyHashable, Any>> = resultsDict["items"] as! Array<Dictionary<AnyHashable, Any>>
// Use a loop to go through all video items.
// for var i=0; i<items.count; ++i
for i in 0 ..< items.count {
let playlistSnippetDict = (items[i] as Dictionary<AnyHashable, Any>)["snippet"] as! Dictionary<AnyHashable, Any>
let video = Video()
video.title = playlistSnippetDict["title"] as? String
// video.thumbnail =
video.videoId = (playlistSnippetDict["resourceId"] as? Dictionary<AnyHashable, Any>)?["videoId"] as? String
guard let thumbnail = ((playlistSnippetDict["thumbnails"] as? Dictionary<AnyHashable, Any>)?["high"] as? Dictionary<AnyHashable, Any>)?["url"] as? String else {
video.thumbnail = UIImage(named: "Icon1024x1024")
return
}
guard let url:URL? = URL(string: thumbnail), let data:Data? = try? Data(contentsOf: url!) else {
video.thumbnail = UIImage(named: "Icon1024x1024")
return
}
if let dataImage = data {
video.thumbnail = UIImage(data: dataImage)
} else {
video.thumbnail = UIImage(named: "Icon1024x1024")
}
self.videos.append(video)
// Reload the tableview.
self.tblVideos.reloadData()
}
} catch {
print("json error: \(error)")
}
} else {
print("")
print("HTTP Status Code = \(HTTPStatusCode)")
print("")
//Show alertDialog here with Error
print("Error while loading videos: \(error?.localizedDescription)")
let alert = UIAlertView(title: "Oops!", message: error?.localizedDescription, delegate: self, cancelButtonTitle: "OK")
alert.show()
}
// Hide the activity indicator.
self.viewWait.isHidden = true
}
}
This is for the performGetRequest
func performGetRequest(_ targetURL: URL, completion: #escaping (_ data: Data?, _ HTTPStatusCode: Int?, _ error: Error?) -> Void) {
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
let task = session.dataTask(with: request) { data, response, error in
DispatchQueue.main.async(execute: {
completion(data, (response as? HTTPURLResponse)?.statusCode, error)
})
}
task.resume()
}

Swift3: Passing parameters into NSFetchRequest method

I use a general CoreData query method in my project.
func query(table: String, searchPredicate: NSPredicate) -> [AnyObject]
{
let context = app.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: table)
fetchRequest.predicate = searchPredicate
let results = try! context.fetch(fetchRequest)
return results
}
In Swift 3 this doesn't work. I found this on Apple's web site:
func findAnimals()
{
let request: NSFetchRequest<Animal> = Animal.fetchRequest
do
{
let searchResults = try context.fetch(request)
... use(searchResults) ...
}
catch
{
print("Error with request: \(error)")
}
}
Using the Apple example, how would I pass Animal in to the method as a parameter to make findAnimals more generic?
I haven't tried this but I think something like this would work...
func findCoreDataObjects<T: NSManagedObject>() -> [T] {
let request = T.fetchRequest
do
{
let searchResults = try context.fetch(request)
... use(searchResults) ...
}
catch
{
print("Error with request: \(error)")
}
}
You have to make the entire function generic and so you have to tell it what type T is when calling it.
someObject.findCoreDataObjects<Animal>()
I think that should do the job. Not entirely certain though as I'm new to generics myself :D
How about this.
func query<T: NSManagedObject>(table: String, searchPredicate: NSPredicate) -> [T] {
let context = app.managedObjectContext
let fetchRequest: NSFetchRequest<T> = NSFetchRequest(entityName: table)
fetchRequest.predicate = searchPredicate
let results = try! context.fetch(fetchRequest)
return results
}
Here is the final result that may help someone:
import Foundation
import Cocoa
func addRecord<T: NSManagedObject>(_ type : T.Type) -> T
{
let entityName = T.description()
let context = app.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
let record = T(entity: entity!, insertInto: context)
return record
}
func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int
{
let recs = allRecords(T.self)
return recs.count
}
func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
if let predicate = search
{
request.predicate = predicate
}
if let sortDescriptors = multiSort
{
request.sortDescriptors = sortDescriptors
}
else if let sortDescriptor = sort
{
request.sortDescriptors = [sortDescriptor]
}
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func deleteRecord(_ object: NSManagedObject)
{
let context = app.managedObjectContext
context.delete(object)
}
func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil)
{
let context = app.managedObjectContext
let results = query(T.self, search: search)
for record in results
{
context.delete(record)
}
}
func saveDatabase()
{
let context = app.managedObjectContext
do
{
try context.save()
}
catch
{
print("Error saving database: \(error)")
}
}
Call it with:
let name = "John Appleseed"
let newContact = addRecord(Contact.self)
newContact.contactNo = 1
newContact.contactName = name
let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %#", name))
for contact in contacts
{
print ("Contact name = \(contact.contactName), no = \(contact.contactNo)")
}
deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %#", name))
recs = recordsInTable(Contact.self)
print ("Contacts table has \(recs) records")
saveDatabase()
I use that way in my projects:
static func retrieveRecords<T: NSManagedObject>(table: String, sortDescriptorKey: NSSortDescriptor? = nil) -> [T] {
do {
let fetchRequest: NSFetchRequest<T> = NSFetchRequest(entityName: table)
fetchRequest.sortDescriptors = [sortDescriptorKey!]
let results = try context.fetch(fetchRequest)
print("\(results)")
return results
} catch let error {
print("Could not fetch \(error.localizedDescription)")
return []
}
}
And to call it:
personen = retrieveRecords(table: "Person", sortDescriptorKey: NSSortDescriptor(key: #keyPath(Person.nachname), ascending: true, selector: #selector(NSString.localizedCompare)))