ç¹ã«
RESTã¢ãŒããã¯ãã£ã䜿çšããWebãµãŒãã¹ã¯ããã§ã«ç§ãã¡ã®ç掻ã«ãã£ãããšå
¥ã£ãŠããŸãã iOSçšã®ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåãå€ãã®å ŽåããµãŒããŒããããŒã¿ãããŠã³ããŒãããããŒã«ã«ã«ä¿å/衚瀺ããå¿
èŠããããŸãã åæã«ãç§ãã¡èªèº«ã®ãèªè»¢è»ãã®çºæã«é Œãããšãªãããããç°¡åãã€èªç¶ã«è¡ããããšæããŸãã
iOSããã³OSXçšã®æåãªObjective-C
RestKitãã¬ãŒã ã¯ãŒã¯ã®ææ°ããŒãžã§ã³ã¯ãRESTful APIã§ã®äœæ¥ã倧å¹
ã«ç°¡çŽ åããŸãã ééããªããæã䟡å€ã®ããæ©èœã®1ã€ã¯ã
CoreDataã䜿çšããŠãªããžã§ã¯ããããŒã«ã«ããŒã¿ããŒã¹ã«èªåçã«ä¿åããæ©èœã§ãã ãµãŒããŒããã®ããŒã¿ã®åä¿¡ãããiOSããã€ã¹ã§ã®ããŒã¿ã®ä¿åãšè¡šç€ºãŸã§ãé·ãéã®ããæ©ã¿ãŸãããã ãããŠãç§ãã¡ãéå±ããªãããã«ãäŸãšããŠãäžççã«æåãªæŒ«ç»æ¬äŒç€ŸMarvelã®APIã䜿çšããŸãã
ãã®èšäºã¯äžçš®ã®ãã¥ãŒããªã¢ã«ã§ãã èªè
ã¯ãiOS SDKãCore Dataãããã³ãããã¯ãªã©ã®æŠå¿µã䜿çšããŠãObjective-Cã®éçºã®åºæ¬æŠå¿µã«æ¢ã«ç²ŸéããŠããããšãåæãšãªã£ãŠããŸãã

1.ããŒãååŸããåé¡ãå®åŒåãã
éå§ããã«ã¯ã
Marvel Webãµã€ãã§éçºè
ãšããŠç»é²ããŸãããã
ç°¡åãªç»é²ã®åŸã[
ã¢ã«ãŠã³ã ]ã¿ãã«ç§»åããŠãå
¬éããŒãšç§å¯ããŒãã³ããŒããŸãã

ãã®åŸãã
察話åããã¥ã¡ã³ããã¿ãã«ç§»åããŠãAPIäœæè
ã芪åã«æäŸããããŒã¿ã®çš®é¡ã確èªããŸãã ããŒããŒãã³ããã¯ãã¯ãªãšã€ã¿ãŒãã€ãã³ããªã©ã®ããŒã¿ããŒã¹ã䜿çšããæ©äŒããããŸãã æ
£ããã«ã¯ã1ã€ã®ããšããã¿ãããããã ãã§ååãªã®ã§ãå°æ¥ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãåã«ãã£ã©ã¯ã¿ãŒã®ãªã¹ããã¢ããããŒãããŠä¿åããæã人æ°ã®ãããã£ã©ã¯ã¿ãŒã®èª¬æã衚瀺ããŸãã
2.ã¯ããã«
Xcodeã§æ°ãããããžã§ã¯ããäœæããŸãã ããã€ã¹ãšããŠiPhoneãéžæãããããžã§ã¯ãäœæãŠã£ã¶ãŒããŠã£ã³ããŠã®[ã³ã¢ããŒã¿ã䜿çš]ãã£ãŒã«ãã®æšªã«ãã§ãã¯ããŒã¯ãæ®ãããšãå¿ããªãã§ãã ããã
ããŒã¿ã«ã«æ»ãã
Character
ãªããžã§ã¯ãã®æ§é ãæ€èšããŸãã
ãã£ã©ã¯ã¿ãŒãªããžã§ã¯ã Character { id (int, optional): The unique ID of the character resource., name (string, optional): The name of the character., description (string, optional): A short bio or description of the character., modified (Date, optional): The date the resource was most recently modified., resourceURI (string, optional): The canonical URL identifier for this resource., urls (Array[Url], optional): A set of public web site URLs for the resource., thumbnail (Image, optional): The representative image for this character., comics (ComicList, optional): A resource list containing comics which feature this character., stories (StoryList, optional): A resource list of stories in which this character appears., events (EventList, optional): A resource list of events in which this character appears., series (SeriesList, optional): A resource list of series in which this character appears. }
ã©ããå¿
èŠã§ããããïŒ ãããããç§ãã¡ã¯èå¥åãååãåçã説æã«èªåèªèº«ãå¶éããŠããŸãã Xcodeã®* .xcdatamodeldãã¡ã€ã«ã«é²ã¿ããªã¢ãŒããªããžã§ã¯ãã«è«ççã«ïŒéšåçã«ã§ã¯ãããïŒå¯Ÿå¿ãã
Character
ãšã³ãã£ãã£ãäœæããŸãããã

