Jak zsynchronizować Podstawowe Dane iPhone ' a z serwerem WWW, a następnie wypychać do innych urządzeń? [zamknięte]

Pracowałem nad metodą synchronizacji danych przechowywanych w aplikacji iPhone między wieloma urządzeniami, takimi jak iPad lub Mac. Nie ma wielu (jeśli w ogóle) RAM synchronizacji do użytku z podstawowymi danymi w systemie iOS. Jednak myślałem o następującej koncepcji:

  1. następuje zmiana w lokalnym magazynie danych i zmiana jest zapisywana. (a) jeśli urządzenie jest online, próbuje wysłać zestaw zmian do serwera, w tym identyfikator urządzenia, które wysłało zestaw zmian. (b) Jeśli zestaw zmian nie dotrze do serwera lub jeśli urządzenie nie jest online, aplikacja doda zestaw zmian do kolejki do wysłania, gdy pojawi się online.
  2. serwer, znajdujący się w chmurze, łączy określone zestawy zmian, które otrzymuje ze swoją główną bazą danych.
  3. Po połączeniu zestawu zmian (lub kolejki zestawów zmian) na serwerze w chmurze, serwer wypycha wszystkie te zestawy zmian do innych urządzeń zarejestrowanych na serwerze za pomocą pewnego rodzaju ankiety system. (Myślałem, że skorzystam z usług Push Apple, ale najwyraźniej według komentarzy nie jest to sprawny system.)

Czy jest coś wymyślnego, o czym muszę myśleć? Przyjrzałem się takim frameworkom jak ObjectiveResource, Core Resource i RestfulCoreData. Oczywiście wszystkie one pracują z Ruby on Rails, z którym nie jestem związany, ale to jest miejsce na początek. Główne wymagania jakie mam dla mojego rozwiązania są:

  1. wszelkie zmiany powinny być wysyłane w tle bez zatrzymywania głównego wątku.
  2. powinien używać jak najmniejszej przepustowości.

Myślałem o kilku wyzwaniach:

  1. upewnianie się, że identyfikatory obiektów dla różnych magazynów danych na różnych urządzeniach są dołączone na serwerze. Oznacza to, że będę miał tabelę identyfikatorów obiektów i identyfikatorów urządzeń, które są powiązane poprzez odniesienie do obiektu przechowywanego w bazie danych. Będę miał record (DatabaseId [unique to this table], ObjectId [unique to the item in the whole database], Datafield1, Datafield2), pole ObjectId odwoła się do innej tabeli, AllObjects: (ObjectId, DeviceId, DeviceObjectId). Następnie, gdy urządzenie wypchnie zestaw zmian, przejdzie wzdłuż identyfikatora urządzenia i obiektu objectId z obiektu core data w lokalnym magazynie danych. Następnie mój serwer w chmurze sprawdzi objectId i device Id w tabeli AllObjects i znajdzie rekord do zmiany w tabela początkowa.
  2. wszystkie zmiany powinny być oznaczone czasem, aby można je było łączyć.
  3. urządzenie będzie musiało przeszukać serwer, bez zużywania zbyt dużej ilości baterii.
  4. urządzenia lokalne będą również musiały zaktualizować wszystko, co znajduje się w pamięci, jeśli/kiedy zmiany zostaną odebrane z serwera.

Czy coś jeszcze mi umyka? Na jakie rodzaje frameworków powinienem zwrócić uwagę, aby było to możliwe?

Author: RichVel, 2011-02-18

9 answers

Sugeruję uważne przeczytanie i wdrożenie strategii synchronizacji omawianej przez Dana Grovera na konferencji iPhone 2009, dostępnej tutaj jako dokument pdf.

Jest to realne rozwiązanie i nie jest takie trudne do wdrożenia (Dan zaimplementował to w kilku swoich aplikacjach), nakładając się na rozwiązanie opisane przez Chrisa. Aby uzyskać dogłębną, teoretyczną dyskusję na temat synchronizacji, zobacz artykuł Russa Coxa (MIT) i Williama Josephsona (Princeton): {]}

Synchronizacja Plików z wektorowymi parami czasu

Co równie dobrze odnosi się do podstawowych danych z pewnymi oczywistymi modyfikacjami. Zapewnia to ogólnie znacznie bardziej solidną i niezawodną strategię synchronizacji, ale wymaga większego wysiłku, aby być prawidłowo wdrożone.

EDIT:

Wygląda na to, że plik PDF Grovera nie jest już dostępny(broken link, marzec 2015). UPDATE: link jest dostępny przez Way Back Machine tutaj

