2013-10-14 3 views
2

У меня есть NSManagedObjectModel с юридическим лицом, «Проект». Я получаю все проекты, чтобы показать их в UITableView с контроллером NSFetchedResult. Теперь, если у JSON есть новые проекты, я их вставляю, и если JSON обновил элементы, я обновляю элементы в контексте Core Data.Удаление объектов в данных ядра в зависимости от JSON

Итак, моя проблема в том, что я получаю JSON с меньшим количеством предметов, чем контекст. Я подумал о двух способах удаления элементов в моем контексте. Один из способов - удалить весь контекст и снова сохранить его с помощью новых элементов. Другой способ - создать массив со всеми элементами контекста и проверить его с помощью элементов в объекте JSON по id, а если нет одного элемента, удалите его.

У меня есть идея, но я не знаю, что это лучший способ. Я тоже думал в backgroundContext.

Я использую этот метод теперь с вне удаления методов:

#pragma mark - Project List service 

- (void)getProjectListWithCpompletionBlock:(CompletionBlock)completionBlock{ 
    NSMutableURLRequest *request = [self requestWithMethod:@"GET" path:kAPIProjectList parameters:nil]; 
    [request setTimeoutInterval:kTimeOutRequest]; 

    AFJSONRequestOperation *requestOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

     NSDictionary *projects = [JSON valueForKey:kTagProjects]; 

     for (NSDictionary *projectDic in projects) { 
      Project *pro = [Project getProjectWithId: [projectDic objectForKey:kTagProjectId] ]; 
      if (pro) { 
       [Project updateProjectWithDictionary:projectDic]; 
       NSLog(@"update %@ ",[projectDic objectForKey:kTagProjectId]); 
      } else { 
       [Project createProjectWithDictionary: projectDic]; 
       NSLog(@"create %@ ",[projectDic objectForKey:kTagProjectId]); 
      } 

     } 
      [ypCoreDataManager saveContext]; 
      if (completionBlock) { 
       completionBlock(NO, nil); 
      } 
     } 
     failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *aError, id JSON) { 
      NSLog(@"%@ Failure JSNON Error%@", NSStringFromSelector(_cmd), aError); 
      if (completionBlock) { 
       completionBlock(YES, aError); 
      } 
     }]; 

    [self enqueueHTTPRequestOperation:requestOperation]; 
} 

Project + Helper моей категории проекта и здесь это код.

+ (Project *)createProjectWithDictionary:(NSDictionary *)dic { 

    Project *project = nil; 

    project = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:mainContext]; 

    project.projectId = [NSNumber numberWithInt:[[dic valueForKey:kTagProjectId] intValue]]; 
    project.title = [[dic valueForKey:kTagProjectTitle]description]; 
    project.estimatedPrice = [NSNumber numberWithInt:[[dic valueForKey:kTagProjectEstimatedPrice] floatValue]]; 
    NSMutableArray *tags = [[NSMutableArray alloc] init]; 
    tags = [dic objectForKey:kTagProjectsTags]; 

    NSMutableSet *tagSet = [[NSMutableSet alloc]init]; 
    for (NSDictionary * tagDic in tags){ 
     NSString *tagName = [tagDic objectForKey:kTagProjectTagName]; 
     Tag *tag = [Tag insertTagName:tagName inManagedObjectContext:mainContext]; 
     [tagSet addObject:tag]; 
    } 
    [project addTags:tagSet]; 



    return project; 
} 


// Return project by id 

+ (Project *)getProjectWithId:(NSString *) projectId { 

    Project *project = nil; 

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Project"]; 
    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"projectId" ascending:YES]]; 
    request.predicate = [NSPredicate predicateWithFormat:@"projectId = %@", [projectId description]]; 

    // Execute the fetch 

    NSError *error = nil; 
    NSArray *matches = [mainContext executeFetchRequest:request error:&error]; 


    if (!matches || ([matches count] > 1)) { // nil means fetch failed; more than one impossible (unique!) 
     // handle error 

    } else { // found the Project, just return it from the list of matches (which there will only be one of) 
     project = [matches lastObject]; 
    } 

return project; 
} 

// Update project 

+ (Project *)updateProjectWithDictionary:(NSDictionary *)dic { 
    Project *project = nil; 

    // Build a fetch request to see if we can find this Project in the database. 

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Project"]; 
    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES]]; 
    request.predicate = [NSPredicate predicateWithFormat:@"projectId = %@", [dic[kTagProjectId]description]]; 

    // Execute the fetch 

    NSError *error = nil; 
    NSArray *matches = [mainContext executeFetchRequest:request error:&error]; 

    // Check what happened in the fetch 

    if (!matches || ([matches count] > 1)) { // nil means fetch failed; more than one impossible (unique!) 
     // handle error 
    } else { 
     project = [matches lastObject]; 
     project.projectId = [NSNumber numberWithInt:[[dic valueForKey:kTagProjectId] intValue]]; 
     project.title = [[dic valueForKey:kTagProjectTitle]description]; 
     project.estimatedPrice = [NSNumber numberWithInt:[[dic valueForKey:kTagProjectEstimatedPrice] floatValue]]; 
     NSMutableArray *tags = [[NSMutableArray alloc] init]; 
     tags = [dic objectForKey:kTagProjectsTags]; 

     NSMutableSet *tagSet = [[NSMutableSet alloc]init]; 
     for (NSDictionary * tagDic in tags){ 
      NSString *tagName = [tagDic objectForKey:kTagProjectTagName]; 
      Tag *tag = [Tag insertTagName:tagName inManagedObjectContext:mainContext]; 
      [tagSet addObject:tag]; 
     } 
     [project addTags:tagSet]; 

    } 

    return project; 
} 
+0

у вас есть категория вашей организации проекта? если да вы можете показать свой код? –

+0

Да. там – croigsalvador

+0

вы пробовали мой код? –

ответ

3

Вы должны добавить этот метод в категорию «Проект» и в свой код после добавления нового элемента вызова этого метода, когда вы передаете объекты массива, живущие в базовых данных, и удаляете все объекты, которые больше не были у вас в массива

+(void)removeExpiredProjectBy:(NSMutableArray *)ProjectLiving inContext:(NSManagedObjectContext *)context{ 


    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Project"]; 

    if (projectLiving.count) { 

     request.predicate = [NSPredicate predicateWithFormat:@"NOT (projectId IN %@)", [projectLiving copy]]; 

     NSError *error = nil; 
     NSArray *matches = [context executeFetchRequest:request error:&error]; 
     if (matches.count != 0) { 
      for (Project *pro in matches) { 
       [context deleteObject:pro]; 
      } 
     } 
    } 

} 
+0

Да, я пытаюсь. но у меня есть некоторые проблемы. В первый раз я запускаю приложение с моим контекстом пустым. он не показывает какой-либо элемент. И если я положил после метода saveContext, то он работает, но он не сохраняет контекст – croigsalvador

+0

, вы передаете массив всего элемента, который вы хотите в базе данных? –

+0

Да. Я передаю массив. – croigsalvador

2

При обработке JSON вы можете создать список всех идентификаторов, которые были добавлены/обновлены. Затем, после этого, вы можете создать запрос на выборку с предикатом, который найдет все элементы, где NOT (id IN %@), и укажите список идентификаторов. Это вернет вам только те элементы, которые необходимо удалить.

Или, с точки зрения эффективного API, сервер должен предоставить вам список удаления, поскольку ему не нужно подтверждать элементы, которые не были изменены, если вы отправляете ему «дату последнего запроса» ...

Смежные вопросы