ç§ã¯æå³çã«2ã€ã®èå¥åãäœæããŸãããæåã®
charID
ã¯ãå°æ¥ã®ããã€ãã£ãããŒãã«ãã®
id
ãæ ŒçŽãã圹å²ãæããã2çªç®ã®
innerID
ã¯ããŒã«ã«ã§ã®äœ¿çšã«å¿
èŠã§ãã
charDescription
屿§ãšname屿§ã¯ããããããªã¢ãŒããã©ã¡ãŒã¿ãŒã®èª¬æãšååã«å¯Ÿå¿ããŠããŸãã
ãŸãã2ã€ã®å±æ§
thumbnailImageData
ãš
thumbnailURLString
äœæããŸããããå
ã®æ§é ã®ãã©ã¡ãŒã¿ãŒãšã¯äžèŽããŸããã ããã¯ãJSONå¿çã§
Image
ã¿ã€ãã®
thumbnail
å®éã«èŸæžãšäžèŽããããã§ãã å®éã®åçã®
thumbnail
ãªããžã§ã¯ãã®äŸã次ã«ç€ºããŸãã
"thumbnail": { "path": "http://i.annihil.us/u/prod/marvel/i/mg/8/c0/4ce5a0e31f109", "extension": "jpg" }
å°æ¥çã«ã¯ããããã©ã®ããã«äœ¿çšãããã瀺ããŸãã
ããŠãCore Dataãšã³ãã£ãã£ãæ£ããåäœãããã«ã¯ãããã衚ãObjective-Cã¯ã©ã¹ãäœæããå¿
èŠããããŸãã
NSManagedObject
ããç¶æ¿ãã
Character
ã¯ã©ã¹ãäœæããŸãã 圌ã®çºè¡šã¯æ¬¡ã®ãšããã§ãã
@interface Character : NSManagedObject { NSDictionary *_thumbnailDictionary; } @property (nonatomic, retain) NSString *name; @property (nonatomic, retain) NSNumber *charID; @property (nonatomic, retain) NSNumber *innerID; @property (nonatomic, retain) NSString *charDescription; @property (nonatomic, retain) NSData *thumbnailImageData; @property (nonatomic, retain) NSString *thumbnailURLString; @property NSDictionary *thumbnailDictionary;
ããã§ã¯ãæãããªé©åæ§ã«å ããŠã
thumbnailDictionary
ããããã£ã
thumbnailDictionary
ãããŸãããããã¯ãå°ãäžã«æžãããµã ãã€ã«ãªããžã§ã¯ãã§ã®äœæ¥ããã䟿å©ã«ããããã«è¿œå ããŸããã ãŸãããããžã§ã¯ãã«è¿œå ã®ã¯ã©ã¹ãäœæããªãããã«ã2ã€ã®ãã«ããŒã¯ã©ã¹ã¡ãœããã远å ããŸããã
3. RestKitã䜿çšããããã®ã¢ãã«
ãããžã§ã¯ãRestKitïŒä»¥é-RKïŒã«æ¥ç¶ããŸãã ãããè¡ãæ¹æ³ã«ã€ããŠã¯ã
ãã ïŒãŸãã¯ãCocoaPodsã奜ããªå Žåã¯
ãã¡ãïŒã§è©³ãã説æã
ãŸã ã
次ã®ã¹ãããã¯ãRKãç¹ã«
RKObjectManager
ã
RKManagedObjectStore
ãªã©ã®ã¯ã©ã¹ã§
GDMarvelRKObjectManager
ããã©ãããŒã¯ã©ã¹
GDMarvelRKObjectManager
ïŒ
NSObject
ïŒãäœæããããš
RKManagedObjectStore
ã ãã®ã¯ã©ã¹ã¯äœæãããªãå ŽåããããŸãããä»åŸã®ã¡ã€ã³ãã¥ãŒã³ã³ãããŒã©ãŒã§ã³ãŒããå°ããªãããŒãããããã«äœ¿çšããŸãã
RKã¯ã©ã¹ã«ã€ããŠå°ãã
RKManagedObjectStore
ã¯Core Dataã®ãã¹ãŠã®äœæ¥ãã«ãã»ã«åãããããå°æ¥çã«
NSManagedObjectContext
ãŸãã¯
NSManagedObjectModel
çŽæ¥
NSManagedObjectContext
ããå¿
èŠã¯ãããŸããã
RKObjectManager
ã¯ããªããžã§ã¯ãã®ãããã³ã°ïŒäžèŽïŒã䜿çšããŠèŠæ±ãéä¿¡ããå¿çãåä¿¡ããããã®éäžåãããã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŸãã ããšãã°ãJSONå¿çã§ååŸãããå¿
èŠãªå€ã¯ããããã³ã°ãæåãããšããªããžã§ã¯ãã®ãã¹ãŠã®ããããã£ã«èªåçã«å²ãåœãŠãããŸãã èšäºã®åé ã§ãããæ¬²ããã£ãã®ã§ã¯ãªãã§ããããïŒ
* .hãã¡ã€ã«ã«RK
#import <RestKit/RestKit.h>
ãå«ããããšãå¿ããªãã§ãã ããã
ã©ãããŒã¯ã©ã¹ã«ã¯ããããã£ã¯ãããŸãããã2ã€ã®ã€ã³ã¹ã¿ã³ã¹å€æ°ããããŸãã
@implementation GDMarvelRKObjectManager { RKObjectManager *objectManager; RKManagedObjectStore *managedObjectStore; }
ãã¹ãŠãæ£åžžã«æ©èœããããã«èšå®ããå¿
èŠããããã®ãèŠãŠã¿ãŸãããã
ãŸãã
- (id)init
ã¡ãœããã§ãå¿
èŠãªRKãªããžã§ã¯ãã®åæåã远å ããŸãã
ããã§ããªã¯ãšã¹ããéä¿¡ãããŸãã Core Dataã®æäœã¯ã©ãã§ããïŒ ã¿ã€ãRKManagedObjectStoreã®ãªããžã§ã¯ããæ§æããã¡ãœãããäœæããŸãããã
- (void)configureWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel { if (!managedObjectModel) return; managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; NSError *error; if (!RKEnsureDirectoryExistsAtPath(RKApplicationDataDirectory(), &error)) RKLogError(@"Failed to create Application Data Directory at path '%@': %@", RKApplicationDataDirectory(), error); NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"RKMarvel.sqlite"]; if (![managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error]) RKLogError(@"Failed adding persistent store at path '%@': %@", path, error); [managedObjectStore createManagedObjectContexts]; objectManager.managedObjectStore = managedObjectStore; }
æåŸã®è¡ã¯éåžžã«éèŠã§ãã 2ã€ã®äž»èŠãªRKãªããžã§ã¯ãã§ãã
objectManager
ãš
managedObjectStore
ãªã³ã¯ããŸãã
ãããã£ãŠãä»åŸã®ã¿ã¹ã¯ã¯ã
GDMarvelRKObjectManager
ã¯ã©ã¹ã«2ã€ã®äž»èŠãªã¢ã¯ã·ã§ã³çšã®ã€ã³ã¿ãŒãã§ã€ã¹ãäœæããããšã§ããã³ã¢ããŒã¿ãšã³ãã£ãã£ãšãªã¢ãŒããªããžã§ã¯ãéã®ãããã³ã°ïŒéä¿¡ïŒã®è¿œå ãããã³ãªã¢ãŒããµãŒããŒããã®ãããã®ãªããžã§ã¯ãã®åä¿¡ã§ãã
æåã®ã¿ã¹ã¯ã¯ã次ã®ã¡ãœããã§å®è£
ãããŸãã
- (void)addMappingForEntityForName:(NSString *)entityName andAttributeMappingsFromDictionary:(NSDictionary *)attributeMappings andIdentificationAttributes:(NSArray *)ids andPathPattern:(NSString *)pathPattern { if (!managedObjectStore) return; RKEntityMapping *objectMapping = [RKEntityMapping mappingForEntityForName:entityName inManagedObjectStore:managedObjectStore];
ããã§ã¯ã
responseDescriptorWithMapping:...
ã¡ãœããã®ããã€ãã®ãã©ã¡ãŒã¿ãŒã«é¢å¿ããããŸã
responseDescriptorWithMapping:...
æåã«ã
pathPattern
ãã©ã¡ãŒã¿ãŒã ãã¯ã
MARVEL_API_PATH_PATTERN
ïŒå€
@"v1/public/"
ïŒãšå
¥åãã©ã¡ãŒã¿ãŒ
pathPattern
ïŒãã®äŸã§ã¯
@"characters"
ïŒãé£çµããããšã«ãã£ãŠååŸãããŸãã ãã£ã©ã¯ã¿ãŒã®ãªã¹ãã§ã¯ãªããããšãã°ã³ããã¯ã®ãªã¹ããååŸãããå Žåã¯ã
@âcomicsâ
ãšããè¡ãæž¡ããŸãããã®è¡ã¯ãã¡ãœããã®æ¬æã§ãã§ã«
@"v1/public/"
æ¥ç¶ãããŸãã
2çªç®ã®éèªæãªå€ã¯ã
@"data.results"
ãã©ã¡ãŒã¿ãŒã®
@"data.results"
ãã©ã¡ãŒã¿ãŒã§ãã ã©ãããæ¥ãã®ïŒ ãã¹ãŠãéåžžã«ç°¡åã§ããMarvelã¯ãã¹ãŠã®åçãåãã©ãããŒã§ã©ãããããã®æ§é ãèŠããšãã¹ãŠãé©åã«é
眮ãããŸãã
ãã£ã©ã¯ã¿ãŒã©ãã㌠{ "code": "int", "status": "string", "copyright": "string", "attributionText": "string", "attributionHTML": "string", "data": { "offset": "int", "limit": "int", "total": "int", "count": "int", "results": [ { "id": "int", "name": "string", "description": "string", "modified": "Date", "resourceURI": "string", "urls": [ { "type": "string", "url": "string" } ], "thumbnail": { "path": "string", "extension": "string" }, "comics": { "available": "int", "returned": "int", "collectionURI": "string", "items": [ { "resourceURI": "string", "name": "string" } ] }, "stories": { "available": "int", "returned": "int", "collectionURI": "string", "items": [ { "resourceURI": "string", "name": "string", "type": "string" } ] }, "events": { "available": "int", "returned": "int", "collectionURI": "string", "items": [ { "resourceURI": "string", "name": "string" } ] }, "series": { "available": "int", "returned": "int", "collectionURI": "string", "items": [ { "resourceURI": "string", "name": "string" } ] } } ] }, "etag": "string" }
ããŒããŒã®å®éã®ãªã¹ãã«å°éããåã«ãRKãç®çã®æ§é ã«å°éããããã«ããã€ãã®ã¬ãã«ã®èŸæžãééããå¿
èŠãããããšã¯æããã§ãã å€
@"data.results"
ã¯ããããŠã³ãããå¿
èŠããããã¹ã瀺ããŠããŸãã
å
éšRKãªããžã§ã¯ããæäœããã¯ã©ã¹ã®2çªç®ã®ã¡ãœããã¯
getMarvelObjectsAtPath
ã«ãªã
getMarvelObjectsAtPath
ãããã¯ãæ¬è³ªçã«
RKObjectManager
åã®ãªããžã§ã¯ãã®
getObjectsAtPath
ãžã®åŒã³åºãããããã·ããŸãã ã¡ãœããã®ååã¯ã話ããã§ã-åé€ããããªããžã§ã¯ãã®èªã¿èŸŒã¿ãæåŸ
ããŠããŸãã Marvel
ã§ã¯ ããªã¯ãšã¹ãããšã«ããã·ã¥ãã¿ã€ã ã¹ã¿ã³ããå
¬éããŒãéä¿¡ãã
å¿
èŠãããããããããã®ãã©ã¡ãŒã¿ãŒã®çæã
getMarvelObjectsAtPath
ã«ã«ãã»ã«åãããšäŸ¿å©
getMarvelObjectsAtPath
ã ããã«ãããŸãïŒ
- (void)getMarvelObjectsAtPath:(NSString *)path parameters:(NSDictionary *)params success:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure {
ã³ãŒãã¯
NSString
-
MD5String
äžã®éæšæºã«ããŽãªã®ã¡ãœããã䜿çšããããšã«æ³šæããŠãã ããã åç·ããMD5-trokãçæããæ¹æ³
ã«ã€ããŠã¯ãã€ã³ã¿ãŒããããã芧
ãã ãã ã
ãã®ã¯ã©ã¹ã«ã¯ãã·ã³ãã«ãªã¡ãœãã
- (NSManagedObjectContext *)managedObjectContext
ã
- (NSManagedObjectContext *)managedObjectContext
ã®ã¡ã€ã³ã³ã³ããã¹ãã
managedObjectStore
ãŸãã ãŸãããã®ã¯ã©ã¹ã¯ãã€ã³ã¹ã¿ã³ã¹ã«ã¢ã¯ã»ã¹ããããã®
+ (GDMarvelRKObjectManager *)manager
ã¡ãœãããæã€ïŒ
Singleton ïŒã·ã³ã°ã«ãã³ã«ãªããŸãã
4.ã¡ã€ã³ViewController
ãŸããåºæ¬çãª
GDBaseViewController
ã³ã³ãããŒã©ãŒãäœæããŸãããã®ã³ã³ãããŒã©ãŒã§ã¯ããµãŒããŒããã®å¿çã®ã¢ãã¡ãŒã·ã§ã³åãããåŸ
æ©ã®ãµããŒãããå¯äžã®æ°ããã¡ãœãã
- (void)animateActivityIndicator:(BOOL)animate
ã
viewDidLoad
ã¡ãœããã§
viewDidLoad
ã¿ã€ã
UIActivityIndicatorView
ãã®ã€ã³ãžã±ãŒã¿ãŒãäœæããååŸããå€ãã€ã³ã¹ã¿ã³ã¹å€æ°
UIActivityIndicatorView *activityIndicator
å²ãåœãŠãŠã
UIActivityIndicatorView
ã«è¿œå ã
self.view
ã
ã¢ãã¡ãŒã·ã§ã³ã®ãªã³/ãªãã¡ãœããã«ã¯ã次ã®ã³ãŒãããããŸãã
animateActivityIndiââcatorïŒã³ãŒã - (void)animateActivityIndicator:(BOOL)animate { activityIndicator.hidden = !animate; if (animate) { [self.view bringSubviewToFront:activityIndicator]; [activityIndicator startAnimating]; } else [activityIndicator stopAnimating]; }
ããŠãåäžã®ãã©ã¡ãŒã¿ãŒã«
YES
å€ãæå®ããŠãã®ã¡ââãœãããåŒã³åºããšãView Controllerã¯æ¬¡ã®ããã«ãªããŸãã

次ã«ããã®ã¯ã©ã¹ããç¶æ¿ãã
GDMainViewController
Controller
GDMainViewController
äœæã
GDMainViewController
ã 圌ã®çºè¡šã¯æ¬¡ã®ãšããã§ãã
@interface GDMainViewController : GDBaseViewController <UITableViewDataSource, UITableViewDelegate, UIAlertViewDelegate> { UITableView *table; NSInteger numberOfCharacters; AllAroundPullView *bottomPullView; BOOL noRequestsMade; } @end
ãã®View Controllerã§ã¯ãããŒã¿ããŒã¹ã®ããŒã¿ã衚瀺ããŸãã ãããè¡ãã«ã¯ã
UITableView
ã€ã³ã¹ã¿ã³ã¹ã䜿çšã
UITableView
ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãåã»ã«ã«ç»åãšåæåã®ååã衚瀺ãããŸãã ãã ããæåã¯ããŒã«ã«ããŒã¿ããŒã¹ã空ãªã®ã§ããŸã ããŠã³ããŒãããå¿
èŠããããŸãã
- (void)viewDidLoad
ã§ã®
UITableView
ã€ã³ã¹ã¿ã³ã¹ã®äœæã«åºæã®ãã¹ãŠã®åæåããã»ã¹ã®åŸã
GDMarvelRKObjectManager
ã©ãããŒ
GDMarvelRKObjectManager
ã䜿çšããŠã
RKManagedObjectStore
CoreDataã¢ãã«ãRKManagedObjectStoreã«ãã€ã³ãããŸãã
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Marvel" withExtension:@"momd"]; [[GDMarvelRKObjectManager manager] configureWithManagedObjectModel:[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]];
ã芧ã®ãšããããªã¢ãŒããªããžã§ã¯ãã®JSONããŒã®ååãšäœæããã¯ã©ã¹ã®ããããã£ãšã®å¯Ÿå¿ãããªãèŸæžã¯ã
andAttributeMappingsFromDictionary:
ãã©ã¡ãŒã¿ãŒãšããŠæž¡ãããŸãã
andPathPattern:
ãã©ã¡ãŒã¿ãŒãšããŠãæåå
@"characters"
ãæž¡ãããŸãïŒãã¯ã
MARVEL_API_CHARACTERS_PATH_PATTERN
ïŒ-ãªã¢ãŒãJSONãªããžã§ã¯ãã®ååã
ãããã³ã°ã远å ããåŸã
[self loadCharacters]
ã¡ãœãããåŒã³åºããŸãã
圌ãããŠããããšãè©³çŽ°ã«æ€èšããŠãã ããïŒ
- (void)loadCharacters { numberOfCharacters = [Character allCharsCountWithContext:[[GDMarvelRKObjectManager manager] managedObjectContext]]; if (noRequestsMade && numberOfCharacters > 0) { noRequestsMade = NO; return; } [self animateActivityIndicator:YES]; noRequestsMade = NO; [[GDMarvelRKObjectManager manager] getMarvelObjectsAtPath:MARVEL_API_CHARACTERS_PATH_PATTERN parameters:@{@"offset" : @(numberOfCharacters)} success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { [self animateActivityIndicator:NO]; NSInteger newInnerID = numberOfCharacters; for (Character *curCharacter in mappingResult.array) { if ([curCharacter isKindOfClass:[Character class]]) { curCharacter.innerID = @(newInnerID); newInnerID++;
æåã«ãããŒã«ã«ããŒã¿ããŒã¹ããæåã®ç·æ°ãååŸããŸãããã®å€ã¯ãã¡ã€ã³ããŒãã«ã®ã»ã«ã®æ°ã«å¯Ÿå¿ããŸãã ã¢ããªã±ãŒã·ã§ã³ãæåã«èµ·åãããšããã¡ãããŒãã«ãªããŸãã ãµãŒããŒã«ã¢ã¯ã»ã¹ãããšãã«ãéä¿¡ããããªãã»ãããã©ã¡ãŒã¿ãŒãšåãå€ã䜿çšããŸãã ãããã£ãŠã以éã®åãªã¯ãšã¹ãã«å¯ŸããŠãMarvelãµãŒããŒã¯æ°ããããŒããŒãªããžã§ã¯ãã®ã¿ãè¿ããŸãïŒããã©ã«ãã§ã¯ãããŒããŒã¯ãããã20åã®ããã¯ãè¿ããŸãïŒã
次ã«ã
getMarvelObjectsAtPath
ã©ãããŒ
getMarvelObjectsAtPath
ã䜿çšããŠåãã¡ã€ã³ãªã¯ãšã¹ãã
getMarvelObjectsAtPath
ãŸãã
ãã®ã¡ãœããã«ã¯ãä»ç§ãã¡ã«ãšã£ãŠéèŠãª2ã€ã®ãã©ã¡ãŒã¿ãŒããããŸãããããã¯æåãšå€±æã§ãããããããã¯ãšãªå®è¡ã®æåãšå€±æã®çµæã®åäœãèšè¿°ãããããã¯ã§ãã ãã®ãããæåã®é
åãæ£åžžã«åä¿¡ãããšãåæåã®
innerID
ãçæããããŒã«ã«ããŒã¿ããŒã¹ã«ä¿åããŠãæåã®ç·æ°ã®å€ã倿ŽããŸãã æ¬¡ã«ãããŒãã«ã®è¡šç€ºãæŽæ°ããŸãã ããã§ã®äž»ãªéæ³ã¯ããã®æ®µéã§ãåä¿¡ãããªããžã§ã¯ãããã§ã«CoreDataã¹ãã¬ãŒãžã«èªåçã«ä¿åãããŠããããšã§ã-RKããããè¡ããŸããã ïŒããã¯ããããã³ã°ã®äžèŽãæå®ããããªããžã§ã¯ãã®ãã£ãŒã«ã/ããããã£ã«ã®ã¿é©çšãããããšã«æ³šæãã䟡å€ããããŸãããããã£ãŠãäžèšã®ã³ãŒãã§ã¯ã
[self saveToStore]
åŒã³åºããŠ
innerID
ãã©ã¡ãŒã¿ãŒã®å€æŽãåå¥ã«ä¿åããå¿
èŠããããŸãïŒã
ãšã©ãŒãçºçããå ŽåããŠãŒã¶ãŒã«è¡šç€ºããã ãã§ãããŒãã«ã¯æŽæ°ããŸããã
ã³ãŒãã¯æ¬¡ã®ã¹ãã¬ãŒãžã¡ãœããã䜿çšããŸãã
- (void)saveToStore { NSError *saveError; if (![[[GDMarvelRKObjectManager manager] managedObjectContext] saveToPersistentStore:&saveError]) XLog(@"%@", [saveError localizedDescription]); }
ãŸãã
bottomPullView
ã€ã³ã¹ã¿ã³ã¹
bottomPullView
ãžã®åç
§ã«ã泚ç®ããŠãã ããã ãã®å€æ°ã¯ãã¿ã€ã
AllAroundPullView
ïŒ
GitHubãã AllAroundPullView
ïŒã®ãªããžã§ã¯ããä¿åããŸããããã¯ã
UIScrollView
ãã¹ãŠã®åŽé¢ããPull-To-Resfreshåäœãå®è£
ããã®ã«åœ¹ç«ã€äŸ¿å©ãªã³ã³ãããŒã«ã§ãã ãã£ã©ã¯ã¿ãŒã®æ¬¡ã®åéšåãããŒãããããŒãã«ã®äžç«¯ã«å°éããŠåŒãäžããŸãã
以åã®
- (void)viewDidLoad
ãã®ã³ã³ãããŒã«ã¯æ¬¡ã®ããã«åæåããã䜿çšãããŸããã
bottomPullView = [[AllAroundPullView alloc] initWithScrollView:table position:AllAroundPullViewPositionBottom action:^(AllAroundPullView *view){ [self loadCharacters]; }]; bottomPullView.hidden = YES; [table addSubview:bottomPullView];
ã芧ã®ãšããããã©ã¡ãŒã¿ãŒã¢ã¯ã·ã§ã³ãšããŠæž¡ããããããã¯ã®æ¬äœã«ãæ°ããããŒããŒãèªã¿èŸŒãããã®åãã¡ãœãã
loadCharacters
ãŸãã
ããŠããšãã¥ã¬ãŒã¿ã§ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããæåã®æåããå¿çãåŸ
ã¡ãŸãã ãã¹ãŠã
I restkit.network:RKObjectRequestOperation.m:220 GET 'http://your-url.here' (200 OK / 20 objects)
ãRKãã¬ãŒã
I restkit.network:RKObjectRequestOperation.m:220 GET 'http://your-url.here' (200 OK / 20 objects)
ãããªãã®
I restkit.network:RKObjectRequestOperation.m:220 GET 'http://your-url.here' (200 OK / 20 objects)
å Žåããã¹ãŠãæ£åžžã§ããã確èªã§ããŸããªããžã§ã¯ããããŒã¹ã«ä¿æããããã©ããã
ãããè¡ãã«ã¯ããšãã¥ã¬ãŒã¿ãŒãã©ã«ããŒã«ç§»åããã¢ããªã±ãŒã·ã§ã³ãšDocumentsãã©ã«ããŒãèŠã€ããŸãã
RKMarvel.sqlite
ããŒã¹ã
RKMarvel.sqlite
ã¯ãã§ãïŒããã¯ã以åã«
addSQLitePersistentStoreAtPath:
ã¡ãœãããåŒã³åºããšãã«ãã©ã¡ãŒã¿ãŒãšããŠæå®ããååã§ãïŒã ãã®ããŒã¹ãSQLite-editorã§éãããã£ã©ã¯ã¿ãŒãä¿åãããŠããããšã確èªããŸãããã

ãã£ãïŒ äžéšã®ããŒããŒã«ã¯ãå°ããªèª¬æãããããŸãã ãã®ãè¯ãããã®ãã¹ãŠã衚瀺ããæéã§ãã
5.ç»åãšãã£ã¹ãã¬ã€ã®ä¿åã
ãã£ãã¡ãªèªè
ã圌ã®å¥œããªãã£ã©ã¯ã¿ãŒã®ç»åãèŠãããšãã£ãšæã£ãŠããããšãç¥ã£ãŠããŸãã ãããè¡ãã«ã¯ãããŒãã«ã®å€èгãã«ã¹ã¿ãã€ãºããå¿
èŠããããŸãã
UITableView
åã®ãªããžã§ã¯ãã®äœæãšèšå®ã®æè¡çãªè©³çްã¯èª¬æããŸããïŒèªè
ã¯èªè
ãæ¢ã«ãããç¥ã£ãŠãããšæ³å®ããŠããŸãïŒããããã«ã»ã«ãäœæããããŒãã«ã®ããªã²ãŒãã¡ãœããã«é²ã¿ãŸãã
tableViewïŒcellForRowAtIndexPathïŒã³ãŒã - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger row = indexPath.row; NSString *reusableIdentifier = [NSString stringWithFormat:@"%d", row % 2]; UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:reusableIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reusableIdentifier]; cell.autoresizingMask = UIViewAutoresizingFlexibleWidth; } [[cell.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; if (numberOfCharacters > row) { Character *curCharacter = [Character charWithManagedObjectContext: [[GDMarvelRKObjectManager manager] managedObjectContext] andInnerID:row]; if (curCharacter) { BOOL charHasDescription = ![curCharacter.charDescription isEqualToString:@""]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, CGRectGetWidth(cell.contentView.frame) - 70 - (charHasDescription ? 60 : 0), 60)]; label.backgroundColor = [UIColor clearColor]; label.text = curCharacter.name; label.autoresizingMask = UIViewAutoresizingFlexibleWidth; [cell.contentView addSubview:label]; GDCellThumbnailView *thumbnail = [GDCellThumbnailView thumbnail]; if (curCharacter.thumbnailImageData) [thumbnail setImage:[UIImage imageWithData:curCharacter.thumbnailImageData]]; else [self loadThumbnail:thumbnail fromURLString:curCharacter.thumbnailURLString forCharacter:curCharacter]; [cell.contentView addSubview:thumbnail]; cell.accessoryType = charHasDescription ? UITableViewCellAccessoryDetailButton : UITableViewCellSelectionStyleNone; cell.selectionStyle = charHasDescription ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone; } } return cell; }
次ã®ã»ã«ãäœæããåŸãç®çã®ããŒããŒãããŒã¿ããŒã¹ããååŸãããã®ååã衚瀺ããŸãããŸãã圌ã«é¢ãã詳现æ
å ±ããããã©ããã確èªããã»ã«ã«ãã¿ã³ãé
眮ããŸããã¯ãªãã¯ãããšããã®æ
å ±ã衚瀺ãããŸãã ãŸãããããŠæãéèŠãªããš-ãã£ã©ã¯ã¿ãŒã®ã€ã¡ãŒãžã ãã®ããã«ãç¹å¥ãªã¯ã©ã¹
GDCellThumbnailView
ãäœæãããã®ã€ã³ã¹ã¿ã³ã¹ãã»ã«ã«é
眮ããŸããã ç¹å¥ãªããšã¯äœãããããµã ãã€ã«ãèªã¿èŸŒãŸãããŸã§åŸ
æ©ãããå転ããè±ãã衚瀺ããã ãã§ãã
loadThumbnail:fromURLString:forCharacter:
ã¡ãœããã空ã®å Žåãã¡ã€ã³ãã¥ãŒã³ã³ãããŒã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã

ããŒããŒã®åçãèªã¿èŸŒãããã®ã¡ãœãããå®è£
ããŸãããã RKã«ã¯ãã§ã«
AFNetworking
ãã¬ãŒã ã¯ãŒã¯ãå«ãŸããŠãããããããã䜿çšããŠãåçãã¢ããããŒãããããã®éåæèŠæ±ãMarvelãµãŒããŒã«éä¿¡ããŸãã
- (void)loadThumbnail:(GDCellThumbnailView *)view fromURLString:(NSString *)urlString forCharacter:(Character *)character { XLog(@"Loading thumbnail for %@", character.name); AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { character.thumbnailImageData = responseObject; [self saveToStore]; [view setImage:[UIImage imageWithData:responseObject]]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { XLog(@"%@", [error localizedDescription]); }]; [operation start]; }
以äžã§ãã ã¢ããªã±ãŒã·ã§ã³ãå床起åããŸãã ãã§ã«è¯ãçµæã§ãã

ããã§åæ¢ããã®ã¯é£ãããªããŸãããèš±å¯ãåŸãŠã䟿å©ãªPull-To-Refreshã³ã³ãããŒã«ã䜿çšããŠããå€ãã®ãã£ã©ã¯ã¿ãŒãããŒãããŸãã åæã«ãçŸåšã®ããŒã¹ã®å€èгã確èªããŸãã

ããã§ãã€ã³ã¿ãŒãããã«æ¥ç¶ããŠãããã©ããã«é¢ä¿ãªããããŒããŒã«é¢ããåçãšæ
å ±ïŒãã¡ãããããŠã³ããŒããããã®ã ãïŒã®äž¡æ¹ãããŒã«ã«ã«ä¿åãããŸãã6.çµè«ã
RestKitã¯ã¿ã¹ã¯ã«å®å
šã«å¯Ÿå¿ããŸããããªã¯ãšã¹ããéä¿¡ãããã¬ã¹ãã³ã¹ãåä¿¡ããããªããžã§ã¯ããèªåçã«ä¿åãããŸãããã®èšäºã§æäŸãããŠããããŒããšè¡šç€ºã®ååã誰ãã奜ããšã¯éããŸãããããŒã¿ããŒã¹å
šäœãããã«ããã¬ãŒãããããŒã«ã«ã§å®å
šã«æäœããæ¹ãåççã§ããå¯èœæ§ããããŸããèè
ã¯ãRKã®åºæ¬çãªæ©èœãçè§£ããã«ã¯ããã®ãããªæ©èœã§ååã§ãããšèããŠããŸãããããžã§ã¯ãå
šäœã®ãœãŒã¹ã³ãŒãïŒããã³ç¹å®ã®ãã£ã©ã¯ã¿ãŒã«é¢ããæ
å ±ã衚瀺ãããã®èšäºã«ãªãéšåïŒã¯ãGitHubããããŠã³ããŒãã§ããŸããèšäºãžã®ã³ã¡ã³ããšããŠããŸãGitHubã§ã®ããŒã«ãªã¯ãšã¹ããšããŠãããªãã®åžæãšã³ã¡ã³ããæè¿ããŸããæåŸã«ãå¥ã®ç»åããé¡ãããŸããä»åã¯ã2çªç®ã®View Controllerã®ã¹ã¯ãªãŒã³ã·ã§ããã§ããã¡ã€ã³View Controllerã®ããŒããŒã®ååã®æšªã«ãããæ
å ±ããã¿ã³ãã¯ãªãã¯ãããšéããŸããéåžžã«é·ãéãããŒãã«ãã¹ã¯ããŒã«ããŠæçµçã«ããŒãããŸããã