2011-02-02 26 views
54

Napisałem wiele aplikacji na iOS, które komunikowały się z backendem. Prawie za każdym razem używałam pamięci podręcznej HTTP do kwerend pamięci podręcznej i parsowania danych odpowiedzi (JSON) w obiektach C obiektów. W przypadku tego nowego projektu zastanawiam się, czy podejście oparte na danych podstawowych miałoby sens.Dane podstawowe klienta (iOS) do buforowania danych z serwera Strategia

Oto co pomyślałem:

Klient iOS sprawia żądanie do serwera i analizowania obiektów z JSON do modeli CoreData.

Za każdym razem, gdy potrzebuję nowego obiektu, zamiast pobierać serwer bezpośrednio, parsuję CoreData, aby sprawdzić, czy już wysłałem to żądanie. Jeśli ten obiekt istnieje i nie wygasł, używam pobranego obiektu.

Jednakże, jeśli obiekt nie istnieje lub wygasł (w tym miejscu zastosowana zostanie pewna logika buforowania), pobierałbym obiekt z serwera i odpowiednio aktualizował CoreData.

myślę mając taką architekturę mógł pomóc z następujących: 1. uniknąć niepotrzebnych zapytań do backend 2. Pozostawić pełne wsparcie dla przeglądania w trybie offline (Można jeszcze zrobić relacyjne zapytania z DataCore RDBMS)

Oto moje pytanie do SO Gods:

  1. Wiem, że ten rodzaj wymaga kodu logiki backendu po raz drugi (Server + CoreData), ale czy to przesada?
  2. Jakiekolwiek ograniczenia, które mam pod szacunkami?
  3. Każdy inny pomysł?

Odpowiedz

90

Po pierwsze, jeśli jesteś zarejestrowanym deweloperem systemu iOS, powinieneś mieć dostęp do sesji WWDC 2010. Jedna z tych sesji zawierała trochę tego, o czym mówisz: "Sesja 117, Budowanie komfortu użytkownika opartego na serwerze". Powinieneś być w stanie find it on iTunes.

Inteligentne połączenie REST/JSON/Core Data działa jak czar i oszczędza dużo czasu, jeśli planujesz ponowne użycie kodu, ale będzie wymagać wiedzy o HTTP (i wiedzy o Core Data, jeśli chcesz aplikacje do wykonywania dobrze i bezpiecznie).

Kluczem jest więc zrozumienie REST i podstawowych danych.

  • Zrozumienie REST oznacza Metody Zrozumienie HTTP (GET, POST, PUT, DELETE ... głowę?) I odpowiedź-Codes (2xx, 3xx, 4xx, 5xx) i nagłówków (Last-Modified, IF- Zmodyfikowane - od, Etag, ...)

  • Zrozumienie podstawowych danych oznacza wiedzę na temat projektowania modelu, ustawiania relacji, obsługi czasochłonnych operacji (usuwanie, wstawianie, aktualizowanie) i jak robić rzeczy w tło, dzięki czemu Twój interfejs użytkownika pozostaje elastyczny. I oczywiście, jak zapytać lokalnie na sqlite (np. Dla wstępnego pobierania identyfikatorów, aby można było aktualizować obiekty, zamiast tworzyć nowe, gdy uzyska się ich odpowiedniki po stronie serwera).

