这里是我的问题:
我探索过的解决方案:
NSIncrementalStore类(在IOS 5中是新的)。我很困惑这到底是怎么回事,但听起来很有希望。据我所知,您的子类是NSIncrementalStore,它允许您拦截常规的核心数据API调用。然后,我可以将这些信息传递给核心数据,并通过web服务将其与外部数据库同步。我可能完全错了。但假设我是对的,如果与互联网的连接中断,我将如何同步三角洲呢?AFIncrementalStore --这是NSIncrementalStore的一个子类,它使用AFNetworking来完成web服务部分。RestKit --我有点担心这个API有多活跃,而且它似乎正在经历向阻塞功能的过渡。有人广泛使用过这个吗?我倾向于使用AFIncrementalStore,因为这使用(似乎)一种更标准的方法。问题是,我可能完全不知道NSIncrementalStore到底是什么。
链接到一些示例代码或教程将是很棒的!
发布于 2012-08-14 22:01:18
我的解决方案是将数据集的两个副本存储在CoreData数据库中。一个表示最后一个已知的服务器状态,并且是不可变的.另一个由用户编辑。
当需要同步更改时,应用程序会在数据的编辑副本和不可更改副本之间创建一个差异。应用程序将diff发送到web服务,该服务将diff应用于自己的数据副本。它用数据集的完整副本进行回复,应用程序将其覆盖到数据的两个副本上。
其优点是:
缺点是:
以下是我在制定战略时所考虑的一些问题:
我听说过的最接近于开箱即用的支持是iOS6中新的iCloud/CoreData同步系统,当实体发生变化时,它会自动将实体从CoreData数据库传输到iCloud。但是,这意味着您必须使用iCloud。
编辑:我知道这已经很晚了,但是这里有一个类能够在两个NSManagedObject实例之间产生差异。
// SZManagedObjectDiff.h
@interface SZManagedObjectDiff
- (NSDictionary *)diffNewObject:(NSManagedObject *)newObject withOldObject:(NSManagedObject *)oldObject
@end
// SZManagedObjectDiff.m
#import "SZManagedObjectDiff.h"
@implementation SZManagedObjectDiff
- (NSDictionary *)diffNewObject:(NSManagedObject *)newObject withOldObject:(NSManagedObject *)oldObject {
NSDictionary *attributeDiff = [self diffAttributesOfNewObject:newObject withOldObject:oldObject];
NSDictionary *relationshipsDiff = [self diffRelationshipsOfNewObject:newObject withOldObject:oldObject];
NSMutableDictionary *diff = [NSMutableDictionary dictionary];
if (attributeDiff.count > 0) {
diff[@"attributes"] = attributeDiff;
}
if (relationshipsDiff.count > 0) {
diff[@"relationships"] = relationshipsDiff;
}
if (diff.count > 0) {
diff[@"entityName"] = newObject ? newObject.entity.name : oldObject.entity.name;
NSString *idAttributeName = newObject ? newObject.entity.userInfo[@"id"] : oldObject.entity.userInfo[@"id"];
if (idAttributeName) {
id itemId = newObject ? [newObject valueForKey:idAttributeName] : [oldObject valueForKey:idAttributeName];
if (itemId) {
diff[idAttributeName] = itemId;
}
}
}
return diff;
}
- (NSDictionary *)diffRelationshipsOfNewObject:(NSManagedObject *)newObject withOldObject:(NSManagedObject *)oldObject {
NSMutableDictionary *diff = [NSMutableDictionary dictionary];
NSDictionary *relationships = newObject == nil ? [[oldObject entity] relationshipsByName] : [[newObject entity] relationshipsByName];
for (NSString *name in relationships) {
NSRelationshipDescription *relationship = relationships[name];
if (relationship.deleteRule != NSCascadeDeleteRule) continue;
SEL selector = NSSelectorFromString(name);
id newValue = nil;
id oldValue = nil;
if (newObject != nil && [newObject respondsToSelector:selector]) newValue = [newObject performSelector:selector];
if (oldObject != nil && [oldObject respondsToSelector:selector]) oldValue = [oldObject performSelector:selector];
if (relationship.isToMany) {
NSArray *changes = [self diffNewSet:newValue withOldSet:oldValue];
if (changes.count > 0) {
diff[name] = changes;
}
} else {
NSDictionary *relationshipDiff = [self diffNewObject:newValue withOldObject:oldValue];
if (relationshipDiff.count > 0) {
diff[name] = relationshipDiff;
}
}
}
return diff;
}
- (NSDictionary *)diffAttributesOfNewObject:(NSManagedObject *)newObject withOldObject:(NSManagedObject *)oldObject {
NSMutableDictionary *diff = [NSMutableDictionary dictionary];
NSArray *attributeNames = newObject == nil ? [[[oldObject entity] attributesByName] allKeys] : [[[newObject entity] attributesByName] allKeys];
for (NSString *name in attributeNames) {
SEL selector = NSSelectorFromString(name);
id newValue = nil;
id oldValue = nil;
if (newObject != nil && [newObject respondsToSelector:selector]) newValue = [newObject performSelector:selector];
if (oldObject != nil && [oldObject respondsToSelector:selector]) oldValue = [oldObject performSelector:selector];
newValue = newValue ? newValue : [NSNull null];
oldValue = oldValue ? oldValue : [NSNull null];
if (![newValue isEqual:oldValue]) {
diff[name] = @{ @"new": newValue, @"old": oldValue };
}
}
return diff;
}
- (NSArray *)diffNewSet:(NSSet *)newSet withOldSet:(NSSet *)oldSet {
NSMutableArray *changes = [NSMutableArray array];
// Find all items that have been newly created or updated.
for (NSManagedObject *newItem in newSet) {
NSString *idAttributeName = newItem.entity.userInfo[@"id"];
NSAssert(idAttributeName, @"Entities must have an id property set in their user info.");
id newItemId = [newItem valueForKey:idAttributeName];
NSManagedObject *oldItem = nil;
for (NSManagedObject *setItem in oldSet) {
id setItemId = [setItem valueForKey:idAttributeName];
if ([setItemId isEqual:newItemId]) {
oldItem = setItem;
break;
}
}
NSDictionary *diff = [self diffNewObject:newItem withOldObject:oldItem];
if (diff.count > 0) {
[changes addObject:diff];
}
}
// Find all items that have been deleted.
for (NSManagedObject *oldItem in oldSet) {
NSString *idAttributeName = oldItem.entity.userInfo[@"id"];
NSAssert(idAttributeName, @"Entities must have an id property set in their user info.");
id oldItemId = [oldItem valueForKey:idAttributeName];
NSManagedObject *newItem = nil;
for (NSManagedObject *setItem in newSet) {
id setItemId = [setItem valueForKey:idAttributeName];
if ([setItemId isEqual:oldItemId]) {
newItem = setItem;
break;
}
}
if (!newItem) {
NSDictionary *diff = [self diffNewObject:newItem withOldObject:oldItem];
if (diff.count > 0) {
[changes addObject:diff];
}
}
}
return changes;
}
@end这里有更多关于它做什么、如何做以及它的限制/假设的信息:
http://simianzombie.com/?p=2379
发布于 2013-08-27 22:29:27
使用Parse平台及其IOS SDK来构造和存储信息。它可以在本地缓存数据,这样您就可以在没有连接的情况下快速检索数据。
https://stackoverflow.com/questions/11961304
复制相似问题