URL background session downloadTask error - ios

I want to know whether completion handler blocks are supported in background sessions.
Right now, I'm getting this error:
libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
There are two ways for a session to download:
use delegate methods
use completion handlers like below.
However, when I'm using the following code I'm getting the error.
let session_config = URLSessionConfiguration.background(withIdentifier: "myID");
let session = URLSession(configuration: session_config);
let task=session.downloadTask(with: request) { (url,response,error) in
}
task.resume()

Related

NSInternalInconsistencyException - Animator is already stopped

Currently getting the following runtime exception
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Animator <UIViewPropertyAnimator(0x600003f24200) [stopped] interruptible> is already stopped!'
Because of the following line of code
// other code up here that modifies offsetAnimator
...
// stop any current running animations on offset
if let offsetAnimator = offsetAnimator {
offsetAnimator.stopAnimation(false) // this line is where the exception gets raised
offsetAnimator.finishAnimation(at: .end)
}
What is perplexing, however, is why this error is NOT readily reproducible
// doing this doesn't always result in an error
if let offsetAnimator = offsetAnimator {
offsetAnimator.stopAnimation(false)
offsetAnimator.finishAnimation(at: .end)
offsetAnimator.stopAnimation(false)
offsetAnimator.finishAnimation(at: .end)
}
What on earth is happening? Can someone explain to me why this error is occurring?
Why does it seem to only happen sporadically? Shouldn't calling .stop twice always trigger it?

MLKit Digital Ink Recognition throws error when initializing recognizer

