NSURLErrorDomain error code -999 in iOS

2020-01-24 07:04发布

问题:

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? I tried searching the web but couldn't find information about it. Thanks in advance.

By the way, I am not using webview on my app. Just the widget api and a show_dialog listener in my Facebook class.

回答1:

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.



回答2:

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.



回答3:

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)


回答4:

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
    }

    }


回答5:

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.



回答6:

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.



回答7:

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



回答8:

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.



回答9:

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