0

Je dois effectuer plusieurs appels de service asynchrones dans l'application: didFinishLaunchingWithOptions: méthode de mon délégué d'application afin de récupérer certaines données d'un service à utiliser sur différents contrôleurs de mon application. J'ai le contrôle sur le service, et j'ai conçu l'API pour qu'elle soit aussi RESTful que possible, donc j'ai besoin de faire plusieurs appels pendant l'initialisation de l'application. Ce que je veux faire est de montrer une vue de chargement avec un indicateur de progression - semblable à l'écran de démarrage par défaut de Default.png - et de supprimer cette vue une fois que les appels de service ont terminé et j'ai les valeurs initiales dont j'ai besoin. C'est assez facile à faire s'il n'y a qu'un seul appel de service, puisque je peux simplement accrocher cette logique dans la méthode connectionDidFinishLoading: delegate de NSURLConnection en masquant la vue de chargement et en affichant le contrôleur racine. Cependant, avec plusieurs appels de service, il devient difficile. Je peux "enchaîner" tout ensemble et déclencher une requête, attendre qu'elle se termine/échoue, puis déclencher la deuxième requête, et ainsi de suite jusqu'à ce que j'arrive à la dernière requête. Dans la dernière requête, je cache alors la vue de chargement et affiche la vue normale. Cependant, cela peut devenir compliqué avec plusieurs appels de service, et le code devient difficile à comprendre et à suivre.Effectuer plusieurs appels de service sur l'initialisation de l'application iPhone

Des suggestions sur la meilleure approche pour cela?

Je pense qu'une solution consiste à avoir une classe singleton responsable de la réalisation des appels de service et de l'initialisation de l'application. L'objet singleton lancera toutes les requêtes nécessaires en parallèle au démarrage, et chaque rappel fail/finish vérifiera si chaque requête est terminée. Si toutes les demandes sont terminées, il peut appeler une méthode dans le délégué de l'application et lui indiquer de masquer la vue de chargement, afficher le contrôleur racine, etc.

Réflexions?

Répondre

0

Une autre possibilité consiste à faire notifier chaque rappel de fin de service (NSNotification) au contrôleur de l'indicateur de progression qui a progressé. Vous pouvez également indiquer au contrôleur l'indicateur de progression du nombre de demandes que vous avez l'intention de faire, et le laisser marquer, et faire lui-même un rappel lorsqu'il pense que tout est fait.

+0

De cette façon, vous pouvez lancer toutes les demandes de service en même temps, au lieu de ralentir les choses en les sérialisant. – hotpaw2

+0

Merci. C'est plus ou moins l'approche que je suis allé avec, puisque j'ai seulement quelques demandes et ai juste besoin d'une solution légère. Chaque requête qui se termine informe l'objet principal qu'une requête est terminée, et cet objet principal vérifie si toutes les demandes requises sont terminées avant de charger la vue principale de l'application. – pmc255

0

Je fais quelque chose de similaire avec un NSOperationQueue qui est configuré pour exécuter 1 seule opération à la fois. Voir par exemple WeaveEngine.m et sa méthode synchronizewithServer:credentials:. Je fais la queue de toutes les opérations séparées, qui sont pour la plupart des appels réseau asynchrones.

0

vous pouvez utiliser NSThreading et faire des appels synchrones dans des threads séparés pour chaque chose que vous devez obtenir comme

[NSThread detachNewThreadSelector:@selector(getDataRequest1:) toTarget:self withObject:urlRequest]; 
[NSThread detachNewThreadSelector:@selector(getDataRequest2:) toTarget:self withObject:urlRequest]; 
[NSThread detachNewThreadSelector:@selector(getDataRequest3:) toTarget:self withObject:urlRequest]; 

puis dans le sélecteur pour chaque thread faire quelque chose comme

- (void) getDataRequest1:(NSURLRequest*)urlRequest { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSHTTPURLResponse *urlResponse; 
    NSError *error; 
    NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:&error]; 
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    if ([urlResponse statusCode] < 200 || [urlResponse statusCode] > 299) { 
     //request probably failed 
    }else{ 
     [self performSelectorOnMainThread:@selector(completeRequest1:) withObject:responseData waitUntilDone:NO];   
    } 
    [pool drain]; 
    [responseString release]; 
    [urlRequest release]; 
} 

Bien sûr, il dépend vraiment du nombre de requêtes/threads que vous souhaitez générer. et vous aurez besoin de garder une trace du nombre de spawn vs combien de finition afin que vous puissiez correctement arrêter votre spinner.

Questions connexes