iphone plan La meilleure architecture pour une application iOS qui fait de nombreuses requêtes réseau?




meilleur application pour plan 3d (4)

Le projet fully-loaded est une bonne lecture.

Je suis en train de repenser mon approche de l'architecture de demande d'une grande application que je développe. J'utilise actuellement ASIHTTPRequest pour effectuer des demandes, mais comme j'ai besoin de nombreux types de demandes suite à de nombreuses actions différentes effectuées dans différents contrôleurs de vue, j'essaie de définir le meilleur système pour organiser ces demandes.

Je suis en train de créer des "demandeurs" uniques qui sont retenus par le délégué de l'application et sont à l'écoute des notifications NSNotifications qui signalent qu'une demande doit être faite; ils font la demande, écoutent la réponse et envoient une nouvelle NSNotification avec les données de réponse. Cela résout la plupart de mes problèmes, mais ne gère pas avec élégance les demandes échouées ou les demandes simultanées adressées au même demandeur singleton.

Quelqu'un a-t-il réussi à concevoir une architecture OO claire permettant d'effectuer différents types de demandes dans une application iOS?


Voici comment je le fais généralement. Moi aussi, j'ai un objet singleton utilisé pour faire des requêtes réseau. Pour les demandes qui doivent être faites souvent, j'ai une NSOperationQueue qui accepte AFHTTPRequestOperations (ou AFJSONRequestOperations) puisque j'utilise généralement AFNetworking pour faire des demandes. Pour ceux-ci, il existe une propriété completionBlock et failureBlock qui est exécutée en cas de succès ou d'échec de la demande. Sur mon objet singleton, j'aurais une méthode pour lancer une requête réseau particulière et, en tant que paramètres de cette méthode, j'inclurais un bloc de succès et d'échec pouvant être transmis aux blocs définis dans la méthode. De cette manière, toute l'application peut faire une demande réseau et le périmètre de l'application à ce stade est disponible pour le singleton dans le bloc transmis à la méthode. Par exemple ... (en utilisant ARC)

        @implementation NetworkManager

    -(void)makeRequestWithSuccess:(void(^)(void))successBlock failure:(void(^)(NSError *error))failureBlock

    {
        NSURL *url = [NSURL URLWithString:@"some URL"];

        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];

        [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            [responseObject doSomething];

            if (successBlock)
                dispatch_async(dispatch_get_main_queue(), successBlock);

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

            if (failureBlock)
                dispatch_async(dispatch_get_main_queue(), ^{
                    failureBlock(error);
                });
        }];

        [self.operationQueue addOperation:op];
    }
@end

Et vous pouvez toujours faire en sorte que le bloc de succès prenne tous les paramètres que vous devez transmettre.


Après avoir essayé plusieurs approches, voici une architecture qui me donne d’excellents résultats, qui est facile à documenter, à comprendre, à maintenir et à étendre:

  • J'ai un seul objet s'occupant de la connectivité réseau, appelons-le un "gestionnaire de réseau". Cet objet est généralement un singleton (créé à l'aide de la macro Cocoa singleton de Matt Gallagher ).
  • Puisque vous utilisez ASIHTTPRequest (ce que je fais toujours, une API merveilleuse), j'ajoute un ivar ASINetworkQueue dans mon gestionnaire de réseau. Je fais du gestionnaire de réseau le délégué de cette file d'attente.
  • Je crée des sous-classes de ASIHTTPRequest pour chaque type de requête réseau requis par mon application (généralement, pour chaque interaction REST dorsale ou point de terminaison SOAP). Cela a un autre avantage (voir ci-dessous pour plus de détails :)
  • Chaque fois que l'un de mes contrôleurs requiert des données (actualisation, viewDidAppear, etc.), le gestionnaire de réseau crée une instance de la sous-classe ASIHTTPRequest requise, puis l'ajoute à la file d'attente.
  • ASINetworkQueue prend en charge les problèmes de bande passante (selon que vous soyez en 3G, EDGE, GPRS ou Wifi, vous avez plus de bande passante et vous pouvez traiter davantage de demandes, etc.). Ceci est fait par la file d'attente, ce qui est cool (du moins, c'est une des choses que je comprends de cette file d'attente, j'espère que je ne me trompe pas :).
  • Chaque fois qu'une demande se termine ou échoue, le gestionnaire de réseau est appelé (rappelez-vous que le gestionnaire de réseau est le délégué de la file d'attente).
  • Le gestionnaire de réseau ne sait pas quoi faire avec le résultat de chaque demande. par conséquent, il appelle simplement une méthode sur la demande ! N'oubliez pas que les demandes sont des sous-classes de ASIHTTPRequest. Vous pouvez donc simplement mettre le code qui gère le résultat de la demande (généralement, désérialisation de JSON ou XML en objets réels, déclenchant d'autres connexions réseau, mettant à jour les magasins Core Data, etc.). Le fait de placer le code dans chaque sous-classe de requêtes distincte, à l'aide d'une méthode polymorphe avec un nom commun entre les classes de requêtes, facilite très largement le débogage et la gestion de IMHO.
  • Enfin, je signale aux contrôleurs ci-dessus des événements intéressants utilisant des notifications; L'utilisation d'un protocole de délégation n'est pas une bonne idée, car dans votre application, de nombreux contrôleurs communiquent avec votre gestionnaire de réseau. Les notifications sont alors plus flexibles (vous pouvez avoir plusieurs contrôleurs répondant à la même notification, etc.).

En tout cas, c’est comme ça que je le fais depuis un moment et, franchement, ça marche plutôt bien. Je peux étendre le système horizontalement, en ajoutant plus de sous-classes ASIHTTPRequest selon mes besoins et le noyau du gestionnaire de réseau reste intact.

J'espère que ça aide!


Essayez STNetTaskQueue , qui peut rendre votre demande réutilisable et maintenable.







asihttprequest