菜鸟教程小白 发表于 2022-12-13 07:26:07

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 &lt;UIKit/UIKit.h&gt;
#import &lt;sqlite3.h&gt;
#import &#34;PersistentStack.h&#34;

@interface ICAppDelegate : UIResponder &lt;UIApplicationDelegate&gt;

@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 () &lt;DBSessionDelegate, DBNetworkRequestDelegate&gt;

//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:@&#34;myApp&#34; ofType:@&#34;sqlite&#34;];
      NSString *destPath = [ stringByAppendingPathComponent:@&#34;myApp.sqlite&#34;];

      if (![ fileExistsAtPath:srcPath]) {
            DebugLog(@&#34;Source file doesn&#39;t exist&#34;);
      }
      if (![ fileExistsAtPath:destPath]) {
            DebugLog(@&#34;Copying DB to documents directory&#34;);
            NSError *error = nil;
            [ copyItemAtPath:srcPath toPath:destPath error:&amp;error];
            if (error != nil) {
                DebugLog(@&#34;Copy failed %@&#34;, );
            }
      }
    }


    /////*****ALL OF THIS IS DUPLICATED AND NEEDS EXCLUDING FROM ICLOUD BACK UP****////////////

      if (populateData) {

      DebugLog(@&#34;Populating database&#34;);
      NSManagedObjectContext *context = ;

      Subscription *subscription = (Subscription *);
      subscription.subscribed = @NO;

      CertificateColour *red = (CertificateColour *);
      red.name = @&#34;Red&#34;;
      red.redComponent = @1.0f;
      red.greenComponent = @0.0f;
      red.blueComponent = @0.0f;

      CertificateColour *purple = (CertificateColour *);
      purple.name = @&#34;Purple&#34;;
      purple.redComponent = @0.4f;
      purple.greenComponent = @0.0f;
      purple.blueComponent = @0.6f;

      CertificateColour *green = (CertificateColour *);
      green.name = @&#34;Green&#34;;
      green.redComponent = @0.0f;
      green.greenComponent = @0.6f;
      green.blueComponent = @0.2f;

      CertificateColour *blue = (CertificateColour *);
      blue.name = @&#34;Blue&#34;;
      blue.redComponent = @0.0f;
      blue.greenComponent = @0.2f;
      blue.blueComponent = @1.0f;


      ICCertificateTypeManager *ctm = ;

      CertificateType *type = ;
      type.title = @&#34;Works&#34;;
      type.identifier = @(Works);

      type = ;
      type.title = @&#34;Type1&#34;;
      type.identifier = @(Type1);

      type = ;
      type.title = @&#34;Type2&#34;;
      type.identifier = @(Type2);

      type = ;
      type.title = @&#34;Type4&#34;;
      type.identifier = @(Type3);

      ;
    }

       if ([ isLoggedIn])
    {
      DebugLog(@&#34;User is logged in &#34;);
    }
    ////////////////////////////////////////////////////////////


    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    LogCmd();
    if ([ handleOpenURL:url]) {
      if ([ isLinked]) {
            DebugLog(@&#34;handling url&#34;);
      }
      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 ( &amp;&amp; !) {


            NSLog(@&#34;Unresolved error %@, %@&#34;, 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&#39;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&#39;t already exist, it is created from the application&#39;s model.
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil) {
      return __managedObjectModel;
    }
    NSURL *modelURL = [ URLForResource:@&#34;myApp&#34; withExtension:@&#34;momd&#34;];
    __managedObjectModel = [ initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}

// Returns the persistent store coordinator for the application.
// If the coordinator doesn&#39;t already exist, it is created and the application&#39;s store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil) {
      return __persistentStoreCoordinator;
    }

    NSURL *storeURL = [ URLByAppendingPathComponent:@&#34;myApp.sqlite&#34;];

    NSError *error = nil;
    __persistentStoreCoordinator = [ initWithManagedObjectModel:];
    if (!) {





      NSLog(@&#34;Unresolved error %@, %@&#34;, error, );
      abort();
    }   

    return __persistentStoreCoordinator;
}

#pragma mark - Application&#39;s Documents directory

// Returns the URL to the application&#39;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:@&#34;myApp&#34; withExtension:@&#34;momd&#34;];
}


@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]
查看完整版本: ios - 将核心数据与 iCloud 同步 - 不包括实体