I'm developing a Flutter app which makes use of the Digital Ink Recognition of ML Kit to recognize handwriting.
I have the following code to perform the recognition on iOS (swift code).
let ink = Ink.init(strokes: mlStrokes)
let identifier = DigitalInkRecognitionModelIdentifier(forLanguageTag: languageTag)
if identifier == nil {
flutterResult(FlutterError(code: "ERROR", message: "No model for language tag found or the language tag could not be parsed", details: nil))
}
let model = DigitalInkRecognitionModel.init(modelIdentifier: identifier!)
// Get a recognizer for the given language
let options: DigitalInkRecognizerOptions = DigitalInkRecognizerOptions.init(model: model)
digitalInkRecognizer = DigitalInkRecognizer.digitalInkRecognizer(options: options)
digitalInkRecognizer.recognize(
ink: ink,
completion: {
(result: DigitalInkRecognitionResult?, error: Error?) in
if let result = result {
var flutterCandidates : [[String: Any?]] = []
for candidate in result.candidates {
flutterCandidates.append(
["text" : candidate.text, "score" : candidate.score]
)
}
// Return recognised candidates to Flutter.
self.flutterResult(flutterCandidates)
} else {
self.flutterResult(FlutterError(code: "ERROR", message: "Unable to recognize handwriting", details: error))
}
})
I'm recognizing a single letter at a time.
This works well for some time, the correct letter is returned in the completion callback and then send back to my Flutter app, but after the method is called a few times (~20), the following error is thrown in the console and my app crashes.
I1025 10:03:01.607888 1 lstm_recognizer.cc:77] Loaded tflite model.
2021-10-25 10:03:01.621992+0200 Runner[796:125890] Unsupported value: Error Domain=com.google.mlkit Code=13 "Unable to initialize recognizer: generic::internal: Unable to mmap file descriptor (Cannot allocate memory). (research/handwriting/util/mmap_data.cc:49)" UserInfo={NSLocalizedDescription=Unable to initialize recognizer: generic::internal: Unable to mmap file descriptor (Cannot allocate memory). (research/handwriting/util/mmap_data.cc:49)} of type NSError
2021-10-25 10:03:01.623350+0200 Runner[796:125890] *** Assertion failure in -[FlutterStandardWriter writeValue:], FlutterStandardCodec.mm:334
2021-10-25 10:03:01.632824+0200 Runner[796:125890] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unsupported value for standard codec'
*** First throw call stack:
(0x20ff2e180 0x20f1069f8 0x20fe4788c 0x21090bb38 0x1034b8138 0x1034b8898 0x1034b5890 0x100c4f0f4 0x100c522fc 0x100c523a8 0x1052536f4 0x105254c78 0x1052626fc 0x20febfb20 0x20febaa58 0x20feb9fb4 0x2120bb79c 0x23c197c38 0x100c4f464 0x20f97d8e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
The error seems linked to a memory issue (Unsupported value: Error Domain=com.google.mlkit Code=13 "Unable to initialize recognizer: generic::internal: Unable to mmap file descriptor (Cannot allocate memory), but I don't find the reason.
Do I have to release something after the digitalInkRecognizer.recognize() method is called? I can't find anything related to this in the documentation.
Thanks in advance for any idea.
I found that the issue was linked to the lifecycle management of the ModelManager and recognizer which I was recreating each time I was performing the digital ink recognition.
After changing this behaviour and keeping a reference to them once created, the issue was solved.
This example was helpful to understand how to work with the ModelManager (see implementation of the StrokeManager).

Google Autocomplete function Crash after Call

I am using Google PlaceAutoComplete method to get suggestions of the Addess that is entered in textField.
func placeAutocomplete(text:String) {
let placesClient = GMSPlacesClient()
let filter = GMSAutocompleteFilter()
filter.type = .Address
placesClient.autocompleteQuery("New Delhi", bounds: nil, filter: nil) { (results, error) in
guard error == nil else {
print("Autocomplete error \(error)")
return
}
self.addressArray.removeAll()
for result in results! {
self.addressArray.append(result.attributedFullText.string)
print("Result \(result.attributedFullText.string) with placeID \(result.placeID)")
}
}
}
When i call this method. It crashes, say the Following error.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary boolValue]: unrecognized selector sent to instance 0x7fe338f01e40'
I have tried to found using exception breakpoint but doesn't work.
Can any have idea, where i am wrong?
I have resolved the issue by correcting in the plist for "allow arbitrary loads" in App Transport security Settings. I was typed it true but its type was set string instead for Boolean
Somewhere a NSDictionary is being passed to the code where it is expecting a something that can be interpreted as a boolean such as an NSString or NSNumber. I don't see anything like that in the code you provided. If exception breakpoints aren't working I would try adding normal breakpoints somewhere and stepping over code until it crashes. You could also try removing certain sections and code and seeing if the crash is still happening, this will let you narrow down what portion of your code is to blame.

xcode present segue on restful callback (swift)

I am self taught Swift user and trying to do something simple but it's got me pretty stumped. I have a simple registration form. After submitting the items for registration, I want to move the page to a "how it works" page via a segue, but ONLY when my restful API returns success. Here's what I have so far; feel free to send me a better way to do this as well. All criticisms are welcome.
let myUrl = NSURL(string:"http://www.example.com/scripts/Register.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "email=\(email)&password=\(pass)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if (error != nil) {
println("Error: \(error)")
return
}
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
var showTutorial : Bool = false
if let parseJSON = json {
var returnValue = parseJSON["status"] as? String
println("Status: \(returnValue)")
var isUserRegistered: Bool = false
if (returnValue == "Success") {
showTutorial = true
} else if (returnValue == "Error") {
// handle error
}
}
// if successful registration, show how it works page
if (showTutorial) {
self.performSegueWithIdentifier("howItWorksSegue", sender: self)
}
}
task.resume()
I have a segue named howItWorksSegue attached to this view controller going to the HowItWorksViewController. I'm receiving this error from Xcode:
2015-10-12 21:22:43.261 ZiftDine[11396:2307755] Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3347.44.2/Keyboard/UIKeyboardTaskQueue.m:374
2015-10-12 21:22:43.391 ZiftDine[11396:2307755] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
Anything done with UI should be done on the main thread, try wrapping you performSegue call like this:
dispatch_async(dispatch_get_main_queue(),{
self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})
#Swinny89 gave the solution to your problem but some explanation is in order.
If you read the description of dataTaskWithRequest:completionHandler:, which is the method you are using (although your Swift code uses trailing closure syntax to drop the completionHandler label and put the closure outside the parentheses) it says:
completionHandler: The completion handler to call when the load
request is complete. This handler is executed on the delegate queue.
Then if you read the description of the init method sessionWithConfiguration:delegate:delegateQueue: it says:
queue: A queue for scheduling the delegate calls and completion
handlers. If nil, the session creates a serial operation queue for
performing all delegate method calls and completion handler calls.
Serial operation queues run on a different thread.
So, taking all of those pieces of information together, it means that your completion closure is going to be executed on a thread other than the main thread.
A cardinal rule of iOS/Mac development is that you must do all UI calls from the main thread. If a call changes anything on the screen, it's a UI call.
Your code is invoking performSegueWithIdentifier: from a background thread. It changes what's displayed on the screen, so it must be a UI call. Therefore it needs to be run on the main thread.
The GCD function dispatch_async(), with a queue of dispatch_get_main_queue(), submits a closure to be run on the main dispatch queue, a queue that runs on the main thread.
So Swinny's solution fixes your problem.
The take-away here:
Any time you are running code in a closure, stop and think: "Am I positive that this closure will always be run on the main thread?" If the answer is no, enclose the code in a call to dispatch_async(dispatch_get_main_queue(), like Swinny's answer.
The answers by #Duncan C and #Swinny89 are good. For anyone coming in from Google, the syntax in Swift 3 has changed a little:
DispatchQueue.main.async(execute: {
self.performSegueWithIdentifier("howItWorksSegue", sender: self)
})

iOs: Error while cancelling performrequest

In my iOs SpriteKit application, I play voice overs using the AVAudioPlayer after a certain amount of seconds after a user action, like so:
[self.vOSoundManager performSelector:#selector(playVoiceOverWithName:) withObject:#"Voiceover_waarhondenbrokken3" afterDelay:8.0];
[self.vOSoundManager setRequestBeingPerformed:TRUE];
When a user performs another action, the sound should stop playing. I do this like so:
if(self.vOSoundManager.requestBeingPerformed){
[NSObject cancelPreviousPerformRequestsWithTarget:self.vOSoundManager];
[self.vOSoundManager stopCurrentSound];
}
The stopCurrentSound method in VoiceOverSoundManager:
- (void)stopCurrentSound{
self.playing = FALSE;
[self.voiceOverPlayer stop];
self.voiceOverPlayer = nil;
}
When the cancelPreviousPerformRequestsWithTarget method is called, I get the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[VoiceOverSoundManager name]: unrecognized selector sent to instance 0x155a9590'
I have no idea why. Does anyone have a solution?
If you are using one instance of player to play all sounds in your game, this could be a problem if you don't re-create it after stopCurrentSound method is executed:
self.voiceOverPlayer = nil;
Try to remove this line or create a new player instance.

Resources