OK ...然后....大声笑。我想我解决了。
新发现。浏览此页面后:
http://www.tuaw.com/2014/09/17/psa-do-not-upgrade-to-icloud-drive-during-ios-8-installation/
它说:
iCloud Drive是Apple新推出的改进的iCloud同步和文件 存储功能,允许您在iOS 8之间共享文档 设备和你的Mac运行OS X 10约塞米蒂。
所以,我决定咬紧牙关并将我的iCloud帐户升级到iCloud驱动器(免费升级)。
升级到iCloud驱动器后,通过一些Xcode 6更改重新运行我的应用程序,它现在正在运行。
需要注意的一些重要事项:
由于上述原因,我改为使用具有此模式的Ubiquity容器:
iCloud中。$(CFBundleIdentifier)
所以类似于:
iCloud.com.xxxxxxxx.iCloudCoreDataDemo
其中“xxxxxxxx”是我的公司名称标识符。
我通过登录我的iOS开发人员中心制作了上面的iCloud容器,也许您可以按Xcode 6中的“+”符号并在那里输入一个,Xcode应该自动为您设置一切。
我用来测试一段代码,看看它是否正常工作:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.persistentStack = [[PersistentStack alloc] initWithStoreURL:self.storeURL modelURL:self.modelURL]; self.managedObjectContext = self.persistentStack.managedObjectContext; NSURL *containerURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"iCloud.com.xxxxxxxxxx.iCloudCoreDataDemo"]; if(containerURL == nil) { NSLog(@"containerURL == nil"); } else { NSLog(@"hurray?"); } return YES; }
如果你看到“欢呼?”那么没关系,您还应该在Xcode控制台输出中看到这种文本模式:
2014-10-07 17:37:23.196 iCloudCoreDataDemo[8104:130250] documentsDirectory = file:///Users/xxxxxxxx/Library/Developer/CoreSimulator/Devices/9FAFE881-13CA-4608-8BE6-728C793FAFFB/data/Containers/Data/Application/BC6CA07D-605A-4927-94AF-E9E21E204D2B/Documents/ 2014-10-07 17:37:23.386 iCloudCoreDataDemo[8104:130250] storeDidChange 2014-10-07 17:37:23.390 iCloudCoreDataDemo[8104:130250] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](808): CoreData: Ubiquity: nobody~sim301AE3E8-16B2-5A08-917D-7B55D1879BE4:iCloudStore Using local storage: 1 2014-10-07 17:37:23.402 iCloudCoreDataDemo[8104:130250] hurray? 2014-10-07 17:37:33.909 iCloudCoreDataDemo[8104:130250] storeWillChange 2014-10-07 17:37:33.933 iCloudCoreDataDemo[8104:130250] storeDidChange 2014-10-07 17:37:33.933 iCloudCoreDataDemo[8104:130330] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](808): CoreData: Ubiquity: nobody~sim301AE3E8-16B2-5A08-917D-7B55D1879BE4:iCloudStore Using local storage: 0
请注意两个重要的行:
Using local storage: 1
后来成为:
Using local storage: 0
本地存储1表示它当前正在使用本地存储,而本地存储0表示它已将数据移动到iCloud存储。
我希望这对其他人都有好处。
好的,所以我刚刚发现了一些东西,并设法让它发挥作用 的 IOS 7 强> 只要。我仍然没有想到如何在iOS 8中做到这一点,但我注意到一些重要的事情。
在运行iOS 8.0.2的iPhone 5上,我没有“ 的 文件&数据 强> “iCloud设置菜单中的选项了。
但是,在运行iOS 7的iPad上,我看到了“文档和数据”选项。
也许这就是它在iOS 8上不起作用的原因,我们不再拥有Document&数据存储 ?
无论如何,这是我发现的iOS 7唯一解决方案。
我在这里找到了这个页面
https://developer.apple.com/library/ios/documentation/General/Conceptual/iCloudDesignGuide/Chapters/iCloudFundametals.html
其中一条线说:
果然,我进入了我的Xcode 6项目文件并勾选了“iCloud Documents”选项。这个没有灰色的单选按钮,但我仍然把它留在“使用默认容器”。
我学到的一件事是我需要在appDelegate中初始化我的PersistentStack。以前,我尝试在+(id)sharedInstance方法中初始化持久性堆栈,但它导致iCloud仅在第一次同步,因此在初始加载和同步之后,添加新记录之后不会同步。
我重写了一个基本应用程序并稍微修改了持久堆栈:
#import <UIKit/UIKit.h> #import "PersistentStack.h" @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (nonatomic, strong) NSManagedObjectContext* managedObjectContext; @property (nonatomic, strong) PersistentStack* persistentStack; @end
@interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.persistentStack = [[PersistentStack alloc] initWithStoreURL:self.storeURL modelURL:self.modelURL]; self.managedObjectContext = self.persistentStack.managedObjectContext; return YES; } ... - (NSURL*)storeURL { NSURL* documentsDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL]; return [documentsDirectory URLByAppendingPathComponent:@"MyApp.sqlite"]; } - (NSURL*)modelURL { return [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"]; }
#import <Foundation/Foundation.h> #import <CoreData/CoreData.h> #import "Book.h" #import <UIKit/UIKit.h> @interface PersistentStack : NSObject +(id)sharedInstance; - (id)initWithStoreURL:(NSURL *)storeURL modelURL:(NSURL *)modelURL; @property (nonatomic,strong,readonly) NSManagedObjectContext *managedObjectContext; #pragma mark - Regular Methods - -(Book *)insertNewBookWithDate:(NSDate *)newDate; -(void)deleteBook:(Book *)book; -(NSArray *)fetchEntityOfType:(NSString *)entityType withPredicate:(NSPredicate *)predicate andSortKey:(NSString *)sortKey; @end
#import "PersistentStack.h" #import "AppDelegate.h" @interface PersistentStack () @property (nonatomic,strong,readwrite) NSManagedObjectContext* managedObjectContext; @property (nonatomic,strong) NSURL* modelURL; @property (nonatomic,strong) NSURL* storeURL; @end @implementation PersistentStack +(id)sharedInstance { static PersistentStack *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; sharedInstance = appDelegate.persistentStack; }); return sharedInstance; } - (id)initWithStoreURL:(NSURL*)storeURL modelURL:(NSURL*)modelURL { self = [super init]; if (self) { self.storeURL = storeURL; self.modelURL = modelURL; [self setupManagedObjectContext]; } return self; } - (void)setupManagedObjectContext { self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; self.managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy; self.managedObjectContext.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel]; //__weak NSPersistentStoreCoordinator *psc = self.managedObjectContext.persistentStoreCoordinator; // iCloud notification subscriptions NSNotificationCenter *dc = [NSNotificationCenter defaultCenter]; [dc addObserver:self selector:@selector(storesWillChange:) name:NSPersistentStoreCoordinatorStoresWillChangeNotification object:self.managedObjectContext.persistentStoreCoordinator]; [dc addObserver:self selector:@selector(storesDidChange:) name:NSPersistentStoreCoordinatorStoresDidChangeNotification object:self.managedObjectContext.persistentStoreCoordinator]; [dc addObserver:self selector:@selector(persistentStoreDidImportUbiquitousContentChanges:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:self.managedObjectContext.persistentStoreCoordinator]; NSError* error; // the only difference in this call that makes the store an iCloud enabled store // is the NSPersistentStoreUbiquitousContentNameKey in options. I use "iCloudStore" // but you can use what you like. For a non-iCloud enabled store, I pass "nil" for options. // Note that the store URL is the same regardless of whether you're using iCloud or not. // If you create a non-iCloud enabled store, it will be created in the App's Documents directory. // An iCloud enabled store will be created below a directory called CoreDataUbiquitySupport // in your App's Documents directory [self.managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:@{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" } error:&error]; if (error) { NSLog(@"error: %@", error); } } - (NSManagedObjectModel*)managedObjectModel { return [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL]; } // Subscribe to NSPersistentStoreDidImportUbiquitousContentChangesNotification - (void)persistentStoreDidImportUbiquitousContentChanges:(NSNotification*)note { NSLog(@"%s", __PRETTY_FUNCTION__); NSLog(@"%@", note.userInfo.description); NSManagedObjectContext *moc = self.managedObjectContext; [moc performBlock:^{ [moc mergeChangesFromContextDidSaveNotification:note]; [[NSNotificationCenter defaultCenter] postNotificationName:@"notifiCloudStoreDidChange" object:nil]; /* // you may want to post a notification here so that which ever part of your app // needs to can react appropriately to what was merged. // An exmaple of how to iterate over what was merged follows, although I wouldn't // recommend doing it here. Better handle it in a delegate or use notifications. // Note that the notification contains NSManagedObjectIDs // and not NSManagedObjects. NSDictionary *changes = note.userInfo; NSMutableSet *allChanges = [NSMutableSet new]; [allChanges unionSet:changes[NSInsertedObjectsKey]]; [allChanges unionSet:changes[NSUpdatedObjectsKey]]; [allChanges unionSet:changes[NSDeletedObjectsKey]]; for (NSManagedObjectID *objID in allChanges) { // do whatever you need to with the NSManagedObjectID // you can retrieve the object from with [moc objectWithID:objID] } */ }]; } // Subscribe to NSPersistentStoreCoordinatorStoresWillChangeNotification // most likely to be called if the user enables / disables iCloud // (either globally, or just for your app) or if the user changes // iCloud accounts. - (void)storesWillChange:(NSNotification *)note { NSLog(@"storeWillChange"); NSManagedObjectContext *moc = self.managedObjectContext; //[moc performBlockAndWait:^{ [moc performBlock:^{ NSError *error = nil; if ([moc hasChanges]) { [moc save:&error]; } [moc reset]; }]; // now reset your UI to be prepared for a totally different // set of data (eg, popToRootViewControllerAnimated:) // but don't load any new data yet. } // Subscribe to NSPersistentStoreCoordinatorStoresDidChangeNotification - (void)storesDidChange:(NSNotification *)note { // here is when you can refresh your UI and // load new data from the new store NSLog(@"storeDidChange"); [[NSNotificationCenter defaultCenter] postNotificationName:@"notifiCloudStoreDidChange" object:nil]; } #pragma mark - Regular Methods - -(Book *)insertNewBookWithDate:(NSDate *)newDate { Book *newBook = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:self.managedObjectContext]; newBook.bookName = @"Book"; newBook.publishDate = newDate; [self.managedObjectContext save:nil]; return newBook; } -(void)deleteBook:(Book *)book { [self.managedObjectContext deleteObject:book]; [self.managedObjectContext save:nil]; } -(NSArray *)fetchEntityOfType:(NSString *)entityType withPredicate:(NSPredicate *)predicate andSortKey:(NSString *)sortKey { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:entityType inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Specify criteria for filtering which objects to fetch [fetchRequest setPredicate:predicate]; // Specify how the fetched objects should be sorted NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:YES]; [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]]; NSError *error = nil; NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; if (fetchedObjects == nil) { NSLog(@"couldn't fetch entity of type '%@', error: %@", entityType, error.localizedDescription); } return fetchedObjects; } @end
我遇到了类似的问题。我会看见:
但没有其他输出。如果我重建了应用程序,我会得到类似的东西:
Error adding store for new account:
有一点需要注意的是,如果我第一次按下iPhone上的“主页按钮”,然后重新打开应用程序,我只能获得此输出。
需要注意的一个关键点是 的 我没有选择任何服务 强> 。为了解决这个问题,我选择了“iCloud Documents”。
您可能需要在重建之前删除该应用程序。