4

I am getting the error: NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802), and I suspect that it is because of querying for images from Parse. Here is the method where I am querying:

func fetchImageForEmployee(employee: PFEmployee, completion: (error: String?, image: UIImage?) -> Void) {
    if (employee.profilePicture == nil) {
        completion(error: "No image file", image: nil)
    } else {
        employee.profilePicture!.getDataInBackgroundWithBlock({ (data, error) -> Void in
            if let error = error {
                let errorString = error.userInfo["error"] as? String
                completion(error: errorString, image: nil)
            } else if (data != nil) {
                let image = UIImage(data: data!)
                completion(error: nil, image: image)
            } else {
                completion(error: nil, image: nil)
            }
        })
    }
}

I also printed the error, and this is what appeared in the debugger: Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UISearchController: 0x13ee44dc0)

I don't know what is going wrong, so all answers are appreciated.

Rehaan Advani
  • 945
  • 1
  • 12
  • 24
  • possible duplicate of [NSURLSession/NSURLConnection HTTP load failed on iOS 9](http://stackoverflow.com/questions/30739473/nsurlsession-nsurlconnection-http-load-failed-on-ios-9) – EnriMR Jul 13 '15 at 08:48

2 Answers2

10

Right click on your Info.plist file > Open As > Source Code, and add the following before the latest </dict> :

<key>NSAppTransportSecurity</key>  
<dict>  
   <key>NSAllowsArbitraryLoads</key>  
   <true/>  
</dict> 

In iOS9, ATS enforces best practices during network calls, including the use of HTTPS. Read more about it in the Apple Documentation.

Sebyddd
  • 4,305
  • 2
  • 39
  • 43
  • I'm having the same damned problem...I have added that xml fragment but I keep on getting "NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)"... why? :( – SagittariusA Sep 21 '15 at 15:42
  • 1
    Please don't do that unless you have a very specific reason (like, you are developing a web browser or rss reader which really needs to access arbitrary sources). Otherwise this will compromise security. – Zsolt Szatmari Nov 03 '15 at 12:58
  • @ZsoltSzatmari, then can you share the solution as this is preventing me from building my app for iOS 10. Any ideas? Same as OP – billy_comic Dec 15 '16 at 22:42
  • Two things: Use the nscurl command line tool with the --ats-diagnostics argument to find to minimum necessary plist modifications so that the app will work with given server. Other is that you need to consult with the network administrator to use ATS-compliant settings on the server. If all else fails, place an exception for that one specific server in your plist. Just keep in mind that this compromises user security. – Zsolt Szatmari Dec 16 '16 at 07:44
  • UPDATE: https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity says "iOS 10.0 or later or macOS 10.12 or later ATS ignores the NSAllowsArbitraryLoads value that you set and instead obeys the other key or keys." – ToolmakerSteve Mar 26 '19 at 14:31
5

I would recommend to not allow just anything.

You need to define the URL you want to apply these rules for in the Info.Plist of your build target.

You can find the correct declaration on Apple's documentation page: https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/

So basically your Info.plist should look like this and include the domain.

Note: for better transparency, I also redeclared the default value for NSAllowsArbitraryLoads to be false

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>yourdomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSAllowsArbitraryLoads</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

Best regards.

In case, you just don't care about all these ssl mess ups (I do not recommend this) and want to only go for debugging your UI, you can alternatively go temporarily and use the non-default for App TransportSecurity and allow just anything:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

I am not sure, whether Apple would let this pass in the AppStore Review ;-)

Btw: to track down all connections of your application by having a look at the established connections. Either you can now sniff the app's traffic, which is generated by third party tools, or you make use of logging all network traffic, referenced here: How can I figure out which URL is being blocked by App Transport Security?

It is easy to track down all occurring errors in this log (not too hard to look for an error code). In this way I was easily able to see what connections were being established and maybe failed, due to load limitations (of course, good software engineers know by heart ;) ) To access the Log you could use for example iFunBox or something, if its on your mobile device.

Short hint: to check, which TLS version the server is running on, I am making use of nmap:

nmap --script ssl-enum-ciphers -p 443 your-domain-without-https.com
Community
  • 1
  • 1
Lepidopteron
  • 6,056
  • 5
  • 41
  • 53
  • 1
    https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity says "iOS 10.0 or later or macOS 10.12 or later ATS ignores the NSAllowsArbitraryLoads value that you set and instead obeys the other key or keys." – ToolmakerSteve Mar 26 '19 at 14:21