Last active
August 29, 2015 13:57
-
-
Save tonnylitao/9657887 to your computer and use it in GitHub Desktop.
CoreData Entity ImportFromApi, before import(Find-or-Create), we delete local not exist data first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSManagedObject+ImportFromApi.m | |
// ThermometerBLE | |
// | |
// Created by Tonny on 3/4/14. | |
// Copyright (c) 2014 Doouya. All rights reserved. | |
// | |
#import "NSManagedObject+ImportFromApi.h" | |
#import "CommunityHeader.h" | |
@implementation NSManagedObject (ImportFromApi) | |
+ (void) DY_importFromArray:(NSArray *)array completion:(DYIndexBlock)completion | |
{ | |
[self DY_importFromArray:array importBlock:nil deletePredicateBlock:nil completion:completion]; | |
} | |
+ (void) DY_importFromArray:(NSArray *)array importBlock:(DYTwoObjectBlock)importBlock deletePredicateBlock:(DYPredicateBlock)predicateBlock completion:(DYIndexBlock)completion{ | |
#ifdef DEBUG | |
__block NSPredicate *deletePre = nil; | |
NSDate *startD = [NSDate date]; | |
NSMutableArray *needUpdateIds = [NSMutableArray arrayWithCapacity:array.count]; | |
NSMutableArray *add = [NSMutableArray arrayWithCapacity:array.count]; | |
#endif | |
NSUInteger count = array.count; | |
[NSManagedObjectContext childSaveWithBlock:^(NSManagedObjectContext *localContext) {//use default context instead of child of root context | |
NSAttributeDescription *primaryAttribute = [[self MR_entityDescription] MR_primaryAttributeToRelateBy]; //topicId | |
NSString *key = [primaryAttribute name]; //topicId | |
if (predicateBlock) { //delete | |
NSPredicate *pre = nil; | |
if (count > 0) { | |
id first = [[array firstObject] MR_valueForAttribute:primaryAttribute]; | |
id last = [[array lastObject] MR_valueForAttribute:primaryAttribute]; | |
NSInteger max = MAX([first integerValue], [last integerValue]); | |
NSInteger min = MIN([first integerValue], [last integerValue]); | |
NSArray *values = [array valueForKeyPath:[[primaryAttribute userInfo] valueForKey:kMagicalRecordImportAttributeKeyMapKey]]; //id | |
pre = predicateBlock(key, min, max, values, localContext); | |
}else{ //0 | |
pre = predicateBlock(key, 0, 0, nil, localContext); | |
} | |
if (pre) { | |
#ifdef DEBUG | |
SLLog(@"delete pre %@", pre); | |
deletePre = pre; | |
NSArray *deleted = [self MR_findAllWithPredicate:pre inContext:localContext]; | |
SLog(@"Import Delete %@ %@", NSStringFromClass([self class]), [[deleted valueForKeyPath:key] componentsJoinedByString:@","]); | |
#endif | |
[self MR_deleteAllMatchingPredicate:pre inContext:localContext]; | |
} | |
} | |
if (count > 0) { | |
///update | |
NSArray *allIds = [array valueForKeyPath:@"id"]; | |
NSPredicate *updatePre = [NSPredicate predicateWithFormat:@"%K IN %@", key, allIds]; | |
NSArray *exist = [self MR_findAllWithPredicate:updatePre inContext:localContext]; | |
NSMutableArray *needUpdate = exist.count>0?[exist mutableCopy]:nil; | |
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
id Id = obj[@"id"]; | |
NSManagedObject *mamObj = nil; | |
if (needUpdate && needUpdate.count > 0) { //update | |
NSInteger location = [[needUpdate valueForKeyPath:key] indexOfObject:Id]; | |
if (location != NSNotFound) { | |
mamObj = needUpdate[location]; | |
[needUpdate removeObject:mamObj]; | |
#ifdef DEBUG | |
[needUpdateIds addObject:Id]; | |
#endif | |
} | |
} | |
if (!mamObj) { | |
#ifdef DEBUG | |
[add addObject:Id]; | |
#endif | |
mamObj = [self MR_createInContext:localContext]; //create | |
} | |
[mamObj MR_importValuesForKeysWithObject:obj]; | |
if (importBlock) { | |
importBlock(obj, mamObj); | |
} | |
}]; | |
//delete repeat data | |
SLog(@"Import Delete Repeate %@ %@", NSStringFromClass([self class]), [[needUpdate valueForKeyPath:key] componentsJoinedByString:@","]); | |
[needUpdate enumerateObjectsUsingBlock:^(NSManagedObject *obj, NSUInteger idx, BOOL *stop) { | |
[obj MR_deleteInContext:localContext]; | |
}]; | |
SLog(@"Import Update %@ %@", NSStringFromClass([self class]), [needUpdateIds componentsJoinedByString:@","]); | |
SLog(@"Import Add %@ %@", NSStringFromClass([self class]), [add componentsJoinedByString:@","]); | |
} | |
} completion:^(BOOL success, NSError *error) { | |
completion(count); | |
#ifdef DEBUG | |
if (deletePre) { | |
NSAssert([self MR_countOfEntitiesWithPredicate:deletePre] == 0, @"Something wrong?"); | |
} | |
NSTimeInterval intervalD = [startD timeIntervalSinceNow]; | |
SLLog(@"timeInterval %f", ABS(intervalD)); | |
#endif | |
}]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Improve: