Κάθε Προγραμματιστής iOS είναι εξοικειωμένος με τα Core Data, ένα πλαίσιο αντικειμένων και διατήρησης από την Apple. Εκτός από τη διατήρηση δεδομένων σε τοπικό επίπεδο, το πλαίσιο έρχεται με μια σειρά από προηγμένες δυνατότητες, όπως παρακολούθηση αλλαγών αντικειμένων και αναίρεση. Αυτές οι λειτουργίες, αν και είναι χρήσιμες σε πολλές περιπτώσεις, δεν παρέχονται δωρεάν. Απαιτεί πολύ κώδικα boilerplate και το πλαίσιο στο σύνολό του έχει μια απότομη καμπύλη μάθησης.
Το 2014, Βασίλειο , μια φορητή βάση δεδομένων, κυκλοφόρησε και πήρε τον κόσμο ανάπτυξης από καταιγίδα. Αν το μόνο που χρειαζόμαστε είναι να διατηρούμε δεδομένα σε τοπικό επίπεδο, το Realm είναι μια καλή εναλλακτική λύση. Σε τελική ανάλυση, δεν απαιτούν όλες οι περιπτώσεις χρήσης τα προηγμένα χαρακτηριστικά του Core Data. Το Realm είναι εξαιρετικά εύκολο στη χρήση και σε αντίθεση με τα Core Data, απαιτεί πολύ λίγο κωδικό boilerplate. Είναι επίσης ασφαλές για νήμα και λέγεται ότι είναι ταχύτερο από το πλαίσιο επιμονής της Apple.
Στις περισσότερες σύγχρονες εφαρμογές για κινητά, τα συνεχιζόμενα δεδομένα επιλύουν το μισό πρόβλημα. Συχνά πρέπει να λαμβάνουμε δεδομένα από μια απομακρυσμένη υπηρεσία, συνήθως μέσω ενός RESTful API. Εδώ είναι που Μανδύας μπαίνει στο παιχνίδι. Είναι ένα πλαίσιο ανοιχτού κώδικα για το κακάο και το κακάο αφής. Το Mantle απλοποιεί σημαντικά τη σύνταξη μοντέλων δεδομένων για αλληλεπίδραση με API που χρησιμοποιούν JSON ως μορφή ανταλλαγής δεδομένων.
Σε αυτό το άρθρο, θα δημιουργήσουμε μια εφαρμογή iOS που θα αναφέρει μια λίστα άρθρων μαζί με συνδέσμους προς αυτά από το New York Times Article Search API v2. Η λίστα θα ληφθεί χρησιμοποιώντας ένα τυπικό αίτημα HTTP GET, με μοντέλα αιτήσεων και απόκρισης που δημιουργήθηκαν χρησιμοποιώντας το Mantle. Θα δούμε πόσο εύκολο είναι με το Mantle να χειριστεί μετασχηματισμούς αξίας (π.χ. από NSDate σε string). Μόλις ληφθούν τα δεδομένα, θα τα διατηρήσουμε τοπικά χρησιμοποιώντας το Realm. Όλα αυτά με ελάχιστο κωδικό boilerplate.
ποια είναι η σημασία της συμπερίληψης των στοιχείων του σχεδιασμού στην εικαστική τέχνη
Ας ξεκινήσουμε δημιουργώντας ένα νέο έργο 'Master-Detail Application' Xcode για iOS με το όνομα 'RealmMantleTutorial'. Θα προσθέσουμε πλαίσια σε αυτό χρησιμοποιώντας CocoaPods. Το podfile πρέπει να μοιάζει με το ακόλουθο:
pod 'Mantle' pod 'Realm' pod 'AFNetworking'
Μόλις εγκατασταθούν οι λοβό, μπορούμε να ανοίξουμε το νέο που δημιουργήθηκε MantleRealmTutorial χώρος εργασίας. Όπως έχετε παρατηρήσει, έχει εγκατασταθεί και το περίφημο πλαίσιο AFNetworking. Θα το χρησιμοποιήσουμε για την εκτέλεση αιτημάτων στο API.
Όπως αναφέρεται στην εισαγωγή, οι New York Times παρέχουν ένα εξαιρετικό API αναζήτησης άρθρων. Για να το χρησιμοποιήσετε, πρέπει να εγγραφείτε για να αποκτήσετε ένα κλειδί πρόσβασης στο API. Αυτό μπορεί να γίνει στο http://developer.nytimes.com . Με το κλειδί API στο χέρι είμαστε έτοιμοι να ξεκινήσουμε με την κωδικοποίηση.
Πριν εξερευνήσουμε τη δημιουργία μοντέλων δεδομένων Mantle, πρέπει να ενεργοποιήσουμε και να λειτουργήσουμε το επίπεδο δικτύου. Ας δημιουργήσουμε μια νέα ομάδα στο Xcode και να την ονομάσουμε Δίκτυο. Σε αυτήν την ομάδα θα δημιουργούμε δύο τάξεις. Ας καλέσουμε το πρώτο SessionManager και βεβαιωθείτε ότι προέρχεται από AFHTTPSessionManager από την οποία ανήκει μια τάξη διαχειριστή συνεδρίας AFNetworking , το ευχάριστο πλαίσιο δικτύωσης. Μας 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
Ο διαχειριστής περιόδου λειτουργίας αρχικοποιείται με το βασικό URL που ορίζεται στατικά kBaseURL μεταβλητός. Θα χρησιμοποιήσει επίσης σειριοποιητές αιτήσεων και απαντήσεων JSON.
Τώρα η δεύτερη τάξη που πρόκειται να δημιουργήσουμε στο Δίκτυο θα καλείται ομάδα APIManager . Θα προέρχεται από το νεοδημιουργημένο μας SessionManager τάξη. Μόλις δημιουργηθούν τα απαραίτητα μοντέλα δεδομένων θα προσθέσουμε μια μέθοδο ApiManager που θα χρησιμοποιηθεί για να ζητήσετε μια λίστα άρθρων από το API.
Η επίσημη τεκμηρίωση για αυτό το εξαιρετικό API διατίθεται στη διεύθυνση http://developer.nytimes.com/…/article_search_api_v2 . Αυτό που πρόκειται να κάνουμε είναι να χρησιμοποιήσουμε το ακόλουθο τελικό σημείο:
http://api.nytimes.com/svc/search/v2/articlesearch
… Για ανάκτηση άρθρων που βρέθηκαν χρησιμοποιώντας έναν όρο ερωτήματος αναζήτησης της επιλογής μας, οριοθετημένο από ένα εύρος ημερομηνιών. Για παράδειγμα, αυτό που θα μπορούσαμε να κάνουμε είναι να ζητήσουμε από το API να επιστρέψει μια λίστα με όλα τα άρθρα που εμφανίστηκαν στους New York Times που είχαν σχέση με το μπάσκετ τις πρώτες επτά ημέρες του Ιουλίου 2015. Σύμφωνα με το API τεκμηρίωση , για να το κάνουμε αυτό πρέπει να ορίσουμε τις ακόλουθες παραμέτρους στο αίτημα λήψης σε αυτό το τελικό σημείο:
μάθετε c και c++
Παράμετρος | αξία |
τι | 'μπάσκετ' |
Ημερομηνία έναρξης | '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.' }
Αυτό που παίρνουμε βασικά σε απάντηση είναι τρία πεδία. Ο πρώτος κάλεσε απάντηση περιέχει τον πίνακα έγγραφα , το οποίο με τη σειρά του περιέχει αντικείμενα που αντιπροσωπεύουν άρθρα. Τα δύο άλλα πεδία είναι κατάσταση και πνευματική ιδιοκτησία . Τώρα που γνωρίζουμε πώς λειτουργεί το API, είναι καιρός να δημιουργήσουμε μοντέλα δεδομένων χρησιμοποιώντας το Mantle.
Όπως αναφέρθηκε προηγουμένως, το Mantle είναι ένα πλαίσιο ανοιχτού κώδικα που απλοποιεί σημαντικά τη σύνταξη μοντέλων δεδομένων. Ας ξεκινήσουμε δημιουργώντας ένα μοντέλο αιτήματος λίστας άρθρων. Ας καλέσουμε αυτήν την τάξη ArticleListRequestModel και βεβαιωθείτε ότι προέρχεται από Μοντέλο MTL , από την οποία πρέπει να προέρχονται όλα τα μοντέλα Mantle. Επιπλέον ας το κάνουμε να συμμορφώνεται με το MTLJSONSerialization πρωτόκολλο. Το μοντέλο αιτήματός μας πρέπει να έχει τρεις ιδιότητες κατάλληλων τύπων: ερώτημα, άρθραFromDate , και άρθραToDate . Για να βεβαιωθείτε ότι το έργο μας είναι καλά οργανωμένο, προτείνω να τοποθετηθεί αυτή η τάξη Μοντέλα ομάδα.
Το Mantle απλοποιεί τη σύνταξη μοντέλων δεδομένων, μειώνει τον κωδικό του boilerplate. ΤιτίβισμαΔείτε πώς το αρχείο διεπαφής του ArticleListRequestModel πρέπει να κοιτάξει:
#import 'MTLModel.h' #import 'Mantle.h' @interface ArticleListRequestModel : MTLModel @property (nonatomic, copy) NSString *query; @property (nonatomic, copy) NSDate *articlesFromDate; @property (nonatomic, copy) NSDate *articlesToDate; @end
Τώρα, αν αναζητήσουμε τα έγγραφα για το τελικό σημείο αναζήτησης του άρθρου μας ή ρίξουμε μια ματιά στον πίνακα με τις παραμέτρους αιτήματος παραπάνω, θα παρατηρήσουμε ότι τα ονόματα των μεταβλητών στο αίτημα API διαφέρουν από αυτά του μοντέλου αιτήματός μας. Ο μανδύας το χειρίζεται αποτελεσματικά χρησιμοποιώντας τη μέθοδο:
+ (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 έχει εφαρμοστεί, μπορούμε να λάβουμε μια αναπαράσταση λεξικού JSON του μοντέλου με τη μέθοδο κλάσης +[MTLJSONAdapter JSONArrayForModels:]
.
Ένα πράγμα που απομένει, όπως γνωρίζουμε από τη λίστα των παραμέτρων, είναι ότι και οι δύο παράμετροι ημερομηνίας πρέπει να έχουν τη μορφή 'YYYYMMDD'. Αυτό είναι όπου ο Mantle γίνεται πολύ βολικός. Μπορούμε να προσθέσουμε προσαρμοσμένη τιμή μετασχηματισμού για οποιαδήποτε ιδιότητα εφαρμόζοντας την προαιρετική μέθοδο +JSONTransformer
. Εφαρμόζοντάς το λέμε στον Μαντλ πώς πρέπει να μετατραπεί η αξία ενός συγκεκριμένου πεδίου 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 πρωτόκολλο, καθώς και εφαρμογή είναι ίσο και χασίσι μεθόδους.
Όπως έχουμε ήδη δει, το JSON που προκύπτει από την κλήση API περιέχει έναν πίνακα αντικειμένων που αντιπροσωπεύουν άρθρα. Εάν θέλουμε να μοντελοποιήσουμε αυτήν την απόκριση χρησιμοποιώντας το Mantle, θα πρέπει να δημιουργήσουμε δύο ξεχωριστά μοντέλα δεδομένων. Θα μοντελοποιήσουμε αντικείμενα που αντιπροσωπεύουν άρθρα ( έγγραφα στοιχεία πίνακα), και το άλλο θα μοντελοποιήσει ολόκληρη την απόκριση JSON εκτός από τα στοιχεία του πίνακα εγγράφων. Τώρα, δεν χρειάζεται να χαρτογραφήσουμε κάθε ιδιοκτησία από το εισερχόμενο JSON στα μοντέλα δεδομένων μας. Ας υποθέσουμε ότι ενδιαφερόμαστε μόνο για δύο πεδία αντικειμένων άρθρων, και αυτά θα ήταν lead_paragraph και web_url . ο ΆρθροΜοντέλο η τάξη είναι αρκετά απλή στην εφαρμογή, όπως μπορούμε να δούμε παρακάτω.
#import 'MTLModel.h' #import @interface ArticleModel : MTLModel @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 #import 'ArticleModel.h' @interface ArticleListResponseModel : MTLModel @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 δεν θα αντιστοιχιστεί στο μοντέλο απόκρισης. Αν κοιτάξουμε το άρθραJSONΜετασχηματιστής μέθοδος, θα δούμε ότι επιστρέφει έναν μετασχηματιστή τιμών για έναν πίνακα που περιέχει αντικείμενα κλάσης ΆρθροΜοντέλο .
Αξίζει επίσης να σημειωθεί ότι στη μέθοδο JSONKeyPathsByPropertyKey , η ιδιότητα του μοντέλου άρθρα αντιστοιχούν στα έγγραφα του πίνακα που είναι ένθετα στο χαρακτηριστικό JSON απάντηση .
Μέχρι τώρα θα πρέπει να έχουμε εφαρμόσει τρεις κατηγορίες μοντέλων: ArticleListRequestModel, ArticleModel και ArticleListResponseModel.
πώς μπορώ να ξέρω αν η llc μου είναι s corp ή c corp
Τώρα που έχουμε εφαρμόσει όλα τα μοντέλα δεδομένων, είναι καιρός να επιστρέψουμε στην τάξη APIManager για να εφαρμόσουμε τη μέθοδο που θα χρησιμοποιήσουμε για την εκτέλεση αιτημάτων GET στο API. Η μέθοδος:
- (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure
παίρνει ένα ArticleListRequestModel request model ως παράμετρος και επιστρέφει ένα ArticleListResponseΜοντέλο σε περίπτωση επιτυχίας ή άλλου σφάλματος NSE. Η εφαρμογή αυτής της μεθόδου χρησιμοποιεί AFNetworking για να εκτελέσετε ένα αίτημα GET στο API. Λάβετε υπόψη ότι για να κάνουμε ένα επιτυχημένο αίτημα 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];
Αυτό που συμβαίνει εδώ είναι ότι η χρήση της μεθόδου που παρέχεται από Προσαρμογέας MTLJSON τάξη έχουμε ένα NSDictionary αναπαράσταση του μοντέλου δεδομένων μας. Αυτή η αναπαράσταση αντικατοπτρίζει το JSON που πρόκειται να σταλεί στο API. Εδώ βρίσκεται η ομορφιά του Mantle. Μετά την εφαρμογή JSONKeyPathsByPropertyKey και +JSONTransformer
μεθόδους στην κατηγορία ArticleListRequestModel, μπορούμε να λάβουμε τη σωστή αναπαράσταση JSON του μοντέλου δεδομένων μας σε χρόνο μηδέν μόνο με μία μόνο γραμμή κώδικα.
Το Mantle μας επιτρέπει επίσης να κάνουμε μετασχηματισμούς και προς την άλλη κατεύθυνση. Και αυτό ακριβώς συμβαίνει με τα δεδομένα που λαμβάνονται από το API. Το NSDictionary που λαμβάνουμε αντιστοιχίζεται σε ένα αντικείμενο της κλάσης ArticleListResponseModel χρησιμοποιώντας την ακόλουθη μέθοδο κλάσης:
ArticleListResponseModel *list = [MTLJSONAdapter modelOfClass:ArticleListResponseModel.class fromJSONDictionary:responseDictionary error:&error];
Τώρα που είμαστε σε θέση να ανακτήσουμε δεδομένα από ένα απομακρυσμένο 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
Και αυτό θα μπορούσε ουσιαστικά να είναι, η εφαρμογή αυτής της τάξης θα μπορούσε να παραμείνει κενή. Λάβετε υπόψη ότι οι ιδιότητες στην κλάση μοντέλου δεν έχουν χαρακτηριστικά όπως μη ατομικά, ισχυρά ή αντίγραφα. Το Realm τα φροντίζει και δεν χρειάζεται να τα ανησυχούμε.
Δεδομένου ότι τα άρθρα που μπορούμε να πάρουμε είναι μοντελοποιημένα με το μοντέλο Mante Αρθρο θα ήταν βολικό να αρχικοποιήσετε Άρθρο Ρέιλ αντικείμενα με αντικείμενα κλάσης Αρθρο . Για να το κάνουμε αυτό θα προσθέσουμε initWithMantleModel μέθοδος στο μοντέλο Realm. Εδώ είναι η πλήρης εφαρμογή του Άρθρο Ρέιλ τάξη.
#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 αντικείμενο επικαλούμενος τη μέθοδο '[RLMRealm defaultRealm]'. Είναι σημαντικό να θυμάστε ότι ένα τέτοιο αντικείμενο ισχύει μόνο στο νήμα στο οποίο δημιουργήθηκε και δεν μπορεί να κοινοποιηθεί σε όλα τα νήματα. Η σύνταξη δεδομένων στο Realm είναι αρκετά απλή. Μια απλή εγγραφή, ή μια σειρά από αυτές, πρέπει να γίνει σε μια συναλλαγή εγγραφής. Ακολουθεί ένα δείγμα εγγραφής στη βάση δεδομένων:
RLMRealm *realm = [RLMRealm defaultRealm]; ArticleRealm *articleRealm = [ArticleRealm new]; articleRealm.leadParagraph = @'abc'; articleRealm.url = @'sampleUrl'; [realm beginWriteTransaction]; [realm addObject:articleRealm]; [realm commitWriteTransaction];
Αυτό που συμβαίνει εδώ είναι το ακόλουθο. Πρώτα δημιουργούμε ένα RLMRealm αντικείμενο για αλληλεπίδραση με τη βάση δεδομένων. Τότε ένα Άρθρο Ρέιλ δημιουργήθηκε αντικείμενο μοντέλου (λάβετε υπόψη ότι προέρχεται από RLMRealm τάξη). Τέλος για να το αποθηκεύσετε, ξεκινά μια συναλλαγή εγγραφής, το αντικείμενο προστίθεται στη βάση δεδομένων και μόλις αποθηκευτεί η συναλλαγή εγγραφής δεσμεύεται. Όπως μπορούμε να δούμε, οι συναλλαγές εγγραφής μπλοκάρουν το νήμα στο οποίο επικαλούνται. Ενώ το Realm λέγεται ότι είναι πολύ γρήγορο, αν θέλαμε να προσθέσουμε πολλά αντικείμενα στη βάση δεδομένων σε μία μόνο συναλλαγή στο κύριο νήμα, αυτό θα μπορούσε να οδηγήσει στο UI να μην ανταποκρίνεται έως ότου ολοκληρωθεί η συναλλαγή. Μια φυσική λύση σε αυτό είναι να εκτελέσετε μια τέτοια συναλλαγή εγγραφής σε ένα νήμα φόντου.
Αυτές είναι όλες οι πληροφορίες που χρειαζόμαστε για να διατηρήσουμε άρθρα χρησιμοποιώντας το Realm. Ας προσπαθήσουμε να εκτελέσουμε ένα αίτημα API χρησιμοποιώντας τη μέθοδο
- (NSURLSessionDataTask *) getArticlesWithRequestModel:(ArticleListRequestModel *)requestModel success:(void (^)(ArticleListResponseModel *responseModel))success failure:(void (^)(NSError *error))failure
και Mantle αιτήματα και μοντέλα απόκρισης για να λάβουμε άρθρα της New York Times που είχαν να κάνουν (όπως στο προηγούμενο παράδειγμα) με το μπάσκετ και δημοσιεύθηκαν τις πρώτες επτά ημέρες του Ιουνίου 2015. Μόλις είναι διαθέσιμη η λίστα αυτών των άρθρων, εμείς θα το επιμείνει στο 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, πρέπει να δημιουργήσουμε αντικείμενα μοντέλου Realm, τα οποία λαμβάνουν χώρα στο loop for (4). Είναι επίσης σημαντικό να παρατηρήσετε ότι δεδομένου ότι υπάρχουν πολλά αντικείμενα σε μια συναλλαγή εγγραφής, η συναλλαγή εγγραφής εκτελείται σε ένα νήμα φόντου (3). Τώρα, αφού όλα τα άρθρα αποθηκευτούν στο Realm, τα αντιστοιχίζουμε στην ιδιότητα κλάσης αυτοσωματίδια (7). Δεδομένου ότι θα έχουν πρόσβαση αργότερα στο κύριο νήμα στις μεθόδους πηγής δεδομένων TableView, είναι ασφαλές να τα ανακτήσετε και από τη βάση δεδομένων Realm στο κύριο νήμα (5). Και πάλι, για να αποκτήσετε πρόσβαση στη βάση δεδομένων από ένα νέο νήμα, πρέπει να δημιουργηθεί ένα νέο αντικείμενο RLMRealm (6) σε αυτό το νήμα.
πώς να προσδιορίσετε την ελαστικότητα της ζήτησης ως προς την τιμή
Εάν η λήψη νέων άρθρων από το API αποτύχει για οποιονδήποτε λόγο, τα υπάρχοντα ανακτώνται από τον τοπικό χώρο αποθήκευσης στο μπλοκ αποτυχίας.
Σε αυτό το σεμινάριο μάθαμε πώς να διαμορφώσουμε το Mantle, ένα πρότυπο πλαίσιο για το Cocoa και το Cocoa Touch, προκειμένου να αλληλεπιδράσουμε με ένα τηλεχειριστήριο ΦΩΤΙΑ . Μάθαμε επίσης πώς να διατηρούμε τοπικά δεδομένα που ανακτώνται με τη μορφή αντικειμένων μοντέλου Mantle χρησιμοποιώντας τη βάση δεδομένων κινητής τηλεφωνίας Realm.
Σε περίπτωση που θέλετε να δοκιμάσετε αυτήν την εφαρμογή, μπορείτε να ανακτήσετε τον πηγαίο κώδικα από το αποθετήριο του GitHub . Θα πρέπει να δημιουργήσετε και να δώσετε το δικό σας κλειδί API πριν εκτελέσετε την εφαρμογή.