Mantle ve Realm ile iOS'ta RESTful API Kullanımını ve Veri Kalıcılığını Basitleştirme
Yayınlanan: 2022-03-11Her iOS geliştiricisi, Apple'ın bir nesne grafiği ve kalıcılık çerçevesi olan Core Data'ya aşinadır. Yerel olarak kalıcı verilerin yanı sıra, çerçeve, nesne değişikliği izleme ve geri alma gibi bir dizi gelişmiş özellik ile birlikte gelir. Bu özellikler, birçok durumda yararlı olsa da, ücretsiz olarak gelmez. Çok fazla standart kod gerektirir ve bir bütün olarak çerçevenin dik bir öğrenme eğrisi vardır.
2014 yılında, bir mobil veri tabanı olan Realm piyasaya sürüldü ve geliştirme dünyasını kasıp kavurdu. İhtiyacımız olan tek şey verileri yerel olarak sürdürmekse, Realm iyi bir alternatiftir. Sonuçta, tüm kullanım durumları Core Data'nın gelişmiş özelliklerini gerektirmez. Realm'in kullanımı son derece kolaydır ve Core Data'nın aksine çok az ortak kod gerektirir. Ayrıca iş parçacığı için güvenlidir ve Apple'ın kalıcılık çerçevesinden daha hızlı olduğu söylenir.
Çoğu modern mobil uygulamada, kalıcı veriler sorunun yarısını çözer. Genellikle uzak bir hizmetten, genellikle bir RESTful API aracılığıyla veri almamız gerekir. İşte burada Mantle devreye giriyor. Cocoa ve Cocoa Touch için açık kaynaklı bir model çerçevesidir. Mantle, veri değişim formatı olarak JSON kullanan API'lerle etkileşim için veri modelleri yazmayı önemli ölçüde basitleştirir.
Bu makalede, makalelerin bir listesini New York Times Article Search API v2'den bağlantılarla birlikte getiren bir iOS uygulaması oluşturacağız. Liste, Mantle kullanılarak oluşturulan istek ve yanıt modelleri ile standart bir HTTP GET isteği kullanılarak getirilecektir. Mantle ile değer dönüşümlerini (örn. NSDate'den string'e) işlemenin ne kadar kolay olduğunu göreceğiz. Veriler alındıktan sonra, Realm kullanarak yerel olarak sürdüreceğiz. Tüm bunlar minimum ortak kod ile.
RESTful API - Başlarken
iOS için “RealmMantleTutorial” adlı yeni bir “Master-Detail Application” Xcode projesi oluşturarak başlayalım. CocoaPods kullanarak çerçeveler ekleyeceğiz. Podfile aşağıdakine benzemelidir:
pod 'Mantle' pod 'Realm' pod 'AFNetworking'
Podlar kurulduktan sonra yeni oluşturulan MantleRealmTutorial çalışma alanını açabiliriz. Fark ettiğiniz gibi, ünlü AFNetworking çerçevesi de kuruldu. API'ye istek gerçekleştirmek için kullanacağız.
Giriş bölümünde belirtildiği gibi, New York Times mükemmel bir makale arama API'sı sağlar. Bunu kullanmak için, API'ye bir erişim anahtarı almak için kaydolmanız gerekir. Bu, http://developer.nytimes.com adresinde yapılabilir. API anahtarı elimizdeyken, kodlamaya başlamaya hazırız.
Mantle veri modelleri oluşturmaya başlamadan önce ağ katmanımızı çalışır duruma getirmemiz gerekiyor. Xcode'da yeni bir grup oluşturalım ve buna Network diyelim. Bu grupta iki sınıf oluşturacağız. İlkini SessionManager olarak adlandıralım ve keyifli ağ çerçevesi olan AFNetworking'den bir oturum yöneticisi sınıfı olan AFHTTPSessionManager'dan türetildiğinden emin olalım. SessionManager sınıfımız, API'ye alma isteklerini gerçekleştirmek için kullanacağımız tek bir nesne olacaktır. Sınıf oluşturulduktan sonra lütfen aşağıdaki kodu sırasıyla arayüz ve uygulama dosyalarına kopyalayın.
#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
Oturum yöneticisi, statik kBaseURL değişkeninde tanımlanan temel URL ile başlatılır. Ayrıca JSON istek ve yanıt serileştiricilerini de kullanacaktır.
Şimdi Network grubunda oluşturacağımız ikinci sınıfın adı APIManager olacak. Yeni oluşturulan SessionManager sınıfımızdan türetilecektir. Gerekli veri modelleri oluşturulduktan sonra, API'den makalelerin bir listesini istemek için kullanılacak olan ApiManager'a bir yöntem ekleyeceğiz.
New York Times Makale Arama API'sine Genel Bakış
Bu mükemmel API'nin resmi belgeleri http://developer.nytimes.com/…/article_search_api_v2 adresinde mevcuttur. Yapacağımız şey aşağıdaki uç noktayı kullanmak:
http://api.nytimes.com/svc/search/v2/articlesearch
… bir tarih aralığıyla sınırlandırılmış, bizim seçtiğimiz bir arama sorgusu terimini kullanarak bulunan makaleleri getirmek için. Örneğin, API'den Temmuz 2015'in ilk yedi gününde New York Times'ta yayınlanan ve basketbolla ilgili tüm makalelerin bir listesini döndürmesini isteyebiliriz. API belgelerine göre, bunu yapmak için bu uç noktaya alma isteğinde aşağıdaki parametreleri ayarlamamız gerekiyor:
Parametre | Değer |
Q | "Basketbol" |
başlangıç tarihi | “20150701” |
bitiş tarihi | “20150707” |
API'den gelen yanıt oldukça karmaşıktır. Aşağıda, yukarıdaki parametrelerin yalnızca bir makaleyle (docs dizisindeki bir öğe) sınırlı olduğu ve çok sayıda alanın açıklığa kavuşturulması için çıkarıldığı bir isteğe yanıt verilmiştir.
{ "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." }
Temel olarak yanıt olarak aldığımız şey üç alan. Yanıt olarak adlandırılan ilki, sırayla makaleleri temsil eden öğeleri içeren docs dizisini içerir. Diğer iki alan durum ve telif hakkıdır . Artık API'nin nasıl çalıştığını bildiğimize göre, Mantle kullanarak veri modelleri oluşturma zamanı.
Manto'ya Giriş
Daha önce belirtildiği gibi, Mantle veri modellerini yazmayı önemli ölçüde basitleştiren açık kaynaklı bir çerçevedir. Bir makale listesi istek modeli oluşturarak başlayalım. Bu sınıfa ArticleListRequestModel adını verelim ve tüm Mantle modellerinin türetilmesi gereken bir sınıf olan MTLModel'den türetildiğinden emin olalım. Ek olarak, MTLJSONSerializing protokolüne uygun hale getirelim. İstek modelimiz, uygun türden üç özelliğe sahip olmalıdır: sorgu, ArticleFromDate ve ArticleToDate . Sadece projemizin iyi organize edildiğinden emin olmak için bu sınıfın Modeller grubuna yerleştirilmesini öneriyorum.
ArticleListRequestModel'in arayüz dosyasının nasıl görünmesi gerektiği aşağıda açıklanmıştır:
#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
Şimdi, makale arama bitiş noktamız için dokümanlara bakarsak veya yukarıdaki istek parametrelerinin bulunduğu tabloya bakarsak, API isteğindeki değişkenlerin adlarının istek modelimizdekilerden farklı olduğunu fark edeceğiz. Mantle, yöntemi kullanarak bunu verimli bir şekilde ele alır:
+ (NSDictionary *)JSONKeyPathsByPropertyKey.
İstek modelimizin uygulanmasında bu yöntemin nasıl uygulanması gerektiği aşağıda açıklanmıştır:
#import "ArticleListRequestModel.h" @implementation ArticleListRequestModel #pragma mark - Mantle JSONKeyPathsByPropertyKey + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"query": @"q", @"articlesFromDate": @"begin_date", @"articlesToDate": @"end_date" }; } @end
Bu yöntemin uygulanması, modelin özelliklerinin JSON temsillerine nasıl eşlendiğini belirtir. JSONKeyPathsByPropertyKey yöntemi uygulandıktan sonra, +[MTLJSONAdapter JSONArrayForModels:]
sınıf yöntemiyle modelin bir JSON sözlüğü temsilini alabiliriz.
Geriye kalan tek şey, parametre listesinden bildiğimiz gibi, her iki tarih parametresinin de “YYYYMMDD” formatında olması gerektiğidir. Mantle'ın çok kullanışlı olduğu yer burasıdır. İsteğe bağlı +<propertyName>JSONTransformer
yöntemini uygulayarak herhangi bir özellik için özel değer dönüşümü ekleyebiliriz. Bunu uygulayarak Mantle'a, JSON serisini kaldırma sırasında belirli bir JSON alanının değerinin nasıl dönüştürülmesi gerektiğini söyleriz. Modelden bir JSON oluştururken kullanılacak tersinir bir transformatör de uygulayabiliriz. Bir NSDate nesnesini bir dizgeye dönüştürmemiz gerektiğinden, NSDataFormatter sınıfını da kullanacağız. İşte ArticleListRequestModel sınıfının tam uygulaması:
#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'ın bir başka harika özelliği de, tüm bu modellerin NSCoding protokolüne uymasının yanı sıra isEqual ve hash yöntemlerini uygulamasıdır.
Daha önce gördüğümüz gibi, API çağrısından elde edilen JSON, makaleleri temsil eden bir dizi nesne içerir. Bu yanıtı Mantle kullanarak modellemek istiyorsak, iki ayrı veri modeli oluşturmamız gerekecek. Biri makaleleri ( docs dizisi öğeleri) temsil eden nesneleri modelleyecek, diğeri ise docs dizisinin öğeleri dışında tüm JSON yanıtını modelleyecektir. Artık, gelen JSON'dan her bir özelliği veri modellerimizle eşleştirmemiz gerekmiyor. Diyelim ki makale nesnelerinin yalnızca iki alanıyla ilgileniyoruz ve bunlar lead_paragraph ve web_url olacak . Aşağıda görebileceğimiz gibi, ArticleModel sınıfının uygulanması oldukça basittir.
#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
Artık makale modeli tanımlandığına göre, makale listesi için bir model oluşturarak yanıt modeli tanımını bitirebiliriz. Makale Listesi yanıt modeli sınıfının nasıl görüneceği aşağıda açıklanmıştır.

