Najlepsza Architektura aplikacji na iOS, która wykonuje wiele żądań sieciowych?

Jestem w trakcie przemyślenia mojego podejścia do architektury zapytań dużej aplikacji, którą rozwijam. Obecnie używam ASIHTTPRequest do składania żądań, ale ponieważ potrzebuję wielu różnych typów żądań w wyniku wielu różnych działań podejmowanych w różnych kontrolerach widoków, staram się wypracować najlepszy system organizowania tych żądań.

Obecnie buduję singleton "requesters", które są przechowywane przez delegata aplikacji i siedzieć i słuchać NSNotifications, które sygnalizują żądanie, muszą być wykonane; wykonują żądanie, nasłuchują odpowiedzi i wysyłają nowe NSNotification z danymi odpowiedzi. To rozwiązuje większość moich problemów, ale nie elegancko obsługuje nieudanych żądań lub jednoczesnych żądań do tego samego żądania singleton.

Czy ktoś ma jakieś sukcesy w opracowaniu przejrzystej architektury OO do tworzenia wielu różnych typów zapytań w aplikacji na iOS?

Author: kevboh, 2011-01-27

4 answers

Po wypróbowaniu kilku podejść, jest to jedna architektura, która daje mi doskonałe wyniki, jest łatwa do udokumentowania, zrozumienia, utrzymania i rozszerzenia:

  • mam jeden obiekt dbający o łączność sieciową, nazwijmy go "menedżerem sieci". Zazwyczaj obiekt ten jest singletonem (utworzonym przy użyciu makra Cocoa singleton Matta Gallaghera ).
  • ponieważ używasz ASIHTTPRequest (co zawsze robię, wspaniałe API) dodaję ASINetworkQueue ivar wewnątrz mojej sieci manager. Robię z Menedżera sieci delegata tej kolejki.
  • tworzę podklasy ASIHTTPRequest dla każdego rodzaju żądań sieciowych, których wymaga moja aplikacja(zazwyczaj dla każdej interakcji REST backend lub punktu końcowego SOAP). Ma to jeszcze jedną zaletę (szczegóły poniżej :)
  • za każdym razem, gdy jeden z moich kontrolerów wymaga danych (refresh, viewdidappear, itd.), network manager tworzy instancję wymaganej podklasy asihttprequest, a następnie dodaje ją do Kolejka
  • ASINetworkQueue zajmuje się problemami z przepustowością (w zależności od tego, czy korzystasz z 3G, EDGE, GPRS czy Wifi, masz większą przepustowość i możesz przetwarzać więcej żądań itp.). Robi to kolejka, co jest fajne (przynajmniej to jedna z rzeczy, które rozumiem, że ta Kolejka robi, mam nadzieję, że się nie mylę :).
  • gdy żądanie zakończy się lub nie powiedzie się, menedżer sieci jest wywoływany(pamiętaj, że menedżer sieci Jest delegatem kolejki).
  • menedżer sieci nie wie, co zrobić z wynikiem każdego żądania; stąd po prostu wywołuje metodę na żądanie! Pamiętaj, że żądania są podklasami ASIHTTPRequest, więc możesz po prostu umieścić kod, który zarządza wynikiem żądania (zazwyczaj deserializacja JSON lub XML do rzeczywistych obiektów, wyzwalanie innych połączeń sieciowych, aktualizacja baz danych, itp.). Umieszczenie kodu w osobnej podklasie request, przy użyciu metody polimorficznej o wspólnej nazwie accross request klas, ułatwia debugowanie i zarządzanie IMHO.
  • na koniec powiadamiam powyższe Kontrolery o interesujących zdarzeniach za pomocą powiadomień; używanie protokołu delegata nie jest dobrym pomysłem, ponieważ w Twojej aplikacji zazwyczaj masz wiele kontrolerów rozmawiających z Twoim menedżerem sieci, a następnie powiadomienia są bardziej elastyczne (możesz mieć kilka kontrolerów reagujących na to samo powiadomienie, itp.).

W każdym razie tak to robię od jakiegoś czasu i szczerze mówiąc działa całkiem dobrze. Mogę rozbudowywać system poziomo, dodając kolejne podklasy ASIHTTPRequest w miarę potrzeb, a rdzeń menedżera sieci pozostaje nienaruszony.

Mam nadzieję, że to pomoże!

 69
Author: Adrian Kosmaczewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 23:03:02

Oto, jak zwykle to robię. Ja też mam obiekt singleton używany do tworzenia żądań sieciowych. W przypadku żądań, które muszą być często składane, mam NSOperationQueue, który akceptuje AFHTTPRequestOperations (lub AFJSONRequestOperations), ponieważ zazwyczaj używam AFNetworking do składania żądań. Dla nich istnieje właściwość completionBlock i failureBlock, która jest wykonywana po pomyślnym lub nieudanym wykonaniu żądania. Na moim singletonie miałbym metodę inicjowania konkretnej sieci request, a jako parametry do tej metody podałbym blok sukcesu i porażki, który można przekazać do bloków zdefiniowanych w metodzie. W ten sposób cała aplikacja może wykonać żądanie sieciowe, a zakres aplikacji w tym momencie jest dostępny singletonowi w bloku przekazywanym do metody. Na przykład...(using 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

I zawsze możesz sprawić, że blok sukcesu przyjmie dowolne parametry, które musisz przekazać.

 1
Author: Jacob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-14 04:47:32

Projekt w pełni załadowany dobrze się czyta.

 0
Author: ohho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 02:38:00

Wypróbuj STNetTaskQueue , który może sprawić, że twoje żądanie będzie wielokrotnego użytku i możliwe do utrzymania.

 0
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-09 15:25:47