Ramy Objective-C o nazwie ZSync oraz opracowany przez Marcusa Zarra został przestarzały, biorąc pod uwagę, że iCloud w końcu wydaje się obsługiwać prawidłową synchronizację danych podstawowych.

 141
Author: Massimo Cafaro,
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-09-28 13:28:53

Zrobiłem coś podobnego do tego, co próbujesz zrobić. Powiem ci, czego się nauczyłem i jak to zrobiłem.

Zakładam, że masz relację jeden do jednego między głównym obiektem danych a modelem (lub schematem db) na serwerze. Po prostu chcesz, aby zawartość serwera była zsynchronizowana z klientami, ale klienci mogą również modyfikować i dodawać dane. Jeśli dobrze zrozumiałem, to czytaj dalej.

Dodałem cztery pola do pomocy synchronizacja:

  1. sync_status - dodaj to pole tylko do podstawowego modelu danych. Jest on używany przez aplikację do określenia, czy masz oczekującą zmianę na elemencie. Używam następujących kodów: 0 oznacza brak zmian, 1 oznacza, że jest w kolejce do synchronizacji z serwerem, a 2 oznacza, że jest to obiekt tymczasowy i można go wyczyścić.
  2. is_deleted - dodaj to do modelu danych serwera i rdzenia. Usuń zdarzenie nie powinno w rzeczywistości usuwać wiersza z bazy danych lub z twojego model klienta, ponieważ nie pozostawia nic do synchronizacji z powrotem. Mając tę prostą flagę logiczną, możesz ustawić is_deleted na 1, zsynchronizować ją i wszyscy będą zadowoleni. Musisz również zmodyfikować kod na serwerze i kliencie, aby odpytywać nie usunięte elementy za pomocą "is_deleted = 0".
  3. last_modified - dodaj to do modelu danych serwera i rdzenia. Pole to powinno być automatycznie aktualizowane o bieżącą datę i godzinę przez serwer za każdym razem, gdy cokolwiek zmieni się na tym rekordzie. Nigdy nie powinien być modyfikowany przez Klienta.
  4. guid - Dodaj globalnie unikalny identyfikator (patrz http://en.wikipedia.org/wiki/Globally_unique_identifier ) pole do serwera i modelu danych core. Pole to staje się kluczem podstawowym i staje się ważne podczas tworzenia nowych rekordów na kliencie. Zwykle Twój klucz podstawowy jest rosnącą liczbą całkowitą na serwerze, ale musimy pamiętać, że zawartość może być utworzona w trybie offline i zsynchronizowana później. GUID pozwala nam na Utwórz klucz będąc w trybie offline.

Na kliencie Dodaj kod, aby ustawić sync_status na 1 na obiekcie Modelu, gdy coś się zmieni i musi być zsynchronizowane z serwerem. Nowe obiekty modelu muszą wygenerować identyfikator GUID.

Synchronizacja jest pojedynczym żądaniem. Wniosek zawiera:

  • znacznik czasu MAX last_modified obiektów modelu. To informuje serwer, że chcesz zmiany tylko po tym znaczniku czasu.
  • tablica JSON zawierająca wszystkie elementy z sync_status=1.

Serwer pobiera żądanie i robi to:

  • pobiera zawartość z tablicy JSON i modyfikuje lub dodaje rekordy, które zawiera. Pole last_modified jest automatycznie aktualizowane.
  • serwer zwraca tablicę JSON zawierającą wszystkie obiekty ze znacznikiem czasu last_modified większym niż znacznik czasu wysłany w żądaniu. Będzie to obejmować obiekty, które właśnie otrzymał, co służy jako potwierdzenie, że rekord został pomyślnie zsynchronizowane z serwerem.

Aplikacja otrzymuje odpowiedź i robi to:

  • pobiera zawartość z tablicy JSON i modyfikuje lub dodaje rekordy, które zawiera. Każdy rekord otrzymuje wartość sync_status równą 0.

Mam nadzieję, że to pomoże. Użyłem słowa rekord i model zamiennie, ale myślę, że masz pomysł. Powodzenia.

 266
Author: chris,
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-08-26 07:43:44

Jeśli nadal szukasz sposobu, aby przejść, zajrzyj do Couchbase mobile. To w zasadzie robi wszystko, co chcesz. ( http://www.couchbase.com/nosql-databases/couchbase-mobile )

 11
Author: radiospiel,
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-06-01 03:16:45

Podobnie jak @Cris zaimplementowałem klasę do synchronizacji pomiędzy Klientem a serwerem i rozwiązałem wszystkie znane dotąd problemy (wysyłanie / odbieranie danych do / z serwera, konflikty scalania oparte na znacznikach czasu, usuwanie duplikatów wpisów w nierzetelnych warunkach sieciowych, synchronizacja zagnieżdżonych danych i plików itp.. )

Po prostu mówisz klasie, która encja i które kolumny powinny być zsynchronizowane i gdzie jest Twój serwer.

M3Synchronization * syncEntity = [[M3Synchronization alloc] initForClass: @"Car"
                                                              andContext: context
                                                            andServerUrl: kWebsiteUrl
                                             andServerReceiverScriptName: kServerReceiverScript
                                              andServerFetcherScriptName: kServerFetcherScript
                                                    ansSyncedTableFields:@[@"licenceNumber", @"manufacturer", @"model"]
                                                    andUniqueTableFields:@[@"licenceNumber"]];


syncEntity.delegate = self; // delegate should implement onComplete and onError methods
syncEntity.additionalPostParamsDictionary = ... // add some POST params to authenticate current user

[syncEntity sync];

Możesz znaleźć źródło, przykład roboczy i więcej instrukcji tutaj: github.com/knagode/M3Synchronization .

 7
Author: knagode,
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-08-21 16:57:43

Powiadomienie Użytkownika o aktualizacji danych za pomocą powiadomienia push. Użyj wątku w tle w aplikacji, aby sprawdzić dane lokalne i dane na serwerze w chmurze, podczas gdy zmiana dzieje się na serwerze, Zmień dane lokalne i odwrotnie.

Więc myślę, że najtrudniejszą częścią jest oszacowanie danych, w której stronie jest unieważnione.

Hope this can help u

 5
Author: Stan,
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-02-18 09:46:35

Właśnie opublikowałem pierwszą wersję mojego nowego Core Data Cloud Syncing API, znanego jako SynCloud. SynCloud ma wiele różnic z iCloud, ponieważ pozwala na interfejs synchronizacji wielu użytkowników. Różni się również od innych API synchronizacji, ponieważ pozwala na wielostolikowe, relacyjne dane.

Więcej informacji na stronie http://www.syncloudapi.com

Buduj z iOS 6 SDK, jest bardzo aktualny od 27/09/2012.

 5
Author: logan,
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
2012-09-28 07:01:46

Myślę, że dobrym rozwiązaniem problemu GUID jest "distributed ID system". Nie jestem pewien, jaki jest poprawny termin, ale myślę, że tak nazywały go dokumenty MS SQL server (SQL używa / używał tej metody dla rozproszonych / zsynchronizowanych baz danych). To całkiem proste:

Serwer przypisuje wszystkie identyfikatory. Za każdym razem, gdy wykonywana jest synchronizacja, pierwszą rzeczą, która jest sprawdzana, jest "ile identyfikatorów zostało mi na tym kliencie?"Jeśli klient kończy pracę, prosi serwer o nowy blok identyfikatorów. Klient wtedy używa identyfikatorów w tym zakresie dla nowych rekordów. Działa to świetnie dla większości potrzeb, jeśli możesz przypisać blok na tyle duży, że powinien "nigdy" zabraknąć przed następną synchronizacją, ale nie tak duży, że serwer skończy się z czasem. Jeśli klient kiedykolwiek zabraknie, obsługa może być dość prosta, po prostu powiedz użytkownikowi "przykro mi, że nie możesz dodać więcej elementów, dopóki nie zsynchronizujesz"... jeśli dodają tak wiele elementów, czy nie powinni synchronizować się, aby uniknąć starych problemów z danymi?

Myślę, że jest to lepsze od używania losowe identyfikatory GUID ponieważ losowe identyfikatory GUID nie są w 100% bezpieczne i zwykle muszą być znacznie dłuższe niż standardowe identyfikatory (128-bitowe vs 32-bitowe). Zwykle masz indeksy według ID i często przechowujesz numery ID w pamięci, więc ważne jest, aby zachować je małe.

Nie chciało mi się pisać jako odpowiedź, ale nie wiem, czy ktoś by widział jako komentarz, i myślę, że jest to ważne w tym temacie, a nie zawarte w innych odpowiedziach.

 5
Author: eselk,
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
2014-09-10 18:59:24

Najpierw powinieneś przemyśleć, ile danych, tabel i relacji będziesz miał. W moim rozwiązaniu zaimplementowałem synchronizację za pomocą Plików Dropbox. Obserwuję zmiany w głównym MOC i zapisuję te dane do plików (każdy wiersz jest zapisywany jako gzipped json). Jeśli działa połączenie internetowe, sprawdzam, czy w Dropbox są jakieś zmiany (Dropbox daje mi zmiany delta), pobieram je i scalam( Ostatnie wygrane), a na koniec umieszczam zmienione pliki. Przed synchronizacją umieszczam plik lock na Dropbox, aby zapobiec innym klientom synchronizacja niekompletnych danych. Podczas pobierania zmian jest bezpieczne, że pobierane są tylko częściowe dane (np. utracone połączenie internetowe). Po zakończeniu pobierania (w całości lub części) zaczyna ładować pliki do podstawowych danych. Gdy istnieją nierozwiązane relacje (nie wszystkie pliki są pobierane), przestaje ładować pliki i próbuje zakończyć pobieranie później. Relacje są przechowywane tylko jako GUID, więc mogę łatwo sprawdzić, które Pliki załadować, aby mieć pełną integralność danych. Synchronizacja rozpoczyna się po zmianach w podstawowych danych są wykonane. Jeśli nie ma żadnych zmian, sprawdza zmiany w Dropbox co kilka minut i podczas uruchamiania aplikacji. Dodatkowo, gdy zmiany są wysyłane na serwer, wysyłam transmisję na inne urządzenia, aby poinformować je o zmianach, aby mogły szybciej się synchronizować. Każdy zsynchronizowany obiekt ma właściwość GUID (guid jest używany również jako nazwa pliku dla plików exchange). Mam również synchronizowaną bazę danych, w której przechowuję wersję Dropbox KAŻDEGO pliku(mogę ją porównać, gdy Dropbox delta resetuje swój stan). Pliki zawierają również nazwę encji, stan (usunięty / Nie usunięty), guid (taki sam jak nazwa pliku), rewizja bazy danych (w celu wykrycia migracji danych lub uniknięcia synchronizacji z wersjami aplikacji never) i oczywiście DANE (jeśli wiersz nie jest usunięty).

To rozwiązanie działa dla tysięcy plików i około 30 podmiotów. Zamiast Dropbox mogę użyć key / value store jako usługi REST web, co chcę zrobić później, ale nie mam na to czasu:) na razie moim zdaniem moje rozwiązanie jest bardziej niezawodne niż iCloud i, co jest bardzo ważne, mam pełna kontrola nad tym, jak to działa (głównie dlatego, że jest to mój własny kod).

Innym rozwiązaniem jest zapisywanie zmian w MOC jako transakcji - będzie znacznie mniej plików wymienianych z serwerem, ale trudniej jest wykonać wstępne ładowanie w odpowiedniej kolejności do pustych danych podstawowych. iCloud działa w ten sposób, a także inne rozwiązania synchronizacyjne mają podobne podejście, np ticoredatasync .

-- UPDATE

Po jakimś czasie przeniosłem się na } składy - polecam to rozwiązanie nad wynalezienie koła na nowo.

 2
