Mantle 및 Realm을 사용하여 iOS에서 RESTful API 사용 및 데이터 지속성 간소화

게시 됨: 2022-03-11

모든 iOS 개발자는 Apple의 객체 그래프 및 지속성 프레임워크인 Core Data에 익숙합니다. 데이터를 로컬로 유지하는 것 외에도 프레임워크에는 개체 변경 추적 및 실행 취소와 같은 고급 기능이 많이 있습니다. 이러한 기능은 많은 경우에 유용하지만 무료로 제공되지 않습니다. 많은 상용구 코드가 필요하고 프레임워크는 전체적으로 가파른 학습 곡선을 가지고 있습니다.

2014년에는 모바일 데이터베이스인 Realm이 출시되어 개발 세계를 강타했습니다. 데이터를 로컬에 유지하는 것이 전부라면 Realm이 좋은 대안입니다. 결국 모든 사용 사례에 Core Data의 고급 기능이 필요한 것은 아닙니다. Realm은 사용이 매우 간편하며 Core Data와 달리 상용구 코드가 거의 필요하지 않습니다. 또한 스레드로부터 안전하며 Apple의 지속성 프레임워크보다 빠릅니다.

대부분의 최신 모바일 애플리케이션에서 데이터를 유지하면 문제의 절반이 해결됩니다. 일반적으로 RESTful API를 통해 원격 서비스에서 데이터를 가져와야 하는 경우가 많습니다. 여기에서 맨틀이 작동합니다. Cocoa 및 Cocoa Touch용 오픈 소스 모델 프레임워크입니다. Mantle은 JSON을 데이터 교환 형식으로 사용하는 API와 상호 작용하기 위한 데이터 모델 작성을 크게 단순화합니다.

iOS용 영역 및 맨틀

이 기사에서는 New York Times 기사 검색 API v2에서 기사 목록과 기사 링크를 가져오는 iOS 애플리케이션을 구축할 것입니다. 목록은 Mantle을 사용하여 생성된 요청 및 응답 모델과 함께 표준 HTTP GET 요청을 사용하여 가져올 것입니다. Mantle을 사용하여 값 변환(예: NSDate에서 문자열로)을 처리하는 것이 얼마나 쉬운지 알게 될 것입니다. 데이터를 가져오면 Realm을 사용하여 로컬에서 유지합니다. 이 모든 것이 최소한의 상용구 코드로 가능합니다.

RESTful API - 시작하기

"RealmMantleTutorial"이라는 iOS용 "Master-Detail Application" Xcode 프로젝트를 새로 만드는 것으로 시작하겠습니다. CocoaPods를 사용하여 프레임워크를 추가할 것입니다. podfile은 다음과 유사해야 합니다.

 pod 'Mantle' pod 'Realm' pod 'AFNetworking'

포드가 설치되면 새로 생성된 MantleRealmTutorial 작업 공간을 열 수 있습니다. 아시다시피, 유명한 AFNetworking 프레임워크도 설치되었습니다. API에 대한 요청을 수행하는 데 사용할 것입니다.

소개에서 언급했듯이 New York Times는 우수한 기사 검색 API를 제공합니다. 그것을 사용하려면 API에 대한 액세스 키를 얻기 위해 가입해야 합니다. 이것은 http://developer.nytimes.com에서 할 수 있습니다. API 키가 있으면 코딩을 시작할 준비가 되었습니다.

Mantle 데이터 모델을 생성하기 전에 네트워크 계층을 시작하고 실행해야 합니다. Xcode에서 새 그룹을 만들고 이름을 네트워크라고 합시다. 이 그룹에서 우리는 두 개의 클래스를 만들 것입니다. 첫 번째 SessionManager 를 호출하고 즐거운 네트워킹 프레임워크인 AFNetworking 의 세션 관리자 클래스인 AFHTTPSessionManager 에서 파생되었는지 확인합니다. SessionManager 클래스는 API에 대한 요청 가져오기를 수행하는 데 사용할 싱글톤 개체입니다. 클래스가 생성되면 아래 코드를 인터페이스 및 구현 파일에 각각 복사하십시오.

 #import "AFHTTPSessionManager.h" @interface SessionManager : AFHTTPSessionManager + (id)sharedManager; @end
 #import "SessionManager.h" static NSString *const kBaseURL = @"http://api.nytimes.com"; @implementation SessionManager - (id)init { self = [super initWithBaseURL:[NSURL URLWithString:kBaseURL]]; if(!self) return nil; self.responseSerializer = [AFJSONResponseSerializer serializer]; self.requestSerializer = [AFJSONRequestSerializer serializer]; return self; } + (id)sharedManager { static SessionManager *_sessionManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sessionManager = [[self alloc] init]; }); return _sessionManager; } @end

