0
NSError* error = nil;

//  load JSON file from the web using url:
NSURL *internetPath = [NSURL URLWithString:url];

NSData *JSONData = [NSData dataWithContentsOfURL:internetPath options:NSDataReadingMappedIfSafe error:&error];

if (!JSONData) {
    NSLog(@"Error = %@", error);
}

The above returns the following error:

Error = Error Domain=NSCocoaErrorDomain Code=256 "The file “antimicrobials.json” couldn’t be opened." UserInfo={NSURL=http://spectrum-prod.herokuapp.com/antimicrobials.json}

I also get the following errors in the console before the above error:

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.

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'

I have also excluded the url in my pList like so:

    <dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>BNDL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>NSAppTransportSecurity</key>
    <key>NSExceptionDomains</key>
    <dict>
        <key>spectrum-prod.herokuapp.com</key>
        <dict>
            <!--Include to allow subdomains-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow HTTP requests-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <!--Include to specify minimum TLS version-->
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
        </dict>
    </dict>

</dict>

This used to work just fine, but now is causing grief.

Any thoughts?

Michael Campsall
  • 4,325
  • 11
  • 37
  • 52

1 Answers1

1

A couple of keys seem to be wrong. NSExceptionAllowsInsecureHTTPLoads should be NSTemporaryExceptionAllowsInsecureHTTPLoads and NSExceptionMinimumTLSVersion should be NSTemporaryExceptionMinimumTLSVersion. Try this:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>thedomain.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

Credit: https://stackoverflow.com/a/31254874/400552

Update: nscurl --ats-diagnostics https://spectrum-prod.herokuapp.com/ seems to suggest everything passes already. So, not sure if you even need any of this.

Update 2: You can also add verbose network logging to your application's scheme's environment variables: CFNETWORK_DIAGNOSTICS: 3

This will print out a path to a file in the console. In this log file, you'll find plenty of detail about each request that is made and if it resulted in error.

Check http://www.nsscreencast.com/episodes/188-app-transport-security

Update 3: Using NSURLSession, the example would look something like this:

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"https://spectrum-prod.herokuapp.com/antimicrobials.json"]
          completionHandler:^(NSData *data,
                              NSURLResponse *response,
                              NSError *error) {
            // handle response
 
  }] resume];

A tutorial on NSURLSession can be found here: http://www.raywenderlich.com/51127/nsurlsession-tutorial

Community
  • 1
  • 1
pshah
  • 2,052
  • 1
  • 21
  • 40
  • I edited my question to show the plist with actual url – Michael Campsall Jan 09 '16 at 00:48
  • Are you sure you are using https in the URL? – pshah Jan 09 '16 at 00:54
  • Just out of curiosity, I am wondering about this "temporary" infix: I searched the apple docs, but the key NSTemporaryExceptionAllowsInsecureHTTPLoads reveals no hits. Do you have an official source for these "temporary" keys? The keys are documented without temporary here https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/ – thst Jan 09 '16 at 00:55
  • @thst I just copy/pasted from a popular stack overflow answer. I have a credit linking to the answer. I did not check the apple docs to be honest. – pshah Jan 09 '16 at 00:57
  • I saw that, but they don't give a proper apple doc page, too. That's why I asked you, but thanks. – thst Jan 09 '16 at 00:57
  • @MichaelCampsall Did you try NSURLSession? I think that's a better API for making network requests than what you are using anyways. – pshah Jan 09 '16 at 01:03
  • @pshah How would the same code look using NSURLSession? – Michael Campsall Jan 09 '16 at 20:38
  • @MichaelCampsall I updated my answer to include an example using NSURLSession. – pshah Jan 09 '16 at 20:44
  • @pshah It worked! Thank you so much. You were right, I did not need to exempt the url as I could use Heroku's SSL. NSURLSession was the key. Thanks again. – Michael Campsall Jan 10 '16 at 19:06