Author: thom_ek,
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-04-11 22:27:57

2017

Odnośnie tego niezwykle starego pytania. To byłoby bardzo podobne do pytania.]}

" chcę kupić urządzenie, którym jest telefon, który mogę nosić ze sobą-ale także używać do wielu zadań obliczeniowych, nawet przeglądania WWW!"

Oczywiście odpowiedź na to pytanie brzmi Jeśli byłeś na Marsie, jedną z głównych technologii zrealizowanych ostatnio na tej planecie były "smartfony", kup jedną.

W dzisiejszych czasach, tworzenie systemu OCC od podstaw byłoby równie szalone, jak tworzenie bazy danych SQL od podstaw.

Oczywiście, dla OCC, który jest podstawowym paradygmatem wszystkich nietrywialnych aplikacji teraz, używasz

  • baza ogniowa
  • PubNub
  • Couchbase

I tak dalej, które są po prostu, głównym postępem w ludzkiej technologii ostatnich kilku lat .

Dzisiaj nie stworzyłbyś OCC od zera, niż]}

  • Napisz własny system operacyjny z scratch

  • Napisz własną bazę danych SQL od podstaw

  • Napisz własną czcionkę-rendering od podstaw

Zauważ, że rzeczywiście, w profesjonalnym sensie nie możesz być "programistą ios "lub" programistą Androida".

Kogo obchodzi, jak układać tabele i przyciski?

Jesteś ekspertem Firebase/whatever, a jako przypadkowy problem poboczny wiesz, jak układać przyciski itp. na ios lub Androidzie.

Jedyny problem jest, którego BAAS użyć - na przykład, może PlayFab, jeśli jest zorientowany na grę, może PubNub, jeśli jest naprawdę napędzany wiadomościami, może ably.io może kinvey, jeśli jesteś korporacyjny-nieważne.

 -1
Author: Fattie,
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
2017-12-14 15:30:38