Search code examples
iosuiwebviewnsurlconnectionios9nsapptransportsecurity

How to print out failed NSURLConnection urls to find set of NSAppTransportSecurity exceptions?


The webviews in my apps have been getting these errors from the new iOS 9 NSAppTransportSecurity standards:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

I don't know where this error is being generated but essentially I want to find out how to know which URL was attempted?

After that I can configure the plist appropriately.

So far I have set a breakpoint in - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error but this code is not called when getting the error.


Solution

  • If you're just debugging, set the CFNETWORK_DIAGNOSTICS environment variable to 3, e.g.

    setenv("CFNETWORK_DIAGNOSTICS", "3", 1);
    

    at the beginning of your app, before you call anything that would potentially cause the CFNetwork framework code to load (i.e. at the beginning of main). You should get the URLs in the console.

    If you need to do this in a shipping app in a way that would let you debug it remotely, register an NSURLProtocol object globally, and in the canInitWithRequest: method, print the value and return NO. That should happen early enough in the process that it works even with strict transport security enabled.

    Example:

    @interface MyProtocol: NSURLProtocol
    @end
    
    @implementation MyProtocol
    + (BOOL)canInitWithRequest:(NSURLRequest *)request
    {
        NSLog(@"Request: %@\n", request); // Log it in whatever way you need.
        return NO;
    }
    @end
    
    ...
    
    // Somewhere else, e.g. in applicationDidFinishLaunching:, do this:
    [NSURLProtocol registerClass:[MyProtocol class]];
    

    Ordering isn't guaranteed, but the failed URL is likely to be printed roughly right before the failure.