简体   繁体   English

如何修复 iOS 中的“NSURLErrorDomain 错误代码 -999”

[英]How to fix "NSURLErrorDomain error code -999" in iOS

I've been trying to use Corona SDK's Facebook API to post the score on the game I'm developing on facebook.我一直在尝试使用 Corona SDK 的 Facebook API 来发布我在 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:在我第一次尝试发布到 facebook 时,登录和用户身份验证后出现此错误:

NSURLErrorDomain error code -999 NSURLErrorDomain 错误代码 -999

Then, it won't post on facebook.然后,它不会在 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.顺便说一句,我没有在我的应用程序上使用 webview。 Just the widget api and a show_dialog listener in my Facebook class.在我的 Facebook 类中只有小部件 api 和一个 show_dialog 侦听器。

The error has been documented on the Mac Developer Library (iOS docs)该错误已记录在Mac 开发人员库(iOS 文档)中

The concerned segment from the documentation will be:文档中的相关部分将是:

URL Loading System Error Codes URL 加载系统错误代码

These values are returned as the error code property of an NSError object with the domain “NSURLErrorDomain”.这些值作为域“NSURLErrorDomain”的 NSError 对象的错误代码属性返回。

 enum { NSURLErrorUnknown = -1, NSURLErrorCancelled = -999, NSURLErrorBadURL = -1000, NSURLErrorTimedOut = -1001,

As you can see;如你看到的; -999 is caused by ErrorCancelled . -999是由ErrorCancelled引起的 This means: another request is made before the previous request is completed.这意味着:在前一个请求完成之前发出另一个请求。

hjpotter92 is absolutely right, I just want to provide solution for my case. hjpotter92 是绝对正确的,我只是想为我的案例提供解决方案。 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在登录页面>按登录>弹出加载对话框>调用登录服务>关闭对话框>推送另一个屏幕>调用另一个服务->导致错误-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.奇怪的是,这个问题只发生在 iOS 7 上。

Just wanted to add here, when receiving a -999 "cancelled" the problem usually is one of two things:只是想在这里补充一下,当收到-999 "cancelled" ,问题通常是两件事之一:

  • You're executing the exact same request again.您再次执行完全相同的请求。
  • You're maintaining a weak reference to your manager object that gets deallocated prematurely.您正在维护对过早解除分配的manager对象的弱引用。 (Create strong reference) (创建强引用)

I have faced the same error with Alamofire and it was because the certificate pinning.我在使用 Alamofire 时遇到了同样的错误,这是因为证书固定。 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 :除了Ramon写的内容之外,在收到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.您通过在 datatask 对象上调用.cancel()或因为您在 session 对象上使用了.invalidateAndCancel()来取消该任务。 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 theApple Developer Documentation :如果您使用委托创建自定义会话,则应调用.invalidateAndCancel().finishTasksAndInvalidate()来解决会话与其委托之间的强引用,如Apple 开发人员文档中所述

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 :如果您对这种日志记录行为感到疑惑,我在Apple Developer 论坛中找到了以下解释:

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.作为解释,在 iOS 10 中我们引入了一个新的日志系统范围的日志架构(观看WWDC 2016 Session 721 Unified Logging and Activity Tracing了解详细信息)和许多子系统,包括 CFNetwork,正在迁移到那。 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:我没有使用 Corona SDK 的 Facebook API,但是在使用 Alamofire 时遇到了这个问题,根据我在互联网上找到的帖子, secondRequest总是在执行中取消并出现错误 -999,原因是session属性在完成之前被deinit异步工作,因为它超出了范围,我最终通过手动deinit会话属性解决了这个问题,这样编译器就不会在错误的位置取消它:

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.我们公司的应用程序在iOS中有很多-999错误。 I have searched around, find the reason has two, like the network task has been dealloc or the certificate isn't valid.找了一圈,发现原因有两个,比如网络任务被dealloc或者证书无效。 But I have checked our code, these two aren't possible.但是我检查了我们的代码,这两个是不可能的。 I am using Alamofire which is using URLSession.我正在使用使用 URLSession 的 Alamofire。 Luckily, our company's android app's network is normal.还好我们公司的android app的网络是正常的。 So we check the difference.所以我们检查差异。 We found the http request from iOS is Http2.0, while android is Http1.1.我们发现来自iOS的http请求是Http2.0,而android是Http1.1。 So we force the backend http support version down to http1.1, then -999 error count descends!!!所以我们强制后端http支持版本降到http1.1,然后-999错误计数下降!!!

I think there maybe some bug in Apple's URLSession.我认为 Apple 的 URLSession 中可能存在一些错误。 Check the link New NSURLSession for every DataTask overkill?检查每个 DataTask 矫枉过正的链接New NSURLSession? for some detail thoughts一些细节的想法

请检查是否在URLSessionDataTask上调用cancel()来修复

NSURLErrorDomain Code=-999 "cancelled"

I was getting this error in iOS specific version of Xamarin app.我在 Xamarin 应用程序的 iOS 特定版本中收到此错误。 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.不确定根本原因,但在我的情况下,可以通过使用 post 方法而不是 get 来解决它,因为它可以在请求正文中传递服务器上下文——无论如何这更有意义。 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. Android / Windows / 该服务都处理带有内容的 GET,但在 iOS 应用程序中将变得部分无响应,然后在日志中吐出 999 NSUrlErrorDomain 内容。 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 .对于我的Cordova 项目(或类似项目) ,结果是插件问题 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 )验证这一点的最简单方法是通过重新cordova create <path> Cordova 项目( cordova create <path> ) 以及所需的平台 ( cordova platform add <platform name> ) 并使用详细标志 (--verbose) 添加每个插件来重新开始在下载插件、添加到项目并为每个平台安装时,您可以在控制台日志中查看是否有任何问题( cordova plugin add cordova-plugin-device --verbose

Recap: cordova create <path> cordova platform add <platform name> cordova plugin add cordova-plugin-device --verbose回顾: 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,解决方法是使用零字节数据而不是 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.框架文档没有说明为什么 from bodyData 是可选类型,或者当它为零时会发生什么。

We solved this problem by reloading the web view when it failed loading.我们通过在加载失败时重新加载 Web 视图来解决这个问题。

extension WebViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.reload()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM