ios - 将核心数据与 iCloud 同步 - 不包括实体
<p><p>我正在将 iCloud 添加到现有应用程序。同步工作正常,但是我需要排除一些实体,或者在我的一些核心数据被复制时想出一个解决方法。 </p>
<p>例如:</p>
<p><code>CertificateColour</code> 被发送到表格 View ,现在每行显示两次。</p>
<p><code>CertificateType</code> 在操作表中显示四个选项,现在有 8 行,每行都被复制一次。</p>
<p>我正在使用 <a href="https://github.com/mluisbrown/iCloudCoreDataStack" rel="noreferrer noopener nofollow">https://github.com/mluisbrown/iCloudCoreDataStack</a>用于我的核心数据同步。 </p>
<p>我查看了 <a href="https://stackoverflow.com/questions/13448793/core-data-icloud-exclude-certain-attributes-from-sync" rel="noreferrer noopener nofollow">Core data + iCloud: exclude certain attributes from sync?</a>这暗示了几件事:<br/>
1. 创建一个单独的本地和云存储,听起来……很有希望,但不确定这是我第一次尝试使用 iCloud 和 Core 数据。<br/>
2. 第二个建议是同步到包含唯一设备标识符的实体,但这已被弃用,并且再次不确定核心数据的流程</p>
<p>AppDelegate.h</p>
<pre><code>#import <UIKit/UIKit.h>
#import <sqlite3.h>
#import "PersistentStack.h"
@interface ICAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navigationController;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
</code></pre>
<p>Appdelegate.m</p>
<pre><code>@interface ICAppDelegate () <DBSessionDelegate, DBNetworkRequestDelegate>
//iCloud
@property (nonatomic, strong) PersistentStack* persistentStack;
@property (nonatomic, strong) NSManagedObjectContext* managedObjectContext;
@end
@implementation ICAppDelegate
@synthesize window = _window;
@synthesize navigationController = _navigationController;
@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//iCloud
self.persistentStack = [ initWithStoreURL:self.storeURL modelURL:self.modelURL];
self.managedObjectContext = self.persistentStack.managedObjectContext;
BOOL populateData = NO;
BOOL copyDb = YES;
// Copy DB to documents directory
if (copyDb == YES) {
NSString *srcPath = [ pathForResource:@"myApp" ofType:@"sqlite"];
NSString *destPath = [ stringByAppendingPathComponent:@"myApp.sqlite"];
if (![ fileExistsAtPath:srcPath]) {
DebugLog(@"Source file doesn't exist");
}
if (![ fileExistsAtPath:destPath]) {
DebugLog(@"Copying DB to documents directory");
NSError *error = nil;
[ copyItemAtPath:srcPath toPath:destPath error:&error];
if (error != nil) {
DebugLog(@"Copy failed %@", );
}
}
}
/////*****ALL OF THIS IS DUPLICATED AND NEEDS EXCLUDING FROM ICLOUD BACK UP****////////////
if (populateData) {
DebugLog(@"Populating database");
NSManagedObjectContext *context = ;
Subscription *subscription = (Subscription *);
subscription.subscribed = @NO;
CertificateColour *red = (CertificateColour *);
red.name = @"Red";
red.redComponent = @1.0f;
red.greenComponent = @0.0f;
red.blueComponent = @0.0f;
CertificateColour *purple = (CertificateColour *);
purple.name = @"Purple";
purple.redComponent = @0.4f;
purple.greenComponent = @0.0f;
purple.blueComponent = @0.6f;
CertificateColour *green = (CertificateColour *);
green.name = @"Green";
green.redComponent = @0.0f;
green.greenComponent = @0.6f;
green.blueComponent = @0.2f;
CertificateColour *blue = (CertificateColour *);
blue.name = @"Blue";
blue.redComponent = @0.0f;
blue.greenComponent = @0.2f;
blue.blueComponent = @1.0f;
ICCertificateTypeManager *ctm = ;
CertificateType *type = ;
type.title = @"Works";
type.identifier = @(Works);
type = ;
type.title = @"Type1";
type.identifier = @(Type1);
type = ;
type.title = @"Type2";
type.identifier = @(Type2);
type = ;
type.title = @"Type4";
type.identifier = @(Type3);
;
}
if ([ isLoggedIn])
{
DebugLog(@"User is logged in ");
}
////////////////////////////////////////////////////////////
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
LogCmd();
if ([ handleOpenURL:url]) {
if ([ isLinked]) {
DebugLog(@"handling url");
}
return YES;
}
return NO;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
;
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
;
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ( && !) {
NSLog(@"Unresolved error %@, %@", error, );
abort();
}
}
}
#pragma mark - DBSessionDelegate
- (void)sessionDidReceiveAuthorizationFailure:(DBSession*)session userId:(NSString *)userId
{
LogCmd();
}
#pragma mark - DBNetworkRequestDelegate
static int outstandingRequests;
- (void)networkRequestStarted {
outstandingRequests++;
if (outstandingRequests == 1) {
[ setNetworkActivityIndicatorVisible:YES];
}
}
- (void)networkRequestStopped {
outstandingRequests--;
if (outstandingRequests == 0) {
[ setNetworkActivityIndicatorVisible:NO];
}
}
#pragma mark - Core Data stack
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = ;
if (coordinator != nil) {
__managedObjectContext = [ init];
;
}
return __managedObjectContext;
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [ URLForResource:@"myApp" withExtension:@"momd"];
__managedObjectModel = [ initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeURL = [ URLByAppendingPathComponent:@"myApp.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [ initWithManagedObjectModel:];
if (!) {
NSLog(@"Unresolved error %@, %@", error, );
abort();
}
return __persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[ URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
#pragma mark - iCloud store
- (NSURL*)storeURL
{
NSURL* documentsDirectory = [ URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
return ;
}
- (NSURL*)modelURL
{
return [ URLForResource:@"myApp" withExtension:@"momd"];
}
@end
</code></pre></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>使用多个持久存储确实是从 iCloud 中排除特定实体类型的唯一选择。为此,您可以在同一个持久存储协调器上多次调用 <code>addPersistentStoreWithType</code> ,但使用不同的持久存储文件(它被称为协调器,因为它可以在多个持久存储之间进行协调)。对其中一个商店使用 iCloud 选项,但对另一个不使用。</p>
<p>您可以使用具有不同实体的两个单独的托管对象模型,也可以使用具有不同配置选项的单个模型。任何一个都有效。</p>
<p>您可能会遇到的问题是<strong>您无法在不同的持久存储文件中的实例之间创建关系</strong>。 (从技术上讲,您可以创建它们,但无法保存它们,这在大多数情况下使它们无用)。您的 <code>CertificateType</code> 实体听起来像是与其他实例有关系,但这不适用于多个商店。</p>
<p>您可以做的是同步每个对象,但添加代码以检测重复项并处理它们。在 WWDC 2012 的“将 iCloud 与核心数据一起使用” session 中,Apple 的“SharedCoreData”示例应用程序中有一个很好的例子,但我现在无法在网上找到该副本。你会做类似的事情</p>
<ol>
<li>等待 <code>NSPersistentStoreDidImportUbiquitousContentChangesNotification</code></li>
<li>收到通知后,查看通知的 <code>userInfo</code> 以查看是否包含任何 <code>CertificateType</code> 对象。</li>
<li>如果是这样,请对该实体进行提取以查找和匹配重复项</li>
<li>以任何对您的应用有意义的方式清理这些重复项。</li>
</ol>
<p><strong>更新:</strong>我忘了我做过 <a href="http://www.atomicbird.com/blog/icloud-complications-part-2" rel="noreferrer noopener nofollow">blog post which covers this in more detail</a> .我还找到了 <a href="https://developer.apple.com/devcenter/download.action?path=/wwdc_2012/wwdc_2012_sample_code/wwdc_2012_session_code.dmg" rel="noreferrer noopener nofollow">WWDC 2012 sample code bundle</a> 的链接。 (链接需要当前的开发者帐户),其中包括 SharedCoreData。该演示中的很多内容都已过时,但重复删除代码与以往一样有效。</p></p>
<p style="font-size: 20px;">关于ios - 将核心数据与 iCloud 同步 - 不包括实体,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/22834654/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/22834654/
</a>
</p>
页:
[1]