How to fix "NSURLErrorDomain error code -999" in iOS - ios

I've been trying to use Corona SDK's Facebook API to post the score on the game I'm developing on facebook. However, I'm having a problem with it. During the first time I try to post to facebook, I get this error after login and user authentication:
NSURLErrorDomain error code -999
Then, it won't post on facebook. What are possible causes of this error and how can I address it?
By the way, I am not using webview on my app. Just the widget api and a show_dialog listener in my Facebook class.

The error has been documented on the Mac Developer Library(iOS docs)
The concerned segment from the documentation will be:
URL Loading System Error Codes
These values are returned as the error code property of an NSError
object with the domain “NSURLErrorDomain”.
enum
{
NSURLErrorUnknown = -1,
NSURLErrorCancelled = -999,
NSURLErrorBadURL = -1000,
NSURLErrorTimedOut = -1001,
As you can see; -999 is caused by ErrorCancelled. This means: another request is made before the previous request is completed.

Just wanted to add here, when receiving a -999 "cancelled" the problem usually is one of two things:
You're executing the exact same request again.
You're maintaining a weak reference to your manager object that gets deallocated prematurely. (Create strong reference)

hjpotter92 is absolutely right, I just want to provide solution for my case. Hopefully it is useful for you as well. Here is my situation:
On log in page > press log in > pop up loading dialog > call log in service > dismiss dialog > push another screen > call another service --> cause error -999
To fix it, I put a delay between dismissing dialog and pushing new screen:
[indicatorAlert dismissWithClickedButtonIndex:0 animated:YES];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"HomeSegue" sender:nil];
});
It is strange that this issue happens on iOS 7 only.

I have faced the same error with Alamofire and it was because the certificate pinning.
The certificate wasn't valid anymore, so I had to remove it and add the new one.
Hope it helps.

In addition to what Ramon wrote, there is a third possible reason when receiving a NSURLErrorDomain -999 cancelled:
You cancelled the task while it was executing either by calling .cancel() on the datatask object or because you used .invalidateAndCancel() on the session object. If you are creating a custom session with a delegate, you should call .invalidateAndCancel() or .finishTasksAndInvalidate() to resolve the strong reference between the session and its delegate, as mentioned in the Apple Developer Documentation:
The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until it exits.
If you are wondering about this logging behaviour, I found the following explanation in the Apple Developer forums:
By way of explanation, back in iOS 10 we introduced a new logging system-wide logging architecture (watch WWDC 2016 Session 721 Unified Logging and Activity Tracing for the details) and lots of subsystem, including CFNetwork, are in the process of moving over to that. Until that move is fully finished you’re going to encounter some weird edge cases like this one.

I didn't use Corona SDK's Facebook API but I encountered this problem when using Alamofire, the secondRequest always cancel in execution with the error -999, according to the posts I found on internet, the reason is that session property is deinit before completion of async work since it is out of the scope, I finally solved this problem by deinit the session property manually so the compiler won't deinit it at wrong position:
class SessionManager {
var session:SessionManager?
init() {
self.session = SessionManager(configuration:URLSessionConfiguration.ephemeral)
}
private func firstRequest() {
guard let session = self.session else {return}
session.request(request_url).responseData {response in
if let data=response.data {
self.secondRequest()
}
}
private func secondRequest() {
guard let session = self.session else {return}
session.request(request_url).responseData {response in
if let data=response.data {
self.secondRequest()
}
//session will no longer be needed, deinit it
self.session = nil
}
}

Our company's app has many -999 error in iOS. I have searched around, find the reason has two, like the network task has been dealloc or the certificate isn't valid. But I have checked our code, these two aren't possible. I am using Alamofire
which is using URLSession. Luckily, our company's android app's network is normal. So we check the difference. We found the http request from iOS is Http2.0, while android is Http1.1. So we force the backend http support version down to http1.1, then -999 error count descends!!!
I think there maybe some bug in Apple's URLSession. Check the link New NSURLSession for every DataTask overkill? for some detail thoughts

Please check If you call cancel() on URLSessionDataTask to fix
NSURLErrorDomain Code=-999 "cancelled"

I was getting this error in iOS specific version of Xamarin app. Not sure the underlying cause, but in my case was able to work around it by using post method instead of get for anything passing the server context in the request body -- which makes more sense anyway. Android / Windows / the service all handle the GET with content, but in iOS app will become partially unresponsive then spit out the 999 NSUrlErrorDomain stuff in the log. Hopefully, that helps someone else running into this. I assume the net code is getting stuck in a loop, but could not see the code in question.

For my Cordova project (or similar), turns out it was a plugin issue. Make sure you're not missing any plugins and make sure they're installed properly without issue.
Easiest way to verify this is simply to start fresh by recreating the Cordova project (cordova create <path>) along with the required platforms (cordova platform add <platform name>) and add each plugin with the verbose flag (--verbose) so that you can see if anything went wrong in the console log while the plugin is being downloaded, added to project and installed for each platform (cordova plugin add cordova-plugin-device --verbose)
Recap:
cordova create <path>
cordova platform add <platform name>
cordova plugin add cordova-plugin-device --verbose

For my case, I used an upload task post that did not need body contents:
// The `from: nil` induces error "cancelled" code -999
let task = session.uploadTask(with: urlRequest, from: nil, completionHandler: handler)
The fix is to use zero byte data instead of nil,
let task = session.uploadTask(with: urlRequest, from: Data(), completionHandler: handler)
The framework documentation doesn't specify why the from bodyData is an optional type, or what happens when it is nil.

We solved this problem by reloading the web view when it failed loading.
extension WebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
webView.reload()
}
}

