iOS iCloud 确实在第二台设备上同步对象,但不同步对象的属性
NonSyncing 属性:类别
应用程序:通用 iOS,CoreData 库样式,使用 FRC 处理 tableViews,没有 GarbageCollection
设备:5.1.1 上的 iPhone 4、iPad 1 都运行相同的 iOS 应用程序。
XCode 4.3.2
数据模型:
** 实体关系目标反向 **
Recipe categories Category recipes
Category recipes Recipe categories
相关对象:Recipe 和Category,第一个有可选的to-many 属性类别,第二个有成对的可选to-many 属性recipe。Recipe 的其他属性包括成分、NSString*
程序:在 iPad 应用程序上,在 MOC 中创建一个新配方,然后我将现有类别添加到配方 obj 中,然后添加一些成分文本。然后我保存:到MOC,--唯一保存:调用。新食谱在 iPhone 上与配料文本同步,但缺少在 iPad 上添加和保存的类别。此搜索类别在添加它的 iPad 上“有效”,但在 iPhone 上无效,也就是说,该类别未添加到第二台设备的新配方的类别属性中。iCloud 将两个 *.cdt 文件放在 iPhone 上。
下面是Recipe和Category的Class接口和实现文件,以及iPhone上出现的两个Log文件的内容plist
- 问题:我希望这些信息足以让您告诉我在哪里寻找修复?我不确定在这里提供什么信息。iCloud 不应该自己处理这个属性同步吗?
谢谢您阅读此篇!标记
// Recipe.h
#import <CoreData/CoreData.h>
@class Category;
@class Photo;
@interface Recipe : NSManagedObject
{
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * recipeID;
@property (nonatomic, retain) NSNumber * ctime;
@property (nonatomic, retain) NSString * ingredients;
@property (nonatomic, retain) NSString * comments;
@property (nonatomic, retain) NSString * nameShort;
@property (nonatomic, retain) NSString * directions;
@property (nonatomic, retain) NSNumber * ptime;
@property (nonatomic, retain) NSSet* photos;
@property (nonatomic, retain) NSSet* categories;
- (NSComparisonResult)compareRecipeNames:(Recipe *)recipe;
@end
@interface Recipe (CoreDataGeneratedAccessors)
- (void)addPhotosObject:(Photo *)value;
- (void)removePhotosObject:(Photo *)value;
- (void)addPhotos:(NSSet *)value;
- (void)removePhotos:(NSSet *)value;
- (void)addCategoriesObject:(Category *)value;
- (void)removeCategoriesObject:(Category *)value;
- (void)addCategories:(NSSet *)value;
- (void)removeCategories:(NSSet *)value;
@end
//
// Recipe.m
#import "Recipe.h"
#import "Category.h"
#import "Photo.h"
@implementation Recipe
@dynamic name;
@dynamic recipeID;
@dynamic ctime;
@dynamic ingredients;
@dynamic comments;
@dynamic nameShort;
@dynamic directions;
@dynamic ptime;
@dynamic junk;
@dynamic photos;
@dynamic categories;
- (id)init{
self = [super init];
return self;
}
- (void)addCategories:(NSSet *)value{
[self willChangeValueForKey:@"categories"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:value];
[[self primitiveCategories] unionSet:value];
[self didChangeValueForKey:@"categories"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:value];
}
- (void)addCategoriesObject:(Category *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"categories" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"categories"] addObject:value];
[self didChangeValueForKey:@"categories" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)removeCategoriesObject:(Category *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"categories" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"categories"] removeObject:value];
[self didChangeValueForKey:@"categories" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)addPhotosObject:(Photo *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"photos" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"photos"] addObject:value];
[self didChangeValueForKey:@"photos" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)removePhotosObject:(Photo *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"photos" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"photos"] removeObject:value];
[self didChangeValueForKey:@"photos" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (NSComparisonResult)compareRecipeNames:(Recipe *)recipe {
// Compare nodes to each other by comparing the data part.
return [self.name compare:[recipe name] options:NSCaseInsensitiveSearch];
}
@end
-- Category.h
//Category.h
#import <CoreData/CoreData.h>
@class Recipe;
@interface Category : NSManagedObject
{
}
@property (nonatomic, retain) NSString * nameShort;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet* recipes;
@property (nonatomic, retain) NSNumber* sortIndex;
- (NSComparisonResult) compareCategoryNames:(Category *)category ;
- (NSComparisonResult) compareCategorySortIndeces:(Category *)category;
@end
@interface Category (CoreDataGeneratedAccessors)
- (void)addRecipesObject:(Recipe *)value;
- (void)removeRecipesObject:(Recipe *)value;
- (void)addRecipes:(NSSet *)value;
- (void)removeRecipes:(NSSet *)value;
@end
//
// Category.m
//
#import "Category.h"
#import "Recipe.h"
@implementation Category
@dynamic nameShort;
@dynamic name;
@dynamic recipes;
@dynamic sortIndex;
- (void)addRecipesObject:(Recipe *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"recipes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"recipes"] addObject:value];
[self didChangeValueForKey:@"recipes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)removeRecipesObject:(Recipe *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"recipes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"recipes"] removeObject:value];
[self didChangeValueForKey:@"recipes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (NSComparisonResult) compareCategoryNames:(Category *)category
{
return [[self name] localizedCaseInsensitiveCompare: [category name]];
}
- (NSComparisonResult) compareCategorySortIndeces:(Category *)category
{
if ([self sortIndex] > [category sortIndex]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([self sortIndex] < [category sortIndex]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}
@end
-- 来自 cdt 文件的第一个 plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compressedGlobalIDs</key>
<array>
<string>0:0:0</string>
<string>1:1:0</string>
<string>0:2:0</string>
<string>0:3:0</string>
<string>0:4:0</string>
<string>0:5:0</string>
<string>0:6:0</string>
<string>0:7:0</string>
<string>0:8:0</string>
<string>0:9:0</string>
<string>0:10:0</string>
<string>0:11:0</string>
<string>0:12:0</string>
<string>0:13:0</string>
</array>
<key>deleted</key>
<dict/>
<key>entityNames</key>
<array>
<string>Recipe</string>
<string>Category</string>
</array>
<key>inserted</key>
<dict>
<key>0</key>
<dict>
<key>categories</key>
<array>
<string>1</string>
</array>
<key>ctime</key>
<integer>0</integer>
<key>name</key>
<string>Aaa Rx D</string>
<key>photos</key>
<array/>
<key>ptime</key>
<integer>0</integer>
<key>recipeID</key>
<integer>0</integer>
</dict>
</dict>
<key>kvStr</key>
<string>mobile.F0F5BE6D-59A3-5D63-A0B2-4767EFECC603:1</string>
<key>modelVersionHash</key>
<string>9FRYa_LmmBTIAw8875pOlLyYmr5vrP1Hwi~lgvsHL1k=</string>
<key>peerIDs</key>
<array>
<string>mobile.F0F5BE6D-59A3-5D63-A0B2-4767EFECC603</string>
</array>
<key>peerStates</key>
<dict/>
<key>primaryKeys</key>
<array>
<string>p89</string>
<string>p6</string>
<string>p43</string>
<string>p4</string>
<string>p41</string>
<string>p5</string>
<string>p52</string>
<string>p58</string>
<string>p68</string>
<string>p13</string>
<string>p79</string>
<string>p28</string>
<string>p17</string>
<string>p25</string>
</array>
<key>transactionDate</key>
<real>1343676810.7298651</real>
<key>transactionNumber</key>
<integer>1</integer>
<key>updated</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>Desserts</string>
<key>recipes</key>
<array>
<string>2</string>
<string>3</string>
<string>4</string>
<string>5</string>
<string>6</string>
<string>7</string>
<string>8</string>
<string>9</string>
<string>0</string>
<string>10</string>
<string>11</string>
<string>12</string>
<string>13</string>
</array>
<key>sortIndex</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
-第二个plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compressedGlobalIDs</key>
<array>
<string>0:0:0</string>
<string>1:1:0</string>
<string>0:2:0</string>
<string>0:3:0</string>
<string>0:4:0</string>
<string>0:5:0</string>
<string>0:6:0</string>
<string>0:7:0</string>
<string>0:8:0</string>
<string>0:9:0</string>
<string>0:10:0</string>
<string>0:11:0</string>
<string>0:12:0</string>
<string>0:13:0</string>
</array>
<key>deleted</key>
<dict/>
<key>entityNames</key>
<array>
<string>Recipe</string>
<string>Category</string>
</array>
<key>inserted</key>
<dict>
<key>0</key>
<dict>
<key>categories</key>
<array>
<string>1</string>
</array>
<key>ctime</key>
<integer>0</integer>
<key>name</key>
<string>Aaa Rx D</string>
<key>photos</key>
<array/>
<key>ptime</key>
<integer>0</integer>
<key>recipeID</key>
<integer>0</integer>
</dict>
</dict>
<key>kvStr</key>
<string>mobile.F0F5BE6D-59A3-5D63-A0B2-4767EFECC603:1</string>
<key>modelVersionHash</key>
<string>9FRYa_LmmBTIAw8875pOlLyYmr5vrP1Hwi~lgvsHL1k=</string>
<key>peerIDs</key>
<array>
<string>mobile.F0F5BE6D-59A3-5D63-A0B2-4767EFECC603</string>
</array>
<key>peerStates</key>
<dict/>
<key>primaryKeys</key>
<array>
<string>p89</string>
<string>p6</string>
<string>p43</string>
<string>p4</string>
<string>p41</string>
<string>p5</string>
<string>p52</string>
<string>p58</string>
<string>p68</string>
<string>p13</string>
<string>p79</string>
<string>p28</string>
<string>p17</string>
<string>p25</string>
</array>
<key>transactionDate</key>
<real>1343676810.7298651</real>
<key>transactionNumber</key>
<integer>1</integer>
<key>updated</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>Desserts</string>
<key>recipes</key>
<array>
<string>2</string>
<string>3</string>
<string>4</string>
<string>5</string>
<string>6</string>
<string>7</string>
<string>8</string>
<string>9</string>
<string>0</string>
<string>10</string>
<string>11</string>
<string>12</string>
<string>13</string>
</array>
<key>sortIndex</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
- 唯一 MOC 保存后的消息:
2012-07-31 12:38:44.632 iHungryMePlus[688:1b03] +PFUbiquityBaseline metadataFromCurrentBaselineForStoreWithName:modelVersionHash:andUbiquityRootLocation:withError:: CoreData: Ubiquity: 没有从元数据 url:file://localhost/private/ 获取基线元数据var/mobile/Library/Mobile%20Documents/3PAT8SS34X~com~DrummingGrouse~iHMP/.baseline/current.nosync/com.DrummingGrouse.iHMP.mainstore/9FRYa_LmmBTIAw8875pOlLyYmr5vrP1Hwi~lgvsHL1k=/baseline.meta
错误:(空)
2012-07-31 12:38:44.818 iHungryMePlus[688:1b03] +PFUbiquityBaseline metadataFromCurrentBaselineForStoreWithName:modelVersionHash:andUbiquityRootLocation:withError:: CoreData: Ubiquity: 没有从元数据 url:file://localhost/private/ 获取基线元数据var/mobile/Library/Mobile%20Documents/3PAT8SS34X~com~DrummingGrouse~iHMP/.baseline/current.nosync/com.DrummingGrouse.iHMP.mainstore/9FRYa_LmmBTIAw8875pOlLyYmr5vrP1Hwi~lgvsHL1k=/baseline.meta
错误:(空)
2012-07-31 12:38:44.824 iHungryMePlus[688:1b03]-PFUbiquityBaselineRecoveryOperation 主要:CoreData:Ubiquity:localPeerID:mobile.F0F5BE6D-59A3-5D63-A0B2-4767EFECC603,商店名称:com.DrummingGrouse.iHMP.mainstore,modelVersion 9FRYa_LmmBTIAw8875pOlLyYmr5vrP1Hwi~lgvsHL1k=
ubiquityRootLocation: <PFUbiquityLocation: 0x162e10>: /private/var/mobile/Library/Mobile Documents/3PAT8SS34X~com~DrummingGrouse~iHMP
当前基线元数据为零,(空)