iPhone Core 데이터를 웹 서버와 동기화한 다음 다른 장치로 푸시하는 방법은 무엇입니까?
저는 iPhone 애플리케이션에 저장된 핵심 데이터를 iPad나 Mac과 같은 여러 장치 간에 동기화하는 방법을 연구해 왔습니다.iOS에서 코어 데이터와 함께 사용할 수 있는 동기화 프레임워크는 많지 않습니다.하지만, 저는 다음과 같은 개념에 대해 생각해 왔습니다.
- 로컬 코어 데이터 저장소에 변경 사항이 적용되고 변경 사항이 저장됩니다. (a) 장치가 온라인 상태인 경우, 변경 사항을 전송한 장치의 장치 ID를 포함하여 서버로 변경 사항 집합을 전송하려고 합니다. (b) 변경 사항 집합이 서버에 도달하지 않거나 장치가 온라인 상태가 아닌 경우,앱이 온라인 상태가 될 때 전송할 변경 세트를 대기열에 추가합니다.
- 클라우드에 있는 서버는 수신한 특정 변경사항 집합을 마스터 데이터베이스와 병합합니다.
- 클라우드 서버에서 변경 세트(또는 변경 세트 대기열)가 병합된 후, 서버는 일종의 폴링 시스템을 사용하여 이러한 모든 변경 세트를 서버에 등록된 다른 장치로 푸시합니다.(Apple의 Push 서비스를 사용하려고 생각했지만, 코멘트에 따르면 이것은 작동 가능한 시스템이 아닙니다.)
제가 생각해야 할 멋진 일이 있나요?목표 리소스, 핵심 리소스, RestfulCoreData와 같은 REST 프레임워크를 살펴보았습니다.물론, 이 모든 것들은 루비 온 레일즈와 함께 일하고 있지만, 저는 그것에 얽매이지 않습니다. 하지만 그것은 시작해야 할 장소입니다.솔루션에 대한 주요 요구 사항은 다음과 같습니다.
- 변경 사항은 메인 스레드를 일시 중지하지 않고 백그라운드로 전송해야 합니다.
- 가능한 한 적은 대역폭을 사용해야 합니다.
저는 다음과 같은 여러 과제에 대해 생각해 보았습니다.
- 서로 다른 장치에 있는 서로 다른 데이터 저장소의 개체 ID가 서버에 연결되어 있는지 확인합니다.즉, 데이터베이스에 저장된 개체에 대한 참조를 통해 연결된 개체 ID 및 장치 ID 테이블을 갖게 됩니다.레코드(DatabaseId [이 테이블에 고유], ObjectId [전체 데이터베이스의 항목에 고유], Datafield1, Datafield2), ObjectId 필드는 다른 테이블인 AllObjects(ObjectId, DeviceId, DeviceObjectId)를 참조합니다.그런 다음 장치가 변경 세트를 푸시하면 로컬 데이터 저장소의 코어 데이터 개체에서 장치 ID와 objectId를 전달합니다.그러면 내 클라우드 서버가 AllObjects 테이블에서 objectId 및 deviceId를 확인하고 초기 테이블에서 변경할 레코드를 찾습니다.
- 모든 변경사항은 병합할 수 있도록 타임스탬프를 기록해야 합니다.
- 장치는 배터리를 너무 많이 사용하지 않고 서버를 폴링해야 합니다.
- 또한 로컬 장치는 서버로부터 변경사항을 수신한 경우 메모리에 저장된 모든 항목을 업데이트해야 합니다.
제가 여기서 또 빠뜨린 것이 있습니까?이를 가능하게 하려면 어떤 종류의 프레임워크를 검토해야 합니까?
저는 당신이 하려는 것과 비슷한 일을 했습니다.제가 무엇을 배우고 어떻게 했는지 말씀드리겠습니다.
Core Data 개체와 서버의 모델(또는 db 스키마) 간에 일대일 관계가 있다고 가정합니다.서버 내용을 클라이언트와 동기화된 상태로 유지하기만 하면 되지만, 클라이언트는 데이터를 수정하고 추가할 수도 있습니다.제가 맞았으면 계속 읽어보세요.
동기화에 도움이 되는 네 개의 필드를 추가했습니다.
- sync_status - 코어 데이터 모델에만 이 필드를 추가합니다.항목에 보류 중인 변경 사항이 있는지 여부를 확인하기 위해 앱에서 사용됩니다.다음 코드를 사용합니다. 0은 변경 사항이 없음을 의미하고, 1은 서버와 동기화하기 위해 대기 중임을 의미하며, 2는 임시 개체이므로 삭제할 수 있음을 의미합니다.
- is_deleted - 서버 및 코어 데이터 모델에 추가합니다.삭제 이벤트는 데이터베이스 또는 클라이언트 모델에서 행을 실제로 삭제하지 않아야 합니다. 이는 다시 동기화할 수 있는 기능이 없기 때문입니다.이 단순한 부울 플래그를 가지면 is_deleted를 1로 설정하고 동기화하면 모두가 기뻐할 것입니다.또한 삭제되지 않은 항목을 "is_details=0"으로 쿼리하도록 서버 및 클라이언트의 코드를 수정해야 합니다.
- last_modified - 서버 및 코어 데이터 모델에 추가합니다.이 필드는 레코드에서 변경될 때마다 서버에 의해 현재 날짜와 시간으로 자동으로 업데이트되어야 합니다.고객이 수정해서는 안 됩니다.
- guid - 전역적으로 고유한 ID를 추가합니다(서버 및 코어 데이터 모델에 http://en.wikipedia.org/wiki/Globally_unique_identifier) 필드 참조).이 필드는 기본 키가 되며 클라이언트에서 새 레코드를 작성할 때 중요합니다.일반적으로 기본 키는 서버에서 증가하는 정수이지만 내용은 오프라인으로 작성되고 나중에 동기화될 수 있습니다.GUID를 사용하면 오프라인 상태에서 키를 만들 수 있습니다.
클라이언트에서 무언가가 변경되고 서버와 동기화해야 할 때마다 모델 개체에서 sync_status를 1로 설정하는 코드를 추가합니다.새 모델 개체는 GUID를 생성해야 합니다.
동기화는 단일 요청입니다.요청에는 다음이 포함됩니다.
- 모델 개체의 MAX last_modified 타임스탬프입니다.이 타임스탬프 이후에만 변경할 수 있음을 서버에 알립니다.
- sync_status=1의 모든 항목을 포함하는 JSON 배열입니다.
서버는 요청을 받고 다음 작업을 수행합니다.
- JSON 배열에서 내용을 가져와서 포함된 레코드를 수정하거나 추가합니다.last_modified 필드가 자동으로 업데이트됩니다.
- 서버가 요청에서 보낸 타임스탬프보다 큰 last_modified 타임스탬프를 가진 모든 개체를 포함하는 JSON 배열을 반환합니다.여기에는 레코드가 서버에 성공적으로 동기화되었음을 확인하는 수신 개체가 포함됩니다.
앱은 응답을 수신하고 다음 작업을 수행합니다.
- JSON 배열에서 내용을 가져와서 포함된 레코드를 수정하거나 추가합니다.각 레코드는 sync_status를 0으로 설정합니다.
저는 레코드라는 단어와 모델이라는 단어를 번갈아 사용했지만, 당신은 이해할 수 있을 거라고 생각합니다.
Dan Grover가 iPhone 2009 컨퍼런스에서 논의한 동기화 전략을 주의 깊게 읽고 실행할 것을 제안합니다. 여기 PDF 문서로 제공됩니다.
이것은 실행 가능한 솔루션이며 구현하는 것이 그리 어렵지 않습니다(Dan은 여러 애플리케이션에서 이를 구현했습니다). Chris가 설명한 솔루션과 겹칩니다.동기화에 대한 심층적이고 이론적인 논의는 Russ Cox(MIT)와 William Josephson(Princeton)의 논문을 참조하십시오.
이는 몇 가지 명백한 수정 사항이 있는 핵심 데이터에도 똑같이 잘 적용됩니다.이를 통해 전반적으로 훨씬 더 강력하고 안정적인 동기화 전략을 제공하지만 올바르게 구현하려면 더 많은 노력이 필요합니다.
편집:
Grover의 pdf 파일은 더 이상 사용할 수 없는 것 같습니다(링크 끊김, 2015년 3월).업데이트: 링크는 여기에서 Way Back Machine을 통해 사용할 수 있습니다.
iCloud가 마침내 올바른 코어 데이터 동기화를 지원하는 것으로 보인다는 점에서 ZSync라고 하고 Marcus Zarra가 개발한 Objective-C 프레임워크는 더 이상 사용되지 않습니다.
여전히 갈 길을 찾고 있다면 카우치베이스 모바일을 살펴보십시오.이것은 기본적으로 당신이 원하는 모든 것을 합니다.(http://www.couchbase.com/nosql-databases/couchbase-mobile)
@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 에서 확인할 수 있습니다.
푸시 알림을 통해 데이터를 업데이트하도록 사용자에게 알립니다.앱의 백그라운드 스레드를 사용하여 로컬 데이터와 클라우드 서버의 데이터를 확인하고 서버에서 변경하거나 로컬 데이터를 변경합니다.
그래서 어느 쪽이 무효인지 데이터를 추정하는 것이 가장 어려운 부분이라고 생각합니다.
이것이 당신에게 도움이 되기를 바랍니다.
방금 SynCloud라는 새로운 Core Data Cloud Syncing API의 첫 번째 버전을 게시했습니다.SynCloud는 다중 사용자 동기화 인터페이스를 허용하기 때문에 iCloud와 많은 차이점이 있습니다.또한 다중 테이블 관계형 데이터를 허용하기 때문에 다른 동기화 API와는 다릅니다.
자세한 내용은 http://www.syncloudapi.com 에서 확인하시기 바랍니다.
iOS 6 SDK로 빌드되며 2012년 9월 27일 현재 매우 최신 상태입니다.
GUID 문제에 대한 좋은 해결책은 "분산 ID 시스템"이라고 생각합니다.정확한 용어가 무엇인지는 잘 모르겠지만, MS SQL 서버 문서에서 그렇게 부르곤 했던 것 같습니다(SQL은 분산/동기화된 데이터베이스에 대해 이 방법을 사용/사용).아주 간단합니다.
서버가 모든 ID를 할당합니다.동기화가 완료될 때마다 가장 먼저 확인되는 항목은 "이 클라이언트에 남아 있는 ID가 몇 개입니까?"입니다.클라이언트가 부족할 경우 서버에 새 ID 블록을 요청합니다.그런 다음 클라이언트는 새 레코드에 대해 해당 범위의 ID를 사용합니다.이것은 다음 동기화 전에 "절대로" 부족하지 않을 만큼 큰 블록을 할당할 수 있지만 시간이 지남에 따라 서버가 부족해질 정도로 크지 않을 경우 대부분의 필요에 적합합니다.클라이언트가 부족해지면 처리가 매우 간단해질 수 있습니다. 사용자에게 "동기화할 때까지 항목을 더 추가할 수 없습니다."라고 말합니다. 항목을 추가할 경우 오래된 데이터 문제를 방지하기 위해 동기화해야 하지 않을까요?
랜덤 GUID는 100% 안전하지 않으며 일반적으로 표준 ID(128비트 대 32비트)보다 훨씬 더 길어야 하기 때문에 랜덤 GUID를 사용하는 것보다 더 우수하다고 생각합니다.일반적으로 ID별 인덱스가 있고 ID 번호를 메모리에 저장하는 경우가 많으므로 이를 작게 유지하는 것이 중요합니다.
딱히 답변으로 게시하고 싶지는 않았지만, 댓글로 볼 사람이 있을지는 모르겠지만, 이 주제에 중요하고 다른 답변에는 포함되지 않는 것이 중요하다고 생각합니다.
먼저 데이터, 표 및 관계의 수를 다시 생각해야 합니다.솔루션에서 Dropbox 파일을 통한 동기화를 구현했습니다.저는 메인 MOC의 변화를 관찰하고 이러한 데이터를 파일에 저장합니다(각 행은 gzipped json으로 저장됨).인터넷에 연결되어 있으면 Dropbox에서 변경 사항이 있는지 확인하고(Dropbox에서 델타 변경 사항이 있음) 다운로드하여 병합(최신 승리)한 후 변경된 파일을 넣습니다.동기화 전에 다른 클라이언트가 불완전한 데이터를 동기화하는 것을 방지하기 위해 Dropbox에 잠금 파일을 넣었습니다.변경 사항을 다운로드할 때 부분 데이터만 다운로드해도 안전합니다(예: 인터넷 연결 끊김).다운로드가 완료되면(전체 또는 부분) 코어 데이터에 파일을 로드하기 시작합니다.확인되지 않은 관계(모든 파일이 다운로드되지 않음)가 있는 경우 파일 로드를 중지하고 나중에 다운로드를 완료하려고 시도합니다.관계는 GUID로만 저장되므로 로드할 파일을 쉽게 확인하여 완전한 데이터 무결성을 확보할 수 있습니다.코어 데이터를 변경한 후 동기화가 시작됩니다.변경 사항이 없는 경우 몇 분마다 Dropbox 및 앱 시작 시 변경 사항을 확인합니다.추가로 변경사항이 서버로 전송될 때 다른 장치에 브로드캐스트를 보내 변경사항을 알려주어 장치가 더 빨리 동기화될 수 있도록 합니다.각 동기화된 엔티티는 GUID 속성을 가집니다(Guid는 교환 파일의 파일 이름으로도 사용됨).각 파일의 Dropbox 버전을 저장하는 Sync 데이터베이스도 있습니다(Dropbox 델타가 상태를 재설정할 때 비교할 수 있습니다).파일에는 엔티티 이름, 상태(삭제/삭제 안 함), GUID(파일 이름과 동일), 데이터베이스 수정(데이터 마이그레이션을 감지하거나 앱 버전이 없는 경우 동기화를 방지하기 위해), 그리고 물론 데이터(행이 삭제되지 않은 경우)도 포함됩니다.
이 솔루션은 수천 개의 파일과 약 30개의 엔티티에서 작동합니다.Dropbox 대신 나중에 하고 싶은 REST 웹 서비스로 키/값 저장소를 사용할 수도 있지만 그럴 시간이 없습니다. :) 현재로서는 제 솔루션이 iCloud보다 더 안정적이며, 매우 중요한 것은 작동 방식을 완전히 제어할 수 있다는 것입니다(주로 자체 코드이기 때문입니다).
또 다른 해결책은 MOC 변경 사항을 트랜잭션으로 저장하는 것입니다. 서버와 교환하는 파일 수는 훨씬 적겠지만 빈 코어 데이터에 대한 초기 로드를 적절하게 수행하는 것이 더 어렵습니다. iCloud는 이러한 방식으로 작동하며, TICoreDataSync와 같은 다른 동기화 솔루션도 유사한 방식을 사용합니다.
업데이트
잠시 후, 저는 앙상블로 이주했습니다. 저는 바퀴를 재창조하는 것보다 이 솔루션을 추천합니다.
언급URL : https://stackoverflow.com/questions/5035132/how-to-sync-iphone-core-data-with-web-server-and-then-push-to-other-devices
'programing' 카테고리의 다른 글
iOS 앱에서 문서 폴더 내부에 폴더 만들기 (0) | 2023.06.03 |
---|---|
Spnet 코어에서 Excel로 내보내기 (0) | 2023.06.03 |
SQL Server 데이터베이스 복원 오류: 지정한 캐스트가 잘못되었습니다. (SqlManager)UI) (0) | 2023.05.29 |
Internet Explorer 엔진을 사용할 수 없기 때문에 응답 내용을 구문 분석할 수 없습니다. (0) | 2023.05.29 |
명령줄의 프로세서/코어 수 (0) | 2023.05.29 |