세션 관리자는 정적 kBaseURL 변수에 정의된 기본 URL로 초기화됩니다. 또한 JSON 요청 및 응답 직렬 변환기를 사용합니다.

이제 네트워크 그룹에서 만들 두 번째 클래스는 APIManager 라고 합니다. 새로 생성된 SessionManager 클래스에서 파생됩니다. 필요한 데이터 모델이 생성되면 API에서 기사 목록을 요청하는 데 사용할 메서드를 ApiManager 에 추가합니다.

New York Times 기사 검색 API 개요

이 우수한 API에 대한 공식 문서는 http://developer.nytimes.com/…/article_search_api_v2에서 볼 수 있습니다. 우리가 할 일은 다음 끝점을 사용하는 것입니다.

 http://api.nytimes.com/svc/search/v2/articlesearch

... 날짜 범위로 묶인 우리가 선택한 검색어를 사용하여 찾은 기사를 가져옵니다. 예를 들어 우리가 할 수 있는 일은 2015년 7월 첫 7일 동안 농구와 관련이 있는 New York Times에 게재된 모든 기사 목록을 반환하도록 API에 요청하는 것입니다. API 문서에 따르면 그렇게 하려면 해당 엔드포인트에 대한 get 요청에서 다음 매개변수를 설정해야 합니다.

매개변수
"농구"
시작일 “20150701”
종료일 “20150707”

API의 응답은 매우 복잡합니다. 다음은 명확성을 위해 생략된 수많은 필드와 함께 단 하나의 기사(문서 배열의 한 항목)로 제한되는 위의 매개변수가 있는 요청에 대한 응답입니다.

 { "response": { "docs": [ { "web_url": "http://www.nytimes.com/2015/07/04/sports/basketball/robin-lopez-and-knicks-are-close-to-a-deal.html", "lead_paragraph": "Lopez, a 7-foot center, joined Arron Afflalo, a 6-foot-5 guard, as the Knicks' key acquisitions in free agency. He is expected to solidify the Knicks' interior defense.", "abstract": null, "print_page": "1", "source": "The New York Times", "pub_date": "2015-07-04T00:00:00Z", "document_type": "article", "news_desk": "Sports", "section_name": "Sports", "subsection_name": "Pro Basketball", "type_of_material": "News", "_id": "5596e7ac38f0d84c0655cb28", "word_count": "879" } ] }, "status": "OK", "copyright": "Copyright (c) 2013 The New York Times Company. All Rights Reserved." }

기본적으로 응답으로 얻는 것은 세 가지 필드입니다. 응답 이라는 첫 번째 항목은 문서를 나타내는 항목을 차례로 포함하는 배열 docs 를 포함합니다. 다른 두 필드는 statuscopyright 입니다. API 작동 방식을 알았으니 이제 Mantle을 사용하여 데이터 모델을 생성할 차례입니다.

맨틀 소개

앞서 언급했듯이 Mantle은 데이터 모델 작성을 크게 단순화하는 오픈 소스 프레임워크입니다. 먼저 기사 목록 요청 모델을 생성해 보겠습니다. 이 클래스를 ArticleListRequestModel이라고 하고 모든 Mantle 모델이 파생되어야 하는 클래스인 MTLModel 에서 파생되었는지 확인합니다. 또한 MTLJSONSerializing 프로토콜을 준수하도록 합시다. 우리의 요청 모델에는 query, ArticleFromDateArticleToDate 라는 적절한 유형의 세 가지 속성이 있어야 합니다. 프로젝트가 잘 구성되었는지 확인하기 위해 이 클래스를 Models 그룹에 배치하는 것이 좋습니다.

Mantle은 데이터 모델 작성을 단순화하고 상용구 코드를 줄입니다.
트위터

ArticleListRequestModel 의 인터페이스 파일은 다음과 같이 표시됩니다.

 #import "MTLModel.h" #import "Mantle.h" @interface ArticleListRequestModel : MTLModel <MTLJSONSerializing> @property (nonatomic, copy) NSString *query; @property (nonatomic, copy) NSDate *articlesFromDate; @property (nonatomic, copy) NSDate *articlesToDate; @end