#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
Bu sınıfın yalnızca iki özelliği vardır: durum ve makaleler . Bunu uç noktadan gelen yanıtla karşılaştırırsak, üçüncü JSON özniteliği telif hakkının yanıt modeliyle eşleştirilmeyeceğini göreceğiz. Makaleler JSONTransformer yöntemine bakarsak, ArticleModel sınıfının nesnelerini içeren bir dizi için bir değer transformatörü döndürdüğünü göreceğiz.
Ayrıca JSONKeyPathsByPropertyKey yönteminde model özelliği makalelerinin JSON özniteliği yanıtı içinde yuvalanmış dizi belgelerine karşılık geldiğini belirtmekte fayda var.
Şimdiye kadar uygulanmış üç model sınıfımız olmalıdır: ArticleListRequestModel, ArticleModel ve ArticleListResponseModel.
İlk API İsteği
Artık tüm veri modellerini uyguladığımıza göre, API'ye GET istekleri gerçekleştirmek için kullanacağımız yöntemi uygulamak için APIManager sınıfına geri dönme zamanı. yöntem:
- (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure
parametre olarak bir ArticleListRequestModel istek modelini alır ve başarılı olması durumunda bir ArticleListResponseModel veya aksi takdirde bir NSError döndürür. Bu yöntemin uygulanması, API'ye bir GET isteği gerçekleştirmek için AFNetworking'i kullanır. Başarılı bir API isteğinde bulunmak için daha önce belirtildiği gibi http://developer.nytimes.com adresinden kaydolarak elde edilebilecek bir anahtar sağlamamız gerektiğini lütfen unutmayın.
#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); }]; }
Bu yöntemin uygulanmasında meydana gelen çok önemli iki şey vardır. Önce şu satıra bir göz atalım:
NSDictionary *parameters = [MTLJSONAdapter JSONDictionaryFromModel:requestModel error:nil];
Burada olan, MTLJSONAdapter sınıfı tarafından sağlanan yöntemi kullanarak veri modelimizin NSDictionary temsilini elde etmemizdir. Bu temsil, API'ye gönderilecek olan JSON'u yansıtır. Mantle'ın güzelliği burada yatıyor. ArticleListRequestModel sınıfında JSONKeyPathsByPropertyKey ve +<propertyName>JSONTransformer
yöntemlerini uyguladıktan sonra, veri modelimizin doğru JSON temsilini hiçbir zaman tek bir kod satırıyla elde edebiliriz.
Manto ayrıca diğer yönde de dönüşümler yapmamızı sağlar. API'den alınan verilerde de tam olarak bu oluyor. Aldığımız NSDictionary, aşağıdaki sınıf yöntemi kullanılarak ArticleListResponseModel sınıfının bir nesnesiyle eşlenir:
ArticleListResponseModel *list = [MTLJSONAdapter modelOfClass:ArticleListResponseModel.class fromJSONDictionary:responseDictionary error:&error];
Realm ile Kalıcı Veriler
Artık uzak bir API'den veri alabildiğimize göre, onu sürdürmenin zamanı geldi. Girişte belirtildiği gibi, bunu Realm kullanarak yapacağız. Realm, bir mobil veritabanıdır ve Core Data ile SQLite'ın yerini alır. Aşağıda göreceğimiz gibi, kullanımı son derece kolaydır.
Realm'de bir veri parçasını kaydetmek için önce RLMObject sınıfından türetilen bir nesneyi kapsüllememiz gerekir. Şimdi yapmamız gereken tek makaleler için veri depolayacak bir model sınıf oluşturmak. İşte böyle bir sınıf oluşturmanın ne kadar kolay olduğu.
#import "RLMObject.h" @interface ArticleRealm : RLMObject @property NSString *leadParagraph; @property NSString *url; @end
Ve temelde bu olabilir, bu sınıfın uygulanması boş kalabilir. Lütfen model sınıfındaki özelliklerin atomik olmayan, güçlü veya kopya gibi niteliklere sahip olmadığını unutmayın. Realm bunlarla ilgilenir ve bizim onlar için endişelenmemize gerek yok.
Alabileceğimiz makaleler Mante model Article ile modellendiğinden ArticleRealm nesnelerini Article sınıfının nesneleri ile başlatmak uygun olacaktır. Bunu yapmak için Realm modelimize initWithMantleModel yöntemini ekleyeceğiz. İşte ArticleRealm sınıfının tam uygulaması.
#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 sınıfının nesnelerini kullanarak veritabanı ile etkileşime gireriz. “[RLMRealm defaultRealm]” yöntemini çağırarak kolayca bir RLMRealm nesnesi alabiliriz. Böyle bir nesnenin yalnızca oluşturulduğu iş parçacığı içinde geçerli olduğunu ve iş parçacıkları arasında paylaşılamayacağını hatırlamak önemlidir. Realm'e veri yazmak oldukça basittir. Bir yazma işleminde tek bir yazma veya bir dizi yazma işlemi yapılmalıdır. İşte veritabanına örnek bir yazma:
RLMRealm *realm = [RLMRealm defaultRealm]; ArticleRealm *articleRealm = [ArticleRealm new]; articleRealm.leadParagraph = @"abc"; articleRealm.url = @"sampleUrl"; [realm beginWriteTransaction]; [realm addObject:articleRealm]; [realm commitWriteTransaction];
Burada olan şey şudur. İlk önce veritabanı ile etkileşime geçmek için bir RLMRealm nesnesi oluşturuyoruz. Ardından bir ArticleRealm model nesnesi oluşturulur (lütfen bunun RLMRealm sınıfından türetildiğini unutmayın). Son olarak, onu kaydetmek için bir yazma işlemi başlar, nesne veritabanına eklenir ve bir kez kaydedildikten sonra yazma işlemi tamamlanır. Gördüğümüz gibi, write işlemleri çağrıldıkları iş parçacığını bloke eder. Realm'in çok hızlı olduğu söylense de, ana iş parçacığındaki tek bir işlemde veritabanına birden fazla nesne eklersek, bu işlem bitene kadar UI'nin yanıt vermemesine neden olabilir. Bunun doğal bir çözümü, bir arka plan iş parçacığı üzerinde böyle bir yazma işlemi gerçekleştirmektir.
API İsteği ve Bölgede Kalıcı Yanıt
Realm kullanarak makaleleri sürdürmek için ihtiyacımız olan tüm bilgiler bu. Yöntemi kullanarak bir API isteği gerçekleştirmeye çalışalım.
- (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure
ve (önceki örnekte olduğu gibi) basketbolla ilgili olan ve Haziran 2015'in ilk yedi gününde yayınlanan New York Times makalelerini almak için Mantle istek ve yanıt modelleri. Bu tür makalelerin listesi hazır olduğunda, onu Diyar'da sürdürecektir. Bunu yapan kod aşağıdadır. Uygulamamızdaki tablo görünümü denetleyicisinin viewDidLoad yöntemine yerleştirilir.
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]; }];
İlk olarak, bir makale listesi içeren bir yanıt modeli döndüren bir istek modeli (1) ile bir API çağrısı yapılır (2). Bu makaleleri Realm kullanarak sürdürmek için for döngüsünde (4) yer alan Realm model nesneleri oluşturmamız gerekiyor. Ayrıca, tek bir yazma işlemi içinde birden çok nesne kalıcı olduğundan, bu yazma işleminin bir arka plan iş parçacığı üzerinde gerçekleştirildiğine dikkat etmek de önemlidir (3). Şimdi, tüm makaleler Realm'e kaydedildikten sonra, bunları self.articles (7) sınıf özelliğine atarız. Bunlara TableView veri kaynağı yöntemlerinde daha sonra ana iş parçacığından erişileceğinden, onları ana iş parçacığındaki Realm veritabanından almak da güvenlidir (5). Yine, veritabanına yeni bir iş parçacığından erişmek için, o iş parçacığı üzerinde yeni bir RLMRealm nesnesinin oluşturulması gerekir (6).
API'den yeni makaleler herhangi bir nedenle alınamazsa, mevcut olanlar arıza bloğundaki yerel depolamadan alınır.
Toplama
Bu öğreticide, uzak bir API ile etkileşim kurmak için Cocoa ve Cocoa Touch için bir model çerçevesi olan Mantle'ı nasıl yapılandıracağımızı öğrendik. Ayrıca, Realm mobil veritabanını kullanarak Mantle model nesneleri biçiminde alınan verilerin yerel olarak nasıl kalıcı hale getirileceğini öğrendik.
Bu uygulamayı denemek isterseniz, kaynak kodunu GitHub deposundan alabilirsiniz. Uygulamayı çalıştırmadan önce kendi API anahtarınızı oluşturmanız ve sağlamanız gerekecektir.