Search code examples
iosswiftherokuparse-platformapp-transport-security

why swift parse .getDataInBackgroundWithBlock blocked as cleartext http request?


I'm writing a swift iOS app that uses Parse hosted on Heroku. As far as I know, all data transport is over HTTPS and I do not have the App Transport Security workaround done to info.plist (and intends to keep it that way). Up until now all Parse queries have executed without errors both on the simulator and on actual iphone running 9.3.3 or 9.3.5.

That is until just now when I added this code which works flawlessly on the simulator but crashes on the iphone due to a cleartext request made over HTTP. But why would a request be made over HTTP?

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier(idInstagramFeedCell, forIndexPath: indexPath) as! InstagramFeedCell

        let imageFile = feed[indexPath.row].imageFile as PFFile
        imageFile.getDataInBackgroundWithBlock({ (data, error) in
            if let image = UIImage(data: data!) {
                cell.postImage.image = image
            } else {
                cell.postImage.image = UIImage(named: defaultImageFile)
            }
        })

        cell.postUsername.text = feed[indexPath.row].username
        cell.postCaption.text = feed[indexPath.row].caption
        return cell
    }

The offending line is isolated to imageFile.getDataInBackgroundWithBlock({ ... }) since if that is commented out, the app does not crash on the iphone.

The errors in console are:

2016-08-18 18:51:56.074 ParseStarterProject-Swift[3694:2189084] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
2016-08-18 18:51:56.081 ParseStarterProject-Swift[3694:2189342] [Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.12.0)
2016-08-18 18:51:56.081 ParseStarterProject-Swift[3694:2189342] [Error]: Network connection failed. Making attempt 1 after sleeping for 1.373388 seconds.
2016-08-18 18:51:56.084 ParseStarterProject-Swift[3694:2189342] [Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.12.0)

Oddly this poster has kind of the opposite problem. Any help would be much appreciated.

Additional Observations: I actually just saw it crash even on the simulator. Initially all of the images uploaded (ie posted) to Parse are photos from the simulator itself. When the app running on an actual device tries to download these images, it crashed as per above. I have since using the app posted a couple of photos from the actual device to Parse. When the app running on the simulator tries to download those photos, the simulator crashes with same error as above.


Solution

  • Courtesy @luizmb on GitHub, the solution is simple. Apparently there is this little known (at least to me) Parse server variable publicServerURL which needs to contain same value as serverURL. If you rely on the Heroku Parse console to manage your instance, you can set it by defining the environ variable PARSE_PUBLIC_SERVER_URL. If you have a customize instance, you need to add this line to index.js when you instantiate Parse:

    publicServerURL: process.env.PARSE_PUBLIC_SERVER_URL || process.env.PARSER_SERVER_URL || process.env.SERVER_URL,
    

    However there are two caveats: 1) If you have any image files uploaded before implementing this solution as I did, you may still encounter the ATS error. To resolve this you need to delete all such images from your instance as I had to do. 2) I could only make it work on an actual device (iOS 9.3.5) but running exactly the same app on the simulator (iOS 9.3), the ATS error does not show up but these do which I have not found a way to bypass:

    NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
    [Error]: An SSL error has occurred and a secure connection to the server cannot be made. (Code: 100, Version: 1.14.2)
    [Error]: Network connection failed. Making attempt 4 after sleeping for 15.848020 seconds.
    

    This solution enables your app to download image files from Parse without having to turn ATS off via AllowArbitraryLoads in info.plist. Please see here for details.