Related

Firestore document creation fails without an error

Edit3: Okay, it seems like it's an issue with Firebase, someone else tweeted about having the same issue. I also contacted support.
A piece of Swift code that handles creating documents suddenly stopped working. No errors are thrown, Firebase doesn't complain in the log and I can verify from the console that the document is not created, I can verify that the device has a healthy internet connection. I also disabled offline persistence for Firebase just to be sure.
When I try debugging it, the debugger jumps straight over the block that handles errors or successes, never running it (i.e. never finishing the Firestore request?).
Here is the code
func createConversation(){
let conversation : [String : Any] = ["owners" : [
UserProfile().getProfile().uid!],
"seeking" : true,
"timestamp" : Timestamp(date: Date())
]
var ref: DocumentReference? = nil
ref = DB().firestore().collection("Conversations").addDocument(data: conversation){ err in
if let err = err {
print("Error creating a convo: \(err)")
} else {
print("Conversation created with ID: \(ref!.documentID)")
StateMachine().action(a: .seekingStarted(ref!.documentID))
}
print("Conversation Creation finished")
}
let documentID = ref?.documentID
print(ref.debugDescription)
}
I'm not sure how to approach this issue, any ideas?
Edit: Okay, the issue is not limited to this block of code, it looks like Firebase is not communicating with the servers. I've waited for more than 5min for the addDocument to return(with error or success) but that never happened.
I noticed that at the initiation of the App BoringSSL complains a bit but this is not new and I don't have problems with the other Firebase services, they work just fine - reading and creating data with no problems.
Edit2: Apparently I can fetch collections and documents from Firestore, the issue seems to be limited to document/collection creation.
The document creation operation takes a little time, if you place the breakpoint inside the asynchronus completion block you will surely get an error or success.

AVPlayer removing observer crash in Swift 2.2

I have a video app that I built a while back in Swift 1 and I've been trying to migrate to Swift 2.2. It all (finally) works apart from a weird crash to do with observers.
func removeObservers()
{
print("REMOVING OBSERVERS")
if ( !self.is_image && self.player != nil ) {
if (self.player?.observationInfo != nil) {
self.player?.removeObserver(self, forKeyPath: "currentItem.status")
self.player?.removeObserver(self, forKeyPath: "readyForDisplay")
}
}
NSNotificationCenter.defaultCenter().removeObserver(self)
}
This worked previously using SwiftTryCatch but with the lines in place crashes with "'Cannot remove an observer for the key path "readyForDisplay" from because it is not registered as an observer.'" OR with that an observer is registered on a deallocated object if I comment it out.
If I add a do { } catch {} to it I get an error that "this does not throw" and it just crashes the same. How do I go about putting this in some form of try-catch format?
In Swift 2, the libs got annoyingly strict about errors that are truly unexpected (which throw) versus errors that the programmer could have prevented (which do not throw, but just crash your app).
(I’m not a fan of this distinction, or at least not of all the specific decisions Apple made about which errors fall in which category. The JSON API verges on the nonsensical in this department. But…we work with the API we’ve got.)
The NSKeyValueObserving docs say:
It is an error to call removeObserver:forKeyPath: if the object has not been registered as an observer.
“It is an error” is Apple code for “you are responsible for never doing this, and if you do, your app will crash in an uncatchable way.”
In these situations, there is usually an API call you can make to check the validity of the thing you’re about to do. However, AFAIK, there’s no KVO API call you can make to ask, “Is X observing key path Y of object Z?” That means you have three options:
Figure out why you’re trying to remove an observer from something you’re not observing, and prevent that using your program’s own internal logic.
Keep a weak instance var for “player I’m observing,” and check that for a match before attempting to remove the observer.
Add self as an observer before removing it. (I’m pretty sure that a redundant add is OK.)
Since you are making a call removeObserver(self) at the end of the method, why cant you uncomment above code? Because removeObserver(self) removes all the observers if registered any. I hope this solves your issue.
NSNotificationCenter.defaultCenter().removeObserver(self)
status is a property of either AVPlayer or AVPlayerItem.
readyForDisplay is a property of AVPlayerLayer

