code

CoreData와 REST 웹 서비스를 비동기적으로 동기화하면서 동시에 REST 오류를 UI에 적절하게 전파하는 방법

starcafe 2023. 10. 25. 23:26
반응형

CoreData와 REST 웹 서비스를 비동기적으로 동기화하면서 동시에 REST 오류를 UI에 적절하게 전파하는 방법

안녕하세요, 저는 저희 앱의 모델 레이어를 작업하고 있습니다.

요구 사항 중 일부는 다음과 같습니다.

  1. 그것은 아이폰 OS 3.0+에서 작동할 것입니다.
  2. 데이터의 출처는 RESTful Rails 애플리케이션입니다.
  3. 우리는 Core Data를 사용하여 데이터를 로컬로 캐싱해야 합니다.
  4. 클라이언트 코드(UI 컨트롤러)는 네트워크에 대한 지식이 최대한 적어야 하며 Core Data API를 사용하여 모델을 쿼리/업데이트해야 합니다.

서버 중심 사용자 환경 구축에 관한 WWDC10 세션 117을 확인하고 목표 리소스, 핵심 리소스 및 Restful 핵심 데이터 프레임워크를 확인하는 데 시간을 보냈습니다.

목표 리소스 프레임워크는 자체적으로 코어 데이터와 대화하지 않으며 REST 클라이언트 구현일 뿐입니다.Core Resource 및 RestfulCoreData는 모두 코드에서 CoreData와 대화하고 모델 레이어의 배경에 있는 모든 너트와 볼트를 해결한다고 가정합니다.

지금까지는 모든 것이 괜찮아 보이고 처음에는 Core Resource 또는 RestfulCoreData가 위의 모든 요구사항을 충족할 것으로 생각했지만...그 중 어느 것도 제대로 해결되지 않은 것으로 보이는 몇 가지가 있습니다.

  1. 로컬 업데이트를 서버에 저장하는 동안 기본 스레드를 차단해서는 안 됩니다.
  2. 저장 작업이 실패하면 오류가 UI로 전파되고 로컬 Core Data 스토리지에 변경 사항이 저장되지 않아야 합니다.

Core Resource는 사용자가 호출할 때 서버에 모든 요청을 발행합니다.- (BOOL)save:(NSError **)errorManaged Object Context(관리 개체 컨텍스트)에서 기본 요청의 올바른 NSError 인스턴스를 서버에 제공할 수 있습니다.그러나 저장 작업이 끝날 때까지 호출 스레드를 차단합니다.실패하다.

RestfulCoreData는 고객의 요구사항을 충족합니다.-save:정상적으로 호출되며 클라이언트 스레드에 대한 추가 대기 시간은 제공되지 않습니다.그저 조심할 뿐입니다.NSManagedObjectContextDidSaveNotification그런 다음 해당 요청을 통지 처리기의 서버에 발행합니다.하지만 이런 식으로.-save:호출은 항상 성공적으로 완료되며(코어 데이터가 저장된 변경 사항에 대해 괜찮다는 것을 감안하면) 실제로 호출한 클라이언트 코드는 저장이 일부 때문에 서버에 전파되지 못했을 수도 있음을 알 수 없습니다.404아니면421또는 서버측 오류가 발생한 경우.게다가 로컬 스토리지는 데이터를 업데이트하게 되지만 서버는 변경 사항에 대해 전혀 알지 못합니다.실패하다.

그래서 저는 이 모든 문제를 해결하는 데 있어 가능한 해결책/일반적인 방법을 찾고 있습니다.

  1. 호출 스레드가 각각 차단되지 않았으면 합니다.-save:네트워크 요청이 발생하는 동안 호출합니다.
  2. 어떻게든 UI에 동기화 작업이 잘못되었다는 알림을 받고 싶습니다.
  3. 서버 요청이 실패할 경우 실제 Core Data 저장도 실패하기를 원합니다.

무슨 생각 있어요?

이 사용 사례에 대해서는 RestKit(http://restkit.org )을 꼭 살펴보셔야 합니다.원격 JSON 리소스를 모델링하고 로컬 Core Data 지원 캐시에 동기화하는 문제를 해결하도록 설계되었습니다.사용 가능한 네트워크가 없을 때 캐시에서 전적으로 작업할 수 있는 오프라인 모드를 지원합니다.모든 동기화는 백그라운드 스레드에서 발생하며(네트워크 액세스, 페이로드 구문 분석 및 관리 개체 컨텍스트 병합), 다양한 위임 메소드가 있으므로 무슨 일이 일어나고 있는지 알 수 있습니다.

기본 구성 요소는 세 가지입니다.

  1. UI Action 및 CoreData에 대한 변경 유지
  2. 서버까지 변경 유지
  3. 서버의 응답으로 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

반응형