私たちのテーブル ビュー コントローラーは、NSFetchedResultsController
コア データからのデータを表示するために を使用します。バックグラウンドで新しいデータをダウンロードします。エンティティが新しいデータで変更されると、iOS 5.1.1 電話では、更新ではなくテーブルの新しい行として扱われます。iOS 5.1 シミュレーターまたは iOS 6 デバイスでは複製できません。
は、 with 同時実行タイプUIApplicationDelegate
を作成します。私たちの道具。新しいデータを取得します。データを取得するメソッドでは、並行 Typeで秒を作成します。その新しいコンテキストでa を実行し、ネットワーク呼び出しと json 解析を実行します。以前のデータを取得するための があるため、古いオブジェクトを削除したり、同じ ID を持つ既存のエンティティを変更したりできます。既存のエンティティを変更するか、新しいエンティティを作成した後、古いエンティティ オブジェクトを削除します。次に、このプライベート コンテキストを保存します。次に、親コンテキストで aを実行して、そこに変更を保存します。NSManagedObjectContext
NSMainQueueConcurrencyType
UITableViewController
NSFetchedResultsControllerDelegate
viewWillAppear
NSManagedObjectContext
NSPrivateQueueConcurrencyType
performBlock
NSFetchRequest
deleteObject
performBlock
iOS5.1 では表が正しくありません。オブジェクトを変更すると、変更されるのではなく、新しい行としてテーブルに追加されます。このコントローラを離れて戻ってきて、新しいデータを取得すると、適切な量が表示されます。
AppDelegate.m
- (void)saveContext
{
[self.privateWriterContext performBlock:^{
NSError *error = nil;
[self.privateWriterContext save:&error];
// Handle error...
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.privateWriterContext];
}];
}
#pragma mark - Core Data stack
- (NSManagedObjectContext *)privateWriterContext
{
if (__privateWriterContext != nil) {
return __privateWriterContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__privateWriterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__privateWriterContext setPersistentStoreCoordinator:coordinator];
}
return __privateWriterContext;
}
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setParentContext:self.privateWriterContext];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(saveContext:)
name:NSManagedObjectContextDidSaveNotification
object:__managedObjectContext];
return __managedObjectContext;
}
サーバーからフェッチするクラス
+ (void) fetchFromURL:(NSString *) notificationsUrl withManagedObjectContext (NSManagedObjectContext *)managedObjectContext
{
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
importContext.parentContext = managedObjectContext;
[importContext performBlock: ^{
NSError *error;
NSURLResponse *response;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSData *responseData = [NSData dataWithContentsOfURLUsingCurrentUser:[NSURL URLWithString:notificationsUrl] returningResponse:&response error:&error];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSMutableSet *newKeys = [[NSMutableSet alloc] init];
NSArray *notifications;
if(responseData) {
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSMutableDictionary *previousNotifications = [[NSMutableDictionary alloc] init];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Notification"];
NSArray * oldObjects = [importContext executeFetchRequest:request error:&error];
for (Notification* oldObject in oldObjects) {
[previousNotifications setObject:oldObject forKey:oldObject.notificationId];
}
notifications = [json objectForKey:@"notifications"];
//create/update objects
for(NSDictionary *notificationDictionary in notifications) {
NSString *notificationId = [notificationDictionary objectForKey:@"id"];
Notification *notification = [previousNotifications objectForKey:notificationId];
if(notification) {
[previousNotifications removeObjectForKey:notificationId];
} else {
notification = [NSEntityDescription insertNewObjectForEntityForName:@"Notification" inManagedObjectContext:importContext];
[newKeys addObject:notificationId];
}
notification.notificationId = [notificationDictionary objectForKey:@"id"];
//other properties from the json response
}
for (NSManagedObject * oldObject in [previousNotifications allValues]) {
[importContext deleteObject:oldObject];
}
}
if (![importContext save:&error]) {
NSLog(@"Could not save to main context after update to notifications: %@", [error userInfo]);
}
//persist to store and update fetched result controllers
[importContext.parentContext performBlock:^{
NSError *parentError = nil;
if(![importContext.parentContext save:&parentError]) {
NSLog(@"Could not save to store after update to notifications: %@", [error userInfo]);
}
}];
}
];
}