GameCenter: "The connection to service named com.apple.gamed was interrupted"

I get this error message
The connection to service named com.apple.gamed was interrupted, but
the message was sent over an additional proxy and therefore this proxy
has become invalid.
sometimes when calling
loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
What does it mean?
I'm on iOS 9.3.2
This is the worst possible answer, but it's my own experience with loading matches, I'm sorry to say: sometimes it works, sometimes it doesn't. I've received this error message before, and then had it go away after no code changes at all. Just try again.
Ok now I have more findings. Forget my comment to the other answer.
In my case I got the message when I did not use the #escaping keyword on a closure parameter of a function (using Swift 3 where closures are by default non-escaping). This function was called with a closure that did not refer to self (because it was not needed). However, that function called another function, forwarding the closure.
So in the end my closure ended up without a reference.
I recommend you keep a copy of your block that you use as an argument to loadMatchesWithCompletionHandler. This way the block is not released prematurely.
This also explains why the error occurs just sometimes and not always. It's typical for memory release issues.

0_ os_lock_corruption_abort in NSURLProtocol

I've built a custom NSURLProtocol which is used by a WebView whilst it browses. But at seemingly random times (between a 20 seconds or a few minutes into browsing) I am getting an EXC_BREAKPOINT and the app stops running in my NSURLProtocol.
The relevant part of my NSURLProtocol is below, it's the last line which is showing the EXC_BREAKPOINT
self.mutableData = NSMutableData(data: data!)
self.response = response
self.client?.URLProtocol(self, didReceiveResponse: response!, cacheStoragePolicy: NSURLCacheStoragePolicy.Allowed)
self.client?.URLProtocol(self, didLoadData: data!)
self.client?.URLProtocolDidFinishLoading(self)
The Xcode error is visible below:
I'm totally bamboozled on this one. Does anyone have an idea what might be causing this, and how to fix it?
Thank you!
Sam
There's not enough context for me to fully understand the code here, much less guess what's wrong, but basically what's happening is that there's a lock (mutex) that has been deallocated, but is still being used somewhere down in the NSURL* stack.
This probably points to something not getting retained properly, but it is anybody's guess what or where. It might even be that your protocol is not getting retained properly, in which case you might be able to fix it by assigning your protocol object to a property on itself until after you call your last delegate method, then nulling it out.
With that said, there's reason to believe that this is a bug in the OS itself, so while you try to work around it, you should also file a bug. It will get duped to the other dozen or so bugs from other people who have asked this same question both here and on the Apple developer forums. :-)

CloudKit method call hung up

When app starts some preliminary process take place. Sometimes it is done quickly in some second, and sometimes It does not end, but without any error it hung up.
I.e. at launch client always fetch the last serverChangedToken. and sometimes it just hung up it does not complete. I am talking about production environment, developer works well. So this route get called, but some times it does not finishes. Any idea why? I do not get any error, timeout.
let fnco = CKFetchNotificationChangesOperation(previousServerChangeToken: nil)
fnco.fetchNotificationChangesCompletionBlock = {newServerChangeToken, error in
if error == nil {
serverChangeToken = newServerChangeToken
dispatch_sync(dispatch_get_main_queue(), {
(colorCodesInUtility.subviews[10] ).hidden = false
})
} else {
Utility.writeMessageToLog("error 4559: \(error!.localizedDescription)")
}
dispatch_semaphore_signal(sema)
}
defaultContainer.addOperation(fnco)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
I know it is not recommended to use semaphores to control flow of the CloudKit method calls.
Do you think the last two line can be swapped? First dispatch_semaphore_wait and then addOperation be called?
Strange that app worked for iOS 8, this bug arise only in iOS 9.
Adding the following line of code will probably solve your problem:
queryOperation.qualityOfService = .UserInteractive
In iOS 9 Apple changed the behavior of that setting. Especially when using cellular data you could get the behaviour you described.
The documentation states for the .qualityOfService this:
The default value of this property is NSOperationQualityOfServiceBackground and you should leave that value in place whenever possible.
In my opinion this is more a CloudKit bug than a changed feature. More people have the same issue. I did already report it at https://bugreport.apple.com

Resources