Jeśli planują wdrożyć wielokrotnego użytku API dla zadań, o których mowa, należy upewnić się, że rozumiesz spoczynku i danych Core, bo tam będzie prawdopodobnie zrobić najwięcej kodowania. (Istniejące API - ASIHttpRequest dla warstwy sieciowej (lub dowolnej innej) i dowolna dobra biblioteka JSON (np. SBJSON) do analizy będą wykonywać zadanie.

Kluczem do uczynienia tego API prostym jest zapewnienie, aby twój serwer zapewniał usługę RESTful, a Twoje jednostki posiadały wymagane atrybuty (dateCreated, dateLastModified itp.), Aby można było tworzyć żądania (łatwo można to zrobić za pomocą ASIHttpRequest, czy to GET, PUT, POST, DELETE) i dodaj odpowiednie nagłówki Http, np dla warunkowego GET: If-Modified-Since.

Jeśli już czujesz się komfortowo z Core Data i może obsługiwać JSON i może łatwo wykonać żądanie HTTP i obsługiwać Odpowiedzi (ponownie, ASIHttpRequest bardzo pomaga, ale są inne, lub możesz trzymać się niższego poziomu Apple NS -Klasy i zrób to sam), wtedy wszystko, czego potrzebujesz, to ustawić poprawne nagłówki HTTP dla twoich Żądań i odpowiednio obsłużyć Http-Response-Codes (zakładając, że twój serwer jest REST-ful).

Jeśli Twoim głównym celem jest uniknięcie ponownej aktualizacji jednostki danych podstawowych z odpowiednika po stronie serwera, po prostu upewnij się, że masz atrybut "ostatnia modyfikacja" w swojej jednostce i wykonaj warunkową odpowiedź GET dla serwer (ustawiając datę ostatniej modyfikacji "If-Modified-Since" Http-Header na twoje jednostki) Serwer odpowie kodem statusowym 304 (niezmodyfikowanym), jeśli zasób się nie zmienił (zakładając, że serwer jest REST-ful) .Jeżeli się zmieni, serwer ustawi "Last-Modified" Http-Header na datę ostatniej zmiany, odpowie Kodem Statusu 200 i dostarczy zasób w ciele (np. W JSON format.)

Tak jak zawsze, odpowiedź brzmi, jak na twoje pytanie, jak zawsze prawdopodobnie "to zależy". Zależy to głównie od tego, ke, aby wprowadzić twoją wielokrotną do użytku warstwę z podstawowymi danymi/spoczynkową.

Aby przekazać ci numery: zajęło mi 6 miesięcy (w wolnym czasie, w tempie 3-10 godzin tygodniowo), aby mieć moje miejsce, w którym chciałem, i szczerze mówiąc, wciąż refaktoryzuję, zmieniając nazwę , aby umożliwić obsługę specjalnych przypadków użycia (anulowanie żądań, roll-backs itp.) i zapewnić precyzyjne oddzwanianie (osiągalność, warstwa sieciowa, serializacja, zapisywanie danych podstawowych ...),. Ale jest całkiem czysty, dopracowany i zoptymalizowany, i mam nadzieję, że pasuje do ogólnych potrzeb mojego pracodawcy (miejsce online dla ogłoszeń z wieloma aplikacjami na iOS). Ten czas obejmował naukę, testowanie, optymalizację, debugowanie i ciągłe zmienianie mojego API (najpierw dodawanie funkcjonalności, potem poprawianie, radykalne upraszczanie i ponowne debugowanie).

Jeśli priorytetem jest czas wprowadzenia produktu na rynek, łatwiej Ci będzie z prostym i pragmatycznym podejściem: zapomnij o ponownym użyciu, po prostu zapamiętuj informacje i zastosuj refaktor w następnym projekcie, ponownie wykorzystując i poprawiając kod tutaj i tam . Ostatecznie suma wszystkich doświadczeń może zmaterializować się w jasnej wizji JAK działa twój API i CO zapewnia. Jeśli jeszcze tego nie zrobiłeś, staraj się, aby był częścią budżetu projektu, i po prostu spróbuj ponownie wykorzystać tak dużo stabilnego interfejsu API 3'-Party.

Przepraszam za długotrwałą reakcję, czułem, że wkraczasz w coś w rodzaju budowania ogólnego interfejsu API, a nawet struktury. Te rzeczy wymagają czasu, wiedzy, opieki i długotrwałego zaangażowania, a przez większość czasu są stratą czasu, ponieważ nigdy ich nie kończycie.

Jeśli chcesz tylko obsługiwać określone scenariusze buforowania, aby umożliwić korzystanie z aplikacji w trybie offline i zminimalizować ruch w sieci, możesz oczywiście zaimplementować te funkcje. Po prostu ustaw zmienione if - od nagłówków w żądaniu, sprawdź ostatnio zmodyfikowane nagłówki lub etagi i zachowaj je w trwałych jednostkach, aby móc ponownie przesłać te informacje w późniejszych żądaniach. Oczywiście zaleciłbym również buforowanie (trwałe) zasobów, takich jak obrazy lokalnie, przy użyciu tych samych nagłówków HTTP.

Jeśli masz luksus modyfikowania (w pełni restrykcyjny) usługi po stronie serwera, wszystko jest w porządku, pod warunkiem, że dobrze ją zaimplementujesz (z doświadczenia możesz zaoszczędzić nawet 3/4 kod sieci/parsowania iOS-side, jeśli usługa zachowuje się dobrze (zwraca odpowiednie kody stanu HTTP, unika sprawdzeń dla zer, transformacji liczbowych z łańcuchów, dat, zapewnia wyszukiwanie identyfikatorów zamiast niejawnych łańcuchów itp.).

Jeśli nie masz takiego luksusu, wtedy albo ta usługa jest co najmniej REST-ful (co bardzo pomaga), albo będziesz musiał naprawić rzeczy po stronie klienta (co jest często bólem).

+1

Dziękuję za odwołanie się do sesji WWDC, pobieram ją właśnie teraz. Już wiem, jak poradzić sobie z przepływem aplikacji Restful. Pytałem, czy było zbyt przesadne, aby podjąć takie przedsięwzięcie, czy nie. Z Twojej odpowiedzi nie mogę powiedzieć, czy popierasz taką architekturę, czy ją popierasz, ponieważ wykonałeś już aplikację przy użyciu tej specyficznej architektury. Czy chcesz wyjaśnić? –

+0

Jak zwykle odpowiedź brzmi "to zależy". – codeclash

+0

Będę edytować moją odpowiedź, pole komentarza nie pozwala na wiele znaków :-) – codeclash

5

to rozwiązanie, którego nie mogłem wypróbować, ponieważ ja też daleko w moim projekcie byłaby do buforowania aspekt serwera mojej aplikacji, ale powinna być przydatna dla osób, które obecnie nie są nadal szukają odpowiedzi:

http://restkit.org/

Robi dokładnie to, co zrobiłem, ale to znacznie więcej wydobywane to co zrobiłem. Bardzo wnikliwe rzeczy. Mam nadzieję, że to pomoże komuś!

+5

Dla przypomnienia: na Githubie jest inny nowy interfejs API: https: //github.com/gowalla/AFNetworking. Nie zapewnia trwałości danych podstawowych (co robi RestKit), ale jest to bardzo miły i oparty na blokach interfejs API do interakcji z usługami RESTful. Posiada również wbudowaną obsługę JSON-Parsing (szybki JSONKit dla iOS <5 i nowy serializator JSON firmy Apple, począwszy od iOS 5. JEŻELI potrzebujesz łatwej asynchronicznej sieci, ale nadal masz pełną kontrolę nad trwałością danych podstawowych, wydaje się to być bardzo czyste rozwiązanie – codeclash

+6

RestKit używa AFNetworking dla swojej warstwy sieci –

5

Myślę, że to jest prawidłowe podejście. Robiłem to wiele razy. Najtrudniejszą częścią jest sytuacja, w której musisz zająć się synchronizacją: jeśli klient i serwer mogą jednocześnie zmieniać rzeczy. W tym celu prawie zawsze potrzebujesz logiki scalania specyficznej dla aplikacji.

Powiązane problemy