Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 535
Rehaan Advani Avatar asked Dec 06 '22 21:12

Rehaan Advani


2 Answers

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.

like image 103
Sebyddd Avatar answered Dec 11 '22 09:12

Sebyddd


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
like image 35
Lepidopteron Avatar answered Dec 11 '22 11:12

Lepidopteron