ios - 根据JSON删除核心数据中的对象

标签 ios objective-c json uitableview core-data

我有一个带有实体“Project”的NSManagedObjectModel。我让所有项目在带有 NSFetchedResult Controller 的 UITableView 中显示它们。现在,如果 JSON 有新项目,我会插入它们,如果 JSON 已更新项目,我会更新核心数据上下文中的项目。

所以,我的问题是当我得到一个 JSON 时,其项目少于上下文。我考虑过两种删除我的上下文中的项目的方法。一种方法是删除所有上下文并使用新项目再次保存。另一种方法是创建一个包含上下文中所有项目的数组,并通过 id 与 JSON 中的项目进行检查,如果没有一个项目,则将其删除。

我有这个想法,但不知道哪个是最好的方法。我也想过在 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;
}

最佳答案

您必须在项目类别中添加此方法,并在添加新项目后在代码中添加此方法,在该方法中传递核心数据中的数组对象,并删除所有未包含在其中的对象数组

+(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];
            }
        }
    }

}

关于ios - 根据JSON删除核心数据中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19358184/

相关文章:

ios - 如何检索详细信息披露按钮的 View ?

ios - 如何将两个 NSDictionary 或 NSMutableDictionary 的 IntersectSet 与值相交?

c++ - 如何使用 nlohmann json 从字符串中获取值类型?

ios - 替换已弃用的 AudioSessionSetProperty

ios - 以编程方式将段落标题添加到 UITextView

ios - UIView 挥动 ARM

javascript - 对嵌套的对象数组进行分组

javascript - 使用正确的时区解析 Grails 中的序列化日期

ios - 如何在不与服务器通信的情况下阻止 WKWebView 中的 304 请求加载缓存图像?

ios - 核心数据 - 复杂获取