CoreData와 REST 웹 서비스를 비동기적으로 동기화하면서 동시에 REST 오류를 UI에 적절하게 전파하는 방법
안녕하세요, 저는 저희 앱의 모델 레이어를 작업하고 있습니다.
요구 사항 중 일부는 다음과 같습니다.
- 그것은 아이폰 OS 3.0+에서 작동할 것입니다.
- 데이터의 출처는 RESTful Rails 애플리케이션입니다.
- 우리는 Core Data를 사용하여 데이터를 로컬로 캐싱해야 합니다.
- 클라이언트 코드(UI 컨트롤러)는 네트워크에 대한 지식이 최대한 적어야 하며 Core Data API를 사용하여 모델을 쿼리/업데이트해야 합니다.
서버 중심 사용자 환경 구축에 관한 WWDC10 세션 117을 확인하고 목표 리소스, 핵심 리소스 및 Restful 핵심 데이터 프레임워크를 확인하는 데 시간을 보냈습니다.
목표 리소스 프레임워크는 자체적으로 코어 데이터와 대화하지 않으며 REST 클라이언트 구현일 뿐입니다.Core Resource 및 RestfulCoreData는 모두 코드에서 CoreData와 대화하고 모델 레이어의 배경에 있는 모든 너트와 볼트를 해결한다고 가정합니다.
지금까지는 모든 것이 괜찮아 보이고 처음에는 Core Resource 또는 RestfulCoreData가 위의 모든 요구사항을 충족할 것으로 생각했지만...그 중 어느 것도 제대로 해결되지 않은 것으로 보이는 몇 가지가 있습니다.
- 로컬 업데이트를 서버에 저장하는 동안 기본 스레드를 차단해서는 안 됩니다.
- 저장 작업이 실패하면 오류가 UI로 전파되고 로컬 Core Data 스토리지에 변경 사항이 저장되지 않아야 합니다.
Core Resource는 사용자가 호출할 때 서버에 모든 요청을 발행합니다.- (BOOL)save:(NSError **)error
Managed Object Context(관리 개체 컨텍스트)에서 기본 요청의 올바른 NSError 인스턴스를 서버에 제공할 수 있습니다.그러나 저장 작업이 끝날 때까지 호출 스레드를 차단합니다.실패하다.
RestfulCoreData는 고객의 요구사항을 충족합니다.-save:
정상적으로 호출되며 클라이언트 스레드에 대한 추가 대기 시간은 제공되지 않습니다.그저 조심할 뿐입니다.NSManagedObjectContextDidSaveNotification
그런 다음 해당 요청을 통지 처리기의 서버에 발행합니다.하지만 이런 식으로.-save:
호출은 항상 성공적으로 완료되며(코어 데이터가 저장된 변경 사항에 대해 괜찮다는 것을 감안하면) 실제로 호출한 클라이언트 코드는 저장이 일부 때문에 서버에 전파되지 못했을 수도 있음을 알 수 없습니다.404
아니면421
또는 서버측 오류가 발생한 경우.게다가 로컬 스토리지는 데이터를 업데이트하게 되지만 서버는 변경 사항에 대해 전혀 알지 못합니다.실패하다.
그래서 저는 이 모든 문제를 해결하는 데 있어 가능한 해결책/일반적인 방법을 찾고 있습니다.
- 호출 스레드가 각각 차단되지 않았으면 합니다.
-save:
네트워크 요청이 발생하는 동안 호출합니다. - 어떻게든 UI에 동기화 작업이 잘못되었다는 알림을 받고 싶습니다.
- 서버 요청이 실패할 경우 실제 Core Data 저장도 실패하기를 원합니다.
무슨 생각 있어요?
이 사용 사례에 대해서는 RestKit(http://restkit.org )을 꼭 살펴보셔야 합니다.원격 JSON 리소스를 모델링하고 로컬 Core Data 지원 캐시에 동기화하는 문제를 해결하도록 설계되었습니다.사용 가능한 네트워크가 없을 때 캐시에서 전적으로 작업할 수 있는 오프라인 모드를 지원합니다.모든 동기화는 백그라운드 스레드에서 발생하며(네트워크 액세스, 페이로드 구문 분석 및 관리 개체 컨텍스트 병합), 다양한 위임 메소드가 있으므로 무슨 일이 일어나고 있는지 알 수 있습니다.
기본 구성 요소는 세 가지입니다.
- UI Action 및 CoreData에 대한 변경 유지
- 서버까지 변경 유지
- 서버의 응답으로 UI 새로 고침
NSOperation + NSOperationQueue를 사용하면 네트워크 요청을 질서 있게 유지하는 데 도움이 됩니다.위임 프로토콜은 UI 클래스가 네트워크 요청의 상태를 이해하는 데 도움이 됩니다. 예를 들어 다음과 같습니다.
@protocol NetworkOperationDelegate
- (void)operation:(NSOperation *)op willSendRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
- (void)operation:(NSOperation *)op didSuccessfullySendRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
- (void)operation:(NSOperation *)op encounteredAnError:(NSError *)error afterSendingRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
@end
프로토콜 형식은 물론 사용자의 특정 사용 사례에 따라 달라지지만 기본적으로 사용자가 작성하는 내용은 변경 사항을 서버에 "밀어" 올릴 수 있는 메커니즘입니다.
다음으로 고려해야 할 UI 루프가 있습니다. 코드를 깨끗하게 유지하려면 저장을 호출하고 변경 사항을 서버에 자동으로 푸시하는 것이 좋습니다.NSManagedObjectContextDidSave 알림을 사용할 수 있습니다.
- (void)managedObjectContextDidSave:(NSNotification *)saveNotification {
NSArray *inserted = [[saveNotification userInfo] valueForKey:NSInsertedObjects];
for (NSManagedObject *obj in inserted) {
//create a new NSOperation for this entity which will invoke the appropraite rest api
//add to operation queue
}
//do the same thing for deleted and updated objects
}
네트워크 작업을 삽입하기 위한 계산 오버헤드는 다소 낮아야 하지만 UI에 현저한 지연이 발생하는 경우 저장 알림에서 엔티티 ID를 가져와 백그라운드 스레드에서 작업을 생성할 수 있습니다.
REST API에서 배치를 지원하는 경우 배열 전체를 한 번에 보낸 다음 UI에 여러 엔티티가 동기화되었음을 알릴 수도 있습니다.
제가 예상하는 유일한 문제는 "진짜" 해결책이 없는 문제는 사용자가 자신의 변경 사항이 서버로 푸시되어 더 많은 변경이 허용될 때까지 기다리지 않을 것이라는 점입니다.제가 발견한 유일한 좋은 패러다임은 사용자가 개체를 계속 편집할 수 있도록 허용하고 적절한 경우 편집 내용을 함께 배치할 수 있다는 것입니다. 즉, 모든 저장 알림을 누르지 않습니다.
이것은 동기화 문제가 되고 해결하기 쉬운 문제가 아닙니다.제가 할 일은 이렇습니다.iPhone UI에서는 하나의 컨텍스트를 사용한 다음 다른 컨텍스트(및 다른 스레드)를 사용하여 웹 서비스에서 데이터를 다운로드합니다.모든 것이 완료되면 아래에 권장되는 동기화/가져오기 프로세스를 거치고 모든 것을 올바르게 가져온 후 UI를 새로 고칩니다.네트워크에 접속하는 동안 문제가 발생하면 비 UI 컨텍스트의 변경 사항을 롤백하기만 하면 됩니다.여러 가지 일이지만, 접근하는 것이 가장 좋은 방법이라고 생각합니다.
다른 스레드(실제 서버 상호 작용이 발생하는 스레드)에서 실행된 후 결과 코드/오류를 준글로벌 데이터에 입력하여 UI 스레드에서 주기적으로 확인하는 콜백 기능이 필요합니다.플래그 역할을 하는 숫자의 배선이 원자인지 확인하십시오. 오류 응답이 32바이트이면 int(원자 액세스 권한이 있어야 함)가 필요한 상태가 된 다음 큰 데이터 블록이 작성될 때까지 해당 int를 오프/false/not-ready 상태로 유지한 후 "true"를 입력하여 플립합니다.그는 말을 바꾸기로 했습니다.
클라이언트 측의 상관 저장을 위해서는 서버에서 롤백 옵션을 사용할 수 있는지 확인하기 위해 서버에서 확인할 때까지 해당 데이터를 저장하지 않고 보관해야 합니다(예를 들어 서버에서 삭제하는 방법이 실패했습니다.
전체 2단계 커밋 절차를 수행하지 않는 한(서버 서버의 신호가 전송된 후 클라이언트 저장 또는 삭제가 실패할 수 있음) 100% 안전하지는 않지만 최소한 서버로 이동하는 데 2번의 비용이 소요됩니다(단 하나의 롤백 옵션이 삭제되면 4번의 비용이 발생할 수 있음).
이상적으로 작업의 전체 차단 버전을 별도의 스레드에서 수행하는 것이 좋으나 이를 위해서는 4.0이 필요합니다.
언급URL : https://stackoverflow.com/questions/3077444/how-to-sync-coredata-and-a-rest-web-service-asynchronously-and-the-same-time-pro
'code' 카테고리의 다른 글
MySQL에 없는 경우 생성 프로시저를 말하는 방법 (0) | 2023.10.25 |
---|---|
Git stash: "더러운 작업 트리에 적용할 수 없습니다. 변경 사항을 스테이징하십시오." (0) | 2023.10.25 |
부트스트랩 4: 드롭다운 메뉴가 화면 오른쪽으로 꺼집니다. (0) | 2023.10.25 |
PHP 5.5의 password_hash 및 password_verify 기능 사용 (0) | 2023.10.25 |
jQuery 상위 양식 찾기 (0) | 2023.10.25 |