이제 기사 검색 엔드포인트에 대한 문서를 찾거나 위의 요청 매개변수가 있는 테이블을 보면 API 요청의 변수 이름이 요청 모델의 이름과 다르다는 것을 알 수 있습니다. Mantle은 다음 방법을 사용하여 이를 효율적으로 처리합니다.

 + (NSDictionary *)JSONKeyPathsByPropertyKey.

다음은 요청 모델의 구현에서 이 메서드를 구현하는 방법입니다.

 #import "ArticleListRequestModel.h" @implementation ArticleListRequestModel #pragma mark - Mantle JSONKeyPathsByPropertyKey + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"query": @"q", @"articlesFromDate": @"begin_date", @"articlesToDate": @"end_date" }; } @end

이 메서드의 구현은 모델의 속성이 JSON 표현에 매핑되는 방법을 지정합니다. JSONKeyPathsByPropertyKey 메소드가 구현되면 +[MTLJSONAdapter JSONArrayForModels:] 클래스 메소드를 사용하여 모델의 JSON 사전 표현을 얻을 수 있습니다.

매개변수 목록에서 알 수 있듯이 아직 남은 한 가지는 두 날짜 매개변수가 모두 "YYYYMMDD" 형식이어야 한다는 것입니다. 이것은 Mantle이 매우 편리한 곳입니다. 선택적 메서드인 +<propertyName>JSONTransformer 를 구현하여 모든 속성에 대한 사용자 지정 값 변환을 추가할 수 있습니다. 그것을 구현함으로써 우리는 Mantle에게 JSON 역직렬화 동안 특정 JSON 필드의 값이 어떻게 변환되어야 하는지 알려줍니다. 모델에서 JSON을 생성할 때 사용할 가역 변환기를 구현할 수도 있습니다. NSDate 객체를 문자열로 변환해야 하므로 NSDataFormatter 클래스도 사용할 것입니다. 다음은 ArticleListRequestModel 클래스의 완전한 구현입니다.

 #import "ArticleListRequestModel.h" @implementation ArticleListRequestModel + (NSDateFormatter *)dateFormatter { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyyMMdd"; return dateFormatter; } #pragma mark - Mantle JSONKeyPathsByPropertyKey + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"query": @"q", @"articlesFromDate": @"begin_date", @"articlesToDate": @"end_date" }; } #pragma mark - JSON Transformers + (NSValueTransformer *)articlesToDateJSONTransformer { return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *dateString, BOOL *success, NSError *__autoreleasing *error) { return [self.dateFormatter dateFromString:dateString]; } reverseBlock:^id(NSDate *date, BOOL *success, NSError *__autoreleasing *error) { return [self.dateFormatter stringFromDate:date]; }]; } + (NSValueTransformer *)articlesFromDateJSONTransformer { return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *dateString, BOOL *success, NSError *__autoreleasing *error) { return [self.dateFormatter dateFromString:dateString]; } reverseBlock:^id(NSDate *date, BOOL *success, NSError *__autoreleasing *error) { return [self.dateFormatter stringFromDate:date]; }]; } @end

Mantle의 또 다른 훌륭한 기능은 이러한 모든 모델이 NSCoding 프로토콜을 준수하고 isEqual해시 메서드를 구현한다는 것입니다.

이미 보았듯이 API 호출의 결과 JSON에는 기사를 나타내는 객체 배열이 포함됩니다. Mantle을 사용하여 이 응답을 모델링하려면 두 개의 개별 데이터 모델을 만들어야 합니다. 하나는 문서를 나타내는 객체( 문서 배열 요소)를 모델링하고 다른 하나는 문서 배열의 요소를 제외한 전체 JSON 응답을 모델링합니다. 이제 들어오는 JSON의 모든 속성을 데이터 모델에 매핑할 필요가 없습니다. 기사 객체의 두 필드에만 관심이 있다고 가정해 보겠습니다. 이 필드는 lead_paragraphweb_url 입니다. ArticleModel 클래스는 아래에서 볼 수 있듯이 구현하기가 다소 간단합니다.

 #import "MTLModel.h" #import <Mantle/Mantle.h> @interface ArticleModel : MTLModel <MTLJSONSerializing> @property (nonatomic, copy) NSString *leadParagraph; @property (nonatomic, copy) NSString *url; @end
 #import "ArticleModel.h" @implementation ArticleModel #pragma mark - Mantle JSONKeyPathsByPropertyKey + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"leadParagraph": @"lead_paragraph", @"url": @"web_url" }; } @end

