1

I have encountered a very strange and frustrating issue when building WatchKit and Today extensions using Xcode 7 (GM) as well as Xcode 7.1 (beta 1). Using AFNetworking 2.0 (up to date as of this posting), I call the following code from any of these extensions:

AFHTTPRequestOperation *op = [manager GET:endpoint parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {

    NSLog(@"Response: %@", responseObject);

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    NSLog(@"ERROR: %@", error);
}];
NSLog(@"Called!");

The expectation here would be that one of the two blocks would be called after Called! is logged. However, neither one is ever executed.

Strangely, however, if I call the following line:

[op cancel];

I get the expected failure block's log outputted. Nothing else I've tried (turning off Internet connectivity on my computer, creating a nonsense URL, etc.) has been able to get the failure block to execute.

At this point I'm not sure if I've been trying to debug this too late into the night, if this is a bug with Xcode 7.x, or if I'm making a mistake somewhere. Any help is appreciated!

rebello95
  • 8,100
  • 5
  • 42
  • 63

1 Answers1

0

Looks like this problem stemmed from a couple of different things.

The base of the problem is iOS 9's new App Transport Security rules. These rules can be overridden using certain keys in the app's info.plist file. However, I was having difficulty getting the override keys to save properly using Xcode 7.0 (GM) in the extensions because it would throw an error when attempting to run the project.

Step 1: In Xcode 7.1 beta 1, the above keys are actually supported by Xcode (and even autocomplete), so I was able to add these keys to my WatchKit and today extension info.plist files:

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

Step 2: At this point, AFNetworking was still hanging and wasn't allowing connections to go through. Even now I'm not sure why this is happening. Instead, I resorted to using the standard iOS classes for making network calls, which ended up finally resolving my problem and being able to run requests as usual:

NSMutableURLRequest *connection = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://myurl.com/xyz"]];
[connection setValue:"Bearer myAuthorization" forHTTPHeaderField:@"Authorization"];
[NSURLConnection sendAsynchronousRequest:connection queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    if (error == nil) {

        NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        //Do stuff with data

    } else {

        //Error handling
    }
}]; 

Hopefully something here helps someone in the future. This was a complete nightmare for a good day and a half to figure out!

Community
  • 1
  • 1
rebello95
  • 8,100
  • 5
  • 42
  • 63