iOS WKWebView ErrorDomain NSURLErrorDomain Code=-999

so.png

引言

问题的现象是 WKWebView 明明已经加载成功并完成了,还是调用了失败的代理方法,弹出了 toast。

正文

问题是如何发生的呢?先上代码:

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [MBProgressHUD showError:NSLocalizedString(@"网络加载失败!", nil)];
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [MBProgressHUD showError:NSLocalizedString(@"网络加载失败!", nil)];
}

因为最近一直在 iOS 12 以上的系统开发,开发过程中一直没有发现问题,到上传 AppStore 从 TestFlight 下载测试的时候,一个测试发现的问题。手机系统是 iOS 11.4.1,然后连上打断点调试,发现每次都会调用失败的代理方法。为什么呢?经过查资料发现原来是请求被 cancel 掉了。-999 的错误代码是 NSURLErrorCancelled,结合项目的实际流程,一开始加载 本地html 在接收到请求成功后,重新加载线上的 url, 只是为了让加载快一点,没想到还给自己挖坑了。

NS_ENUM(NSInteger)
{
    NSURLErrorUnknown =             -1,
    NSURLErrorCancelled =           -999,
    NSURLErrorBadURL =              -1000,
    NSURLErrorTimedOut =            -1001,
    NSURLErrorUnsupportedURL =          -1002,
    NSURLErrorCannotFindHost =          -1003,
    NSURLErrorCannotConnectToHost =         -1004,
    NSURLErrorNetworkConnectionLost =       -1005,
    NSURLErrorDNSLookupFailed =         -1006,
    NSURLErrorHTTPTooManyRedirects =        -1007,
    NSURLErrorResourceUnavailable =         -1008,
    NSURLErrorNotConnectedToInternet =      -1009,
    NSURLErrorRedirectToNonExistentLocation =   -1010,
    NSURLErrorBadServerResponse =       -1011,
    NSURLErrorUserCancelledAuthentication =     -1012,
    NSURLErrorUserAuthenticationRequired =  -1013,
    NSURLErrorZeroByteResource =        -1014,
    NSURLErrorCannotDecodeRawData =             -1015,
    NSURLErrorCannotDecodeContentData =         -1016,
    NSURLErrorCannotParseResponse =             -1017,
    NSURLErrorAppTransportSecurityRequiresSecureConnection NS_ENUM_AVAILABLE(10_11, 9_0) = -1022,
    NSURLErrorFileDoesNotExist =        -1100,
    NSURLErrorFileIsDirectory =         -1101,
    NSURLErrorNoPermissionsToReadFile =     -1102,
    NSURLErrorDataLengthExceedsMaximum NS_ENUM_AVAILABLE(10_5, 2_0) =   -1103,
    
    // SSL errors
    NSURLErrorSecureConnectionFailed =      -1200,
    NSURLErrorServerCertificateHasBadDate =     -1201,
    NSURLErrorServerCertificateUntrusted =  -1202,
    NSURLErrorServerCertificateHasUnknownRoot = -1203,
    NSURLErrorServerCertificateNotYetValid =    -1204,
    NSURLErrorClientCertificateRejected =   -1205,
    NSURLErrorClientCertificateRequired =   -1206,
    NSURLErrorCannotLoadFromNetwork =       -2000,
    
    // Download and file I/O errors
    NSURLErrorCannotCreateFile =        -3000,
    NSURLErrorCannotOpenFile =          -3001,
    NSURLErrorCannotCloseFile =         -3002,
    NSURLErrorCannotWriteToFile =       -3003,
    NSURLErrorCannotRemoveFile =        -3004,
    NSURLErrorCannotMoveFile =          -3005,
    NSURLErrorDownloadDecodingFailedMidStream = -3006,
    NSURLErrorDownloadDecodingFailedToComplete =-3007,
 
    NSURLErrorInternationalRoamingOff NS_ENUM_AVAILABLE(10_7, 3_0) =         -1018,
    NSURLErrorCallIsActive NS_ENUM_AVAILABLE(10_7, 3_0) =                    -1019,
    NSURLErrorDataNotAllowed NS_ENUM_AVAILABLE(10_7, 3_0) =                  -1020,
    NSURLErrorRequestBodyStreamExhausted NS_ENUM_AVAILABLE(10_7, 3_0) =      -1021,
    
    NSURLErrorBackgroundSessionRequiresSharedContainer NS_ENUM_AVAILABLE(10_10, 8_0) = -995,
    NSURLErrorBackgroundSessionInUseByAnotherProcess NS_ENUM_AVAILABLE(10_10, 8_0) = -996,
    NSURLErrorBackgroundSessionWasDisconnected NS_ENUM_AVAILABLE(10_10, 8_0)= -997,
};

所以,解决方法就是在代理方法里面加一个判断,对,只是这一个方法:

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    // 如果是被取消,这里根据自身实际业务需求进行编辑
    if (error.code == NSURLErrorCancelled) {
        return;
    }
    [MBProgressHUD showError:NSLocalizedString(@"网络加载失败!", nil)];
}

注:如果是手动调用 WKWebView 的 stopLoading 方法,也会出发该代理方法。

结尾

一开始的时候提到了在 iOS 12 上并没有这个问题。对,因为 iOS WKWebView 在 iOS 12 进行了一些改变,比如 userAgent 等。所以在 iOS 12 上不会出现。

记录一下就当是提醒自己不要再写类似的 bug。

你可能感兴趣的:(iOS WKWebView ErrorDomain NSURLErrorDomain Code=-999)