Dans une petite application iOS, j'ai besoin de récupérer un fichier JSON d'un serveur (similaire à une requête DNS) et d'utiliser cette réponse pour initier d'autres connexions. Pour ce faire, j'ai un objet qui s'occupe de la requête JSON, en utilisant NSURLSession. Cet objet reçoit l'objet principal (MainController) en tant que délégué et doit appeler une méthode lorsque les données JSON sont disponibles. Voici l'appel dans le MainController:NSURLSession et les délégués
- (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];
}
Mon problème est que - dès le completionHandler - entre en action, le MainController ne fera pas ce qu'il devrait. Et je n'ai aucune idée pourquoi ???
Ceci est le contenu de ServerListRetriever (en-tête):
#import "ServerListRetrieverDelegate.h"
@interface ServerListRetriever : NSObject
@property (assign, nonatomic) id <ServerListRetrieverDelegate> delegate;
- (void)searchServer:(NSString *)serverID usingPass:(NSString *)pass;
@end
... (et mise en œuvre)
#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
La méthode serverConnect
sera lancé dans les deux cas, mais lorsqu'il est appelé par le completionHandler , beaucoup de pense ne fonctionnera pas correctement alors. J'ai vérifié le délégué par débogage, et il a le même ID dans les deux cas.
Comme je suis toujours aux prises avec la gestion de la mémoire sur iOS, perdre un objet au début pourrait être une explication. Pourtant, je manque d'expérience pour localiser le problème. Merci pour vos idées et conseils!
En attendant, j'ai aussi essayé de se débarrasser de la classe supplémentaire 'ServerListRetriever' et d'écrire son code directement dans le MainViewController. Cela signifie qu'aucun délégué n'est utilisé du tout. Pas de changement. – BurninLeo