이제 기사 모델이 정의되었으므로 기사 목록에 대한 모델을 생성하여 응답 모델 정의를 완료할 수 있습니다. 다음은 ArticleList 응답 모델의 모습입니다.

 #import "MTLModel.h" #import <Mantle/Mantle.h> #import "ArticleModel.h" @interface ArticleListResponseModel : MTLModel <MTLJSONSerializing> @property (nonatomic, copy) NSArray *articles; @property (nonatomic, copy) NSString *status; @end
 #import "ArticleListResponseModel.h" @class ArticleModel; @implementation ArticleListResponseModel #pragma mark - Mantle JSONKeyPathsByPropertyKey + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"articles" : @"response.docs", @"status" : @"status" }; } #pragma mark - JSON Transformer + (NSValueTransformer *)articlesJSONTransformer { return [MTLJSONAdapter arrayTransformerWithModelClass:ArticleModel.class]; } @end

이 클래스에는 상태기사 의 두 가지 속성만 있습니다. 엔드포인트의 응답과 비교하면 세 번째 JSON 속성 copyright이 응답 모델에 매핑되지 않는다는 것을 알 수 있습니다. ArticleJSONTransformer 메서드를 보면 ArticleModel 클래스의 객체를 포함하는 배열에 대한 값 변환기를 반환한다는 것을 알 수 있습니다.

JSONKeyPathsByPropertyKey 메서드에서 모델 속성 기사 는 JSON 속성 응답 내에 중첩된 배열 문서에 해당한다는 점도 주목할 가치가 있습니다.

이제 ArticleListRequestModel, ArticleModel 및 ArticleListResponseModel의 세 가지 모델 클래스를 구현해야 합니다.

첫 번째 API 요청

편안한 API

