In a little iOS app, I need to retrieve some JSON from a server (similar to a DNS request), and use this response to initiate further connections. To do so, I have an object that cares for the JSON request, using NSURLSession. This object receives the main object (MainController) as delegate, and should call a method, when the JSON data is available. Here's the call in the MainController:
- (void)serverResolve:(NSString *)serverID withPass:(NSString *)pass {
// Must retrieve the server list from JSON
ServerListRetriever *slCom = [[ServerListRetriever alloc] init];
slCom.delegate = self;
[slCom searchServer:serverID usingPass:pass];
}
My problem is that - as soon as the completionHandler - comes into action, the MainController won't do what it should. And I have no idea why???
This is the ServerListRetriever's content (header):
#import "ServerListRetrieverDelegate.h"
@interface ServerListRetriever : NSObject
@property (assign, nonatomic) id <ServerListRetrieverDelegate> delegate;
- (void)searchServer:(NSString *)serverID usingPass:(NSString *)pass;
@end
... (and implementation)
#import "ServerListRetriever.h"
#define SERVER_LIST @"https://www.example.com/hosts.json"
@implementation ServerListRetriever
- (void)searchServer:(NSString *)serverID usingPass:(NSString *)pass
{
// This will work...
[self.delegate serverConnect:@"https://www.example.net/" withPass:pass];
return;
// And if removing the above two lines, this won't work
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:SERVER_LIST]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Handle response
if (error) {
[self.delegate serverListFailedWithError:error];
} else {
// NSLog(@"Retrieved JSON: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// Extract the server URL
NSError *jsonError = nil;
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (jsonError) {
[self.delegate serverListFailedWithError:jsonError];
return;
}
NSString *serverURL = [parsedObject objectForKey:serverID];
NSLog(@"Resolved server URL: %@", serverURL);
// Continue with connection
[self.delegate serverConnect:serverURL withPass:pass];
}
}] resume];
}
@end
The method serverConnect
will be run in both cases, but when called by the completionHandler, a lot of thinks will not work correctly then. I have checked the delegate via debugging, and it has the same ID in both cases.
As I am still struggling with the memory management on iOS, losing some object to early could be an explanation. Yet, I lack the experience to locate the problem. Thanks for ideas and advice!