iPhone 핵심 데이터를 웹 서버와 동기화 한 다음 다른 장치로 이동하는 방법은 무엇입니까?


Answers

당신이하려고하는 것과 비슷한 것을했습니다. 내가 배운 것을 내가 어떻게했는지 말해 줄께.

코어 데이터 객체와 서버의 모델 (또는 db 스키마) 사이에 일대일 관계가 있다고 가정합니다. 클라이언트와 서버 내용을 동기화하고 싶지만 클라이언트는 데이터를 수정하고 추가 할 수도 있습니다. 그 말이 맞다면 계속 읽으십시오.

동기화에 도움이되는 네 개의 필드를 추가했습니다.

  1. sync_status -이 필드를 핵심 데이터 모델에만 추가하십시오. 앱에서 보류중인 변경 사항을 확인하는 데 사용됩니다. 다음 코드를 사용합니다. 0은 변경 사항 없음을 의미하고 1은 서버와 동기화되도록 대기열에 있음을 의미하고 2는 임시 객체이고 제거 될 수 있음을 의미합니다.
  2. is_deleted - 이것을 서버 및 코어 데이터 모델에 추가합니다. 삭제 이벤트는 실제로 데이터베이스 또는 클라이언트 모델에서 행을 삭제하면 안됩니다. 왜냐하면 다시 동기화 할 수 없기 때문입니다. 이 간단한 부울 플래그를 사용하면 is_deleted를 1로 설정하고 동기화하여 모든 사람이 만족할 수 있습니다. "is_deleted = 0"을 사용하여 삭제되지 않은 항목을 쿼리하도록 서버 및 클라이언트의 코드를 수정해야합니다.
  3. last_modified - 이것을 서버 및 코어 데이터 모델에 추가합니다. 이 필드는 해당 레코드에서 변경 될 때마다 서버에 의해 현재 날짜 및 시간으로 자동 갱신됩니다. 그것은 클라이언트에 의해 수정되어서는 안됩니다.
  4. guid - 전역 고유 ID ( http://en.wikipedia.org/wiki/Globally_unique_identifier 참조) 필드를 서버 및 핵심 데이터 모델에 추가합니다. 이 필드는 기본 키가되며 클라이언트에서 새 레코드를 만들 때 중요 해집니다. 일반적으로 기본 키는 서버에서 증가하는 정수이지만 콘텐츠를 오프라인에서 만들고 나중에 동기화 할 수 있다는 점을 명심해야합니다. GUID를 사용하면 오프라인 상태에서 키를 만들 수 있습니다.

클라이언트에서 변경 사항이 있고 서버와 동기화해야 할 때마다 model 객체에서 sync_status를 1로 설정하는 코드를 추가하십시오. 새 모델 객체는 GUID를 생성해야합니다.

동기화는 단일 요청입니다. 요청 내용 :

  • 모델 개체의 MAX last_modified 타임 스탬프입니다. 그러면 서버에이 시간 소인 이후의 변경 사항 만 필요합니다.
  • sync_status = 1 인 모든 항목을 포함하는 JSON 배열입니다.

서버가 요청을 받고 다음을 수행합니다.

  • JSON 배열에서 내용을 가져와 포함 된 레코드를 수정하거나 추가합니다. last_modified 필드가 자동으로 업데이트됩니다.
  • 서버는 last_modified 타임 스탬프가 요청에서 보낸 타임 스탬프보다 큰 모든 객체를 포함하는 JSON 배열을 반환합니다. 여기에는 방금 수신 한 오브젝트가 포함되며 레코드가 서버와 성공적으로 동기화되었음을 확인하는 역할을합니다.

앱이 응답을 받고 다음을 수행합니다.

  • JSON 배열에서 내용을 가져와 포함 된 레코드를 수정하거나 추가합니다. 각 레코드는 sync_status를 0으로 설정합니다.

도움이되기를 바랍니다. 나는 레코드와 모델을 같은 의미로 사용했지만 아이디어를 얻은 것 같아요. 행운을 빕니다.

Question

iPad 또는 Mac과 같은 여러 장치간에 iPhone 응용 프로그램에 저장된 핵심 데이터를 동기화하는 방법을 연구했습니다. iOS의 핵심 데이터와 함께 사용할 프레임 워크를 동기화 할 수있는 프레임 워크가 많지는 않습니다. 그러나, 나는 다음과 같은 개념을 생각 해왔다 :

  1. 로컬 코어 데이터 저장소가 변경되고 변경 내용이 저장됩니다. (a) 장치가 온라인 상태이면 변경 집합을 보낸 장치의 장치 ID를 포함하여 서버에 변경 집합을 보내려고합니다. (b) 변경 세트가 서버에 도착하지 않거나 온라인 상태가 아닌 경우 변경 사항 세트가 대기열에 추가되어 온라인 상태가되면 보낼 수 있습니다.
  2. 클라우드에있는 서버는 수신 한 특정 변경 집합을 해당 마스터 데이터베이스와 병합합니다.
  3. 변경 세트 (또는 변경 세트 대기열)가 클라우드 서버에 병합 된 후, 서버는 모든 변경 세트를 일종의 폴링 시스템을 사용하여 서버에 등록 된 다른 디바이스에 푸시합니다. (필자는 애플의 푸시 (Push) 서비스를 사용한다고 생각했지만, 논평에 따르면 이는 실행 가능한 시스템이 아니다.

내가 생각할 필요가있는 공상이 있습니까? ObjectiveResource , Core ResourceRestfulCoreData 와 같은 REST 프레임 워크를 살펴 보았습니다. 물론, 이것들은 모두 Ruby on Rails와 관련이 있습니다. 나는 연결되어 있지 않습니다. 그러나 시작할 장소입니다. 내 솔루션에 대한 주요 요구 사항은 다음과 같습니다.

  1. 모든 변경 사항은 주 스레드를 일시 중지하지 않고 백그라운드에서 보내야합니다.
  2. 가능한 한 적은 대역폭을 사용해야합니다.

나는 많은 도전에 대해 생각 해왔다 :

  1. 서로 다른 장치에있는 서로 다른 데이터 저장소의 개체 ID가 서버에 연결되어 있는지 확인하십시오. 즉, 데이터베이스에 저장된 객체에 대한 참조를 통해 연결되는 객체 ID 및 장치 ID 테이블을 갖게됩니다. 레코드 (DatabaseId [이 테이블에 고유], 전체 데이터베이스의 항목에 고유 한 ObjectId, Datafield1, Datafield2)를 가지며, ObjectId 필드는 다른 테이블 인 AllObjects : (ObjectId, DeviceId, DeviceObjectId)를 참조합니다. 그런 다음 장치가 변경 집합을 밀어 올리면 장치 ID와 objectId를 로컬 데이터 저장소의 핵심 데이터 개체에서 전달합니다. 그런 다음 클라우드 서버가 AllObjects 테이블의 objectId 및 device Id를 확인하고 초기 테이블에서 변경할 레코드를 찾습니다.
  2. 모든 변경 사항은 병합 될 수 있도록 타임 스탬프 처리되어야합니다.
  3. 장치는 너무 많은 배터리를 사용하지 않고도 서버를 폴링해야합니다.
  4. 서버에서 변경 사항을 수신하면 로컬 장치는 메모리에있는 항목을 업데이트해야합니다.

내가 여기서 누락 된 것이 있습니까? 이것을 가능하게하기 위해서는 어떤 유형의 프레임 워크를 사용해야합니까?




@Cris와 비슷하게 클라이언트와 서버 간의 동기화를위한 클래스를 구현했으며 지금까지 알려진 모든 문제를 해결했습니다 (서버와주고받는 데이터를주고 받음, 타임 스탬프를 기반으로 충돌을 병합, 신뢰할 수없는 네트워크 조건에서 중복 항목을 제거함, 중첩 된 데이터를 동기화 함 파일 등 ..)

어떤 엔티티와 어떤 컬럼이 동기화되어야하는지, 서버가 어디에 있는지 클래스에 알려주는 것입니다.

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];

소스, 작동 예제 및 기타 지침은 github.com/knagode/M3Synchronization 에서 찾을 수 있습니다.




먼저 얼마나 많은 데이터, 테이블 및 관계를 가질 지 다시 생각해야합니다. 내 솔루션에서는 Dropbox 파일을 통해 동기화를 구현했습니다. 주 MOC의 변경 사항을 관찰하고이 데이터를 파일에 저장합니다 (각 행은 gzipped json으로 저장됩니다). 인터넷 연결이 작동하는 경우, Dropbox (Dropbox가 델타 변경 사항을 제공함)에 변경 사항이 있는지 확인하고 다운로드하여 병합 (최신 승리) 한 다음 변경된 파일을 저장합니다. 동기화 전에 다른 클라이언트가 불완전한 데이터를 동기화하지 못하도록 Dropbox에 잠금 파일을 저장했습니다. 변경 사항을 다운로드 할 때 부분 데이터 만 다운로드하는 것이 안전합니다 (예 : 인터넷 연결 끊김). 다운로드가 완료되면 (전체 또는 부분) 코어 데이터에 파일을로드하기 시작합니다. 해결되지 않은 관계가있을 때 (모든 파일이 다운로드되는 것은 아님) 파일로드가 중지되고 나중에 다운로드가 완료됩니다. 관계는 GUID로만 ​​저장되므로 전체 데이터 무결성을 위해로드 할 파일을 easly 확인할 수 있습니다. 동기화는 핵심 데이터가 변경된 후에 시작됩니다. 변경 사항이없는 경우 몇 분마다 Dropbox에서 변경 사항을 확인하고 앱을 시작할 때 확인합니다. 추가 변경 사항이 서버로 전송되면 다른 장치로 브로드 캐스트를 보내 변경 사항을 알려줌으로써 더 빠르게 동기화 할 수 있습니다. 각 동기화 된 엔터티에는 GUID 속성이 있습니다 (guid는 교환 파일의 파일 이름으로도 사용됩니다). 또한 각 파일의 Dropbox 개정판을 저장하는 동기화 데이터베이스 (Dropbox 델타가 상태를 재설정 할 때 비교할 수 있음)가 있습니다. 파일에는 엔티티 이름, 상태 (삭제됨 / 삭제되지 않음), guid (파일 이름과 동일), 데이터베이스 개정판 (데이터 이전 감지 또는 앱 버전과의 동기화 방지) 및 물론 데이터 (행이 삭제되지 않은 경우)가 포함됩니다.

이 솔루션은 수천 개의 파일과 약 30 개의 엔티티에서 작동합니다. Dropbox 대신 키 / 값 저장소를 나중에 수행하고 싶은 REST 웹 서비스로 사용할 수는 있지만 시간이 없다. 지금 당장은 내 의견으로는 내 솔루션이 iCloud보다 안정적이며 매우 중요하다. 나는 그것이 어떻게 작동하는지에 대한 완전한 제어권을 가지고있다 (주로 그것이 내 코드이기 때문이다).

또 다른 해결책은 MOC 변경 사항을 트랜잭션으로 저장하는 것입니다. 서버와의 파일 교환이 훨씬 적지 만 빈 코어 데이터에 적절한 순서로 초기로드를 수행하는 것이 더 어렵습니다. iCloud는 이러한 방식으로 작동하며, 다른 동기화 솔루션에도 TICoreDataSync 와 같은 유사한 접근 방식이 있습니다.

- 업데이트

얼마 후, Ensembles 로 마이그레이션했습니다. 휠 재발 사보다는이 솔루션을 권장합니다.




SynCloud로 알려진 새로운 Core Data Cloud Syncing API의 첫 번째 버전을 게시했습니다. SynCloud는 다중 사용자 동기화 인터페이스를 허용하기 때문에 iCloud와 많은 차이가 있습니다. 다중 테이블, 관계형 데이터를 허용하기 때문에 다른 동기화 API와도 다릅니다.

자세한 내용은 http://www.syncloudapi.com 에서 확인하십시오.

iOS 6 SDK를 사용하여 제작하십시오. 2012 년 9 월 27 일부터 최신 버전입니다.




Links