UIWebView加载时报错:H5中一个按钮点击跳转另一个网页(NSURLErrorCancelled = -999)

96
陈满iOS 22d8d123 271c 4d80 9c59 6990844a9e37
2018.03.19 15:31* 字数 259
  • 问题情境

嵌入金融相关的H5时,可能会有这样的操作:从接口请求得到一个JSON字符串,取出其中html字符串,由UIWebView的loadHTMLString方法渲染该html字符串。当一个按钮点击跳转另一个网页时,会走网页加载错误的代理方法。这时候,需要区分这种错误。

  • 问题代码
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    //把出错信息打出来
    NSLog(@"webview didFailLoadWithError %@ , and err is %@",webView.debugDescription, error.debugDescription);
    [Toast showBottomWithText:@"加载失败,请稍后再试"];
}
  • 问题分析

慢网时,页面内通过按钮等控件跳转可能会出现报错(即使视觉上网页跳转并加载成功)。这是由于当一个按钮点击跳转另一个网页时,会走网页加载错误的代理方法。而走代理方法的原因是因为上一个URL还没完全加载完全,就开始下一个URL的请求,就会走该代理方法。

  • 断点分析error
Error Domain=NSURLErrorDomain Code=-999 “The operation couldn’t be completed.
  • 查看NSURLErrorDomain的枚举类型
NS_ERROR_ENUM(NSURLErrorDomain)
{
    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 API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = -1022,
    NSURLErrorFileDoesNotExist =        -1100,
    NSURLErrorFileIsDirectory =         -1101,
    NSURLErrorNoPermissionsToReadFile =     -1102,
    NSURLErrorDataLengthExceedsMaximum API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) =  -1103,
    NSURLErrorFileOutsideSafeArea API_AVAILABLE(macos(10.12.4), ios(10.3), watchos(3.2), tvos(10.2)) = -1104,
    
    // 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 API_AVAILABLE(macos(10.7), ios(3.0), watchos(2.0), tvos(9.0)) =         -1018,
    NSURLErrorCallIsActive API_AVAILABLE(macos(10.7), ios(3.0), watchos(2.0), tvos(9.0)) =                    -1019,
    NSURLErrorDataNotAllowed API_AVAILABLE(macos(10.7), ios(3.0), watchos(2.0), tvos(9.0)) =                  -1020,
    NSURLErrorRequestBodyStreamExhausted API_AVAILABLE(macos(10.7), ios(3.0), watchos(2.0), tvos(9.0)) =      -1021,
    
    NSURLErrorBackgroundSessionRequiresSharedContainer API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) = -995,
    NSURLErrorBackgroundSessionInUseByAnotherProcess API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) = -996,
    NSURLErrorBackgroundSessionWasDisconnected API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0))= -997,
};

  • 解决方案

取出error,专门忽略该类型错误

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    // 如果是被取消,什么也不干
    if([error code] == NSURLErrorCancelled)  {
        return;
    }
    
    //把出错信息打出来
    NSLog(@"webview didFailLoadWithError %@ , and err is %@",webView.debugDescription, error.debugDescription);
    [Toast showBottomWithText:@"加载失败,请稍后再试"];
}
iOS开发技巧
Web note ad 1