이제 모든 데이터 모델을 구현했으므로 API에 대한 GET 요청을 수행하는 데 사용할 메서드를 구현하기 위해 APIManager 클래스로 돌아갈 시간입니다. 방법:

 - (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure

ArticleListRequestModel 요청 모델을 매개변수로 취하고 성공하면 ArticleListResponseModel을 반환하고 그렇지 않으면 NSError 를 반환합니다. 이 메서드의 구현은 AFNetworking 을 사용하여 API에 대한 GET 요청을 수행합니다. API 요청을 성공적으로 하려면 http://developer.nytimes.com에 등록하여 앞에서 언급한 대로 얻을 수 있는 키를 제공해야 합니다.

 #import "SessionManager.h" #import "ArticleListRequestModel.h" #import "ArticleListResponseModel.h" @interface APIManager : SessionManager - (NSURLSessionDataTask *)getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure; @end
 #import "APIManager.h" #import "Mantle.h" static NSString *const kArticlesListPath = @"/svc/search/v2/articlesearch.json"; static NSString *const kApiKey = @"replace this with your own key"; @implementation APIManager - (NSURLSessionDataTask *)getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure{ NSDictionary *parameters = [MTLJSONAdapter JSONDictionaryFromModel:requestModel error:nil]; NSMutableDictionary *parametersWithKey = [[NSMutableDictionary alloc] initWithDictionary:parameters]; [parametersWithKey setObject:kApiKey forKey:@"api-key"]; return [self GET:kArticlesListPath parameters:parametersWithKey success:^(NSURLSessionDataTask *task, id responseObject) { NSDictionary *responseDictionary = (NSDictionary *)responseObject; NSError *error; ArticleListResponseModel *list = [MTLJSONAdapter modelOfClass:ArticleListResponseModel.class fromJSONDictionary:responseDictionary error:&error]; success(list); } failure:^(NSURLSessionDataTask *task, NSError *error) { failure(error); }]; }

이 방법의 구현에는 두 가지 매우 중요한 일이 있습니다. 먼저 다음 줄을 살펴보겠습니다.

 NSDictionary *parameters = [MTLJSONAdapter JSONDictionaryFromModel:requestModel error:nil];

여기서 일어나는 일은 MTLJSONAdapter 클래스에서 제공하는 메서드를 사용하여 데이터 모델의 NSDictionary 표현을 얻는 것입니다. 해당 표현은 API로 전송될 JSON을 반영합니다. 여기에 맨틀의 아름다움이 있습니다. ArticleListRequestModel 클래스에서 JSONKeyPathsByPropertyKey+<propertyName>JSONTransformer 메서드를 구현하면 단 한 줄의 코드로 짧은 시간 안에 데이터 모델의 올바른 JSON 표현을 얻을 수 있습니다.

맨틀은 또한 우리가 다른 방향으로도 변형을 수행할 수 있도록 합니다. 그리고 그것이 바로 API에서 수신된 데이터에서 일어나고 있는 일입니다. 우리가 받은 NSDictionary는 다음 클래스 메서드를 사용하여 ArticleListResponseModel 클래스의 개체에 매핑됩니다.

 ArticleListResponseModel *list = [MTLJSONAdapter modelOfClass:ArticleListResponseModel.class fromJSONDictionary:responseDictionary error:&error];

Realm으로 데이터 유지

이제 원격 API에서 데이터를 가져올 수 있으므로 이를 유지할 차례입니다. 소개에서 언급했듯이 Realm을 사용하여 수행합니다. Realm은 모바일 데이터베이스이며 Core Data 및 SQLite를 대체합니다. 아래에서 볼 수 있듯이 사용하기가 매우 쉽습니다.

최고의 모바일 데이터베이스인 Realm은 Core Data와 SQLite를 완벽하게 대체합니다.
트위터

Realm에 데이터를 저장하려면 먼저 RLMObject 클래스에서 파생된 객체를 캡슐화해야 합니다. 이제 우리가 해야 할 일은 단일 기사에 대한 데이터를 저장할 모델 클래스를 만드는 것입니다. 다음은 이러한 클래스를 만드는 방법입니다.

 #import "RLMObject.h" @interface ArticleRealm : RLMObject @property NSString *leadParagraph; @property NSString *url; @end

그리고 이것은 기본적으로 이것일 수 있습니다. 이 클래스의 구현은 비어 있을 수 있습니다. 모델 클래스의 속성에는 nonatomic, strong 또는 copy와 같은 속성이 없습니다. Realm이 이를 처리하므로 걱정할 필요가 없습니다.

우리가 얻을 수 있는 기사는 Mante 모델 Article 로 모델링되기 때문에 ArticleRealm 객체를 Article 클래스의 객체로 초기화하는 것이 편리할 것입니다. 이를 위해 Realm 모델에 initWithMantleModel 메서드를 추가합니다. ArticleRealm 클래스의 완전한 구현은 다음과 같습니다.

 #import "RLMObject.h" #import "ArticleModel.h" @interface ArticleRealm : RLMObject @property NSString *leadParagraph; @property NSString *url; - (id)initWithMantleModel:(ArticleModel *)articleModel; @end
 #import "ArticleRealm.h" @implementation ArticleRealm - (id)initWithMantleModel:(ArticleModel *)articleModel{ self = [super init]; if(!self) return nil; self.leadParagraph = articleModel.leadParagraph; self.url = articleModel.url; return self; } @end

RLMRealm 클래스의 객체를 사용하여 데이터베이스와 상호 작용합니다. "[RLMRealm defaultRealm]" 메소드를 호출하여 RLMRealm 객체를 쉽게 얻을 수 있습니다. 이러한 객체는 생성된 스레드 내에서만 유효하며 스레드 간에 공유할 수 없음을 기억하는 것이 중요합니다. Realm에 데이터를 쓰는 것은 매우 간단합니다. 단일 쓰기 또는 일련의 쓰기는 쓰기 트랜잭션 내에서 수행되어야 합니다. 다음은 데이터베이스에 대한 샘플 쓰기입니다.

 RLMRealm *realm = [RLMRealm defaultRealm]; ArticleRealm *articleRealm = [ArticleRealm new]; articleRealm.leadParagraph = @"abc"; articleRealm.url = @"sampleUrl"; [realm beginWriteTransaction]; [realm addObject:articleRealm]; [realm commitWriteTransaction];

여기서 일어나는 일은 다음과 같습니다. 먼저 데이터베이스와 상호 작용할 RLMRealm 개체를 만듭니다. 그런 다음 ArticleRealm 모델 개체가 생성됩니다( RLMRealm 클래스에서 파생된다는 점에 유의하십시오). 마지막으로 저장하기 위해 쓰기 트랜잭션이 시작되고 데이터베이스에 개체가 추가되고 저장되면 쓰기 트랜잭션이 커밋됩니다. 보시다시피 쓰기 트랜잭션은 호출된 스레드를 차단합니다. Realm은 매우 빠르다고 하지만 메인 스레드의 단일 트랜잭션 내에서 데이터베이스에 여러 객체를 추가하면 트랜잭션이 완료될 때까지 UI가 응답하지 않을 수 있습니다. 이에 대한 자연스러운 솔루션은 백그라운드 스레드에서 이러한 쓰기 트랜잭션을 수행하는 것입니다.

Realm의 API 요청 및 지속 응답

이것은 Realm을 사용하여 기사를 지속하는 데 필요한 모든 정보입니다. 메소드를 사용하여 API 요청을 수행해 봅시다.

 - (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure

및 Mantle 요청 및 응답 모델을 사용하여 농구와 관련이 있고(앞의 예에서와 같이) 2015년 6월 첫 7일 동안 게시된 New York Times 기사를 가져옵니다. 이러한 기사 목록을 사용할 수 있게 되면 Realm에서 유지됩니다. 아래는 이를 수행하는 코드입니다. 우리 앱에서 테이블 뷰 컨트롤러의 viewDidLoad 메서드에 배치됩니다.

 ArticleListRequestModel *requestModel = [ArticleListRequestModel new]; // (1) requestModel.query = @"Basketball"; requestModel.articlesToDate = [[ArticleListRequestModel dateFormatter] dateFromString:@"20150706"]; requestModel.articlesFromDate = [[ArticleListRequestModel dateFormatter] dateFromString:@"20150701"]; [[APIManager sharedManager] getArticlesWithRequestModel:requestModel // (2) success:^(ArticleListResponseModel *responseModel){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // (3) @autoreleasepool { RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm deleteAllObjects]; [realm commitWriteTransaction]; [realm beginWriteTransaction]; for(ArticleModel *article in responseModel.articles){ ArticleRealm *articleRealm = [[ArticleRealm alloc] initWithMantleModel:article]; // (4) [realm addObject:articleRealm]; } [realm commitWriteTransaction]; dispatch_async(dispatch_get_main_queue(), ^{ // (5) RLMRealm *realmMainThread = [RLMRealm defaultRealm]; // (6) RLMResults *articles = [ArticleRealm allObjectsInRealm:realmMainThread]; self.articles = articles; // (7) [self.tableView reloadData]; }); } }); } failure:^(NSError *error) { self.articles = [ArticleRealm allObjects]; [self.tableView reloadData]; }];

먼저 API 호출(2)이 요청 모델(1)로 이루어지며, 이는 기사 목록이 포함된 응답 모델을 반환합니다. Realm을 사용하여 해당 기사를 유지하려면 for 루프(4)에서 발생하는 Realm 모델 객체를 생성해야 합니다. 단일 쓰기 트랜잭션 내에서 여러 개체가 지속되기 때문에 해당 쓰기 트랜잭션이 백그라운드 스레드에서 수행된다는 점에 유의하는 것도 중요합니다(3). 이제 모든 기사가 Realm에 저장되면 클래스 속성 인 self.articles (7)에 할당합니다. TableView 데이터 소스 메소드의 메인 스레드에서 나중에 액세스할 것이기 때문에 메인 스레드의 Realm 데이터베이스에서도 검색하는 것이 안전합니다(5). 다시 말하지만, 새 스레드에서 데이터베이스에 액세스하려면 해당 스레드에서 새 RLMRealm 객체를 생성해야 합니다(6).

어떤 이유에서든 API에서 새 기사를 가져오는 데 실패하면 기존 기사는 실패 블록의 로컬 저장소에서 검색됩니다.

마무리

이 튜토리얼에서는 원격 API와 상호 작용하기 위해 Cocoa 및 Cocoa Touch용 모델 프레임워크인 Mantle을 구성하는 방법을 배웠습니다. 또한 Realm 모바일 데이터베이스를 사용하여 Mantle 모델 객체의 형태로 검색된 데이터를 로컬에 유지하는 방법도 배웠습니다.

이 애플리케이션을 시험해보고 싶다면 GitHub 리포지토리에서 소스 코드를 검색할 수 있습니다. 애플리케이션을 실행하기 전에 고유한 API 키를 생성하고 제공해야 합니다.