Zha*_*ang 42 core-data ios icloud xcode6 ios8
有没有人在Xcode 6和iOS 8上获得iCloud核心数据同步设置?(希望这不是一个重复的帖子)
iCloud核心数据存储选项在哪里?
我记得Core Data有一个名为Core Data storage的额外存储选项,但现在在Xcode 6中,当我在Xcode 6中启用iCloud切换时,它似乎只显示键值和文档存储.
到目前为止,我不知道我是否正确设置了Core Data iCloud.
Xcode似乎已在iOS Developer Portal中设置了iCloud容器:
iCloud.com.xxxxxx.xxxxxxxx (note: I've replaced the actual strings with xxxx here)
Run Code Online (Sandbox Code Playgroud)
我的Xcode 6 iCloud"服务"列表显示旁边没有刻度:
我们现在应该使用哪一个,因为它没有将"核心数据"列为存储选项?
在"服务"正下方的"容器"中,它显示以下灰色选项:
我无法选择任何选项,它似乎迫使我"使用默认容器".
最后,Xcode似乎显示为:
因此,通过Xcode自己的自动化流程,它为我设置了一切.
好的,所以我四处阅读并注意到这里写的iCloud堆栈:
https://github.com/mluisbrown/iCloudCoreDataStack
我已经采取了必要的代码并尝试适应我的核心数据管理器单例:
+ (id)sharedModel;
+ (ALAssetsLibrary *)sharedLibrary;
@property (nonatomic, readonly) NSManagedObjectContext *mainContext;
@property (nonatomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
- (NSString *)modelName;
- (NSString *)pathToModel;
- (NSString *)storeFilename;
- (NSString *)pathToLocalStore;
#pragma mark - Entity Fetching Methods -
-(NSArray *)fetchEntityOfType:(NSString *)entityType UsingPredicated:(NSPredicate *)predicate sortBy:(NSString *)sortKey ascendingOrder:(BOOL)ascendingOrder;
Run Code Online (Sandbox Code Playgroud)
@property (nonatomic, strong) NSManagedObjectModel *managedObjectModel;
- (NSString *)documentsDirectory;
@end
@implementation MLSAlbumsDataModel
@synthesize managedObjectModel = _managedObjectModel;
@synthesize storeCoordinator = _storeCoordinator;
@synthesize mainContext = _mainContext;
+ (id)sharedModel {
static MLSAlbumsDataModel *__instance = nil;
if (__instance == nil) {
__instance = [[MLSAlbumsDataModel alloc] init];
}
return __instance;
}
+ (ALAssetsLibrary *)sharedLibrary {
static ALAssetsLibrary *__instance = nil;
if (__instance == nil) {
__instance = [[ALAssetsLibrary alloc] init];
}
return __instance;
}
- (NSString *)modelName {
return @"Albums";
}
- (NSString *)pathToModel {
return [[NSBundle mainBundle] pathForResource:[self modelName] ofType:@"momd"];
}
- (NSString *)storeFilename {
return [[self modelName] stringByAppendingPathExtension:@"sqlite"];
}
- (NSString *)pathToLocalStore {
return [[self documentsDirectory] stringByAppendingPathComponent:[self storeFilename]];
}
- (NSString *)documentsDirectory {
NSString *documentsDirectory = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
- (NSManagedObjectContext *)mainContext {
if(_mainContext == nil) {
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
// setup persistent store coordinator
DLog(@"SQLITE STORE PATH: %@", [self pathToLocalStore]);
NSURL *storeURL = [NSURL fileURLWithPath:[self pathToLocalStore]];
//_mainContext.persistentStoreCoordinator = [self storeCoordinator];
_mainContext.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
__weak NSPersistentStoreCoordinator *psc = self.mainContext.persistentStoreCoordinator;
// iCloud notification subscriptions
NSNotificationCenter *dc = [NSNotificationCenter defaultCenter];
[dc addObserver:self
selector:@selector(storesWillChange:)
name:NSPersistentStoreCoordinatorStoresWillChangeNotification
object:psc];
[dc addObserver:self
selector:@selector(storesDidChange:)
name:NSPersistentStoreCoordinatorStoresDidChangeNotification
object:psc];
[dc addObserver:self
selector:@selector(persistentStoreDidImportUbiquitousContentChanges:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:psc];
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.mainContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:@{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" }
error:&error];
if (error) {
NSLog(@"error: %@", error);
}
_storeCoordinator = self.mainContext.persistentStoreCoordinator;
}
return _mainContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if(_managedObjectModel == nil) {
NSURL *storeURL = [NSURL fileURLWithPath:[self pathToModel]];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:storeURL];
}
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)storeCoordinator {
if (_storeCoordinator == nil) {
// -----------------------------------------------------------------------------------------------------------------------------
// Code moved to managed object context code above
// -----------------------------------------------------------------------------------------------------------------------------
/*
DLog(@"SQLITE STORE PATH: %@", [self pathToLocalStore]);
NSURL *storeURL = [NSURL fileURLWithPath:[self pathToLocalStore]];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:error forKey:NSUnderlyingErrorKey];
NSString *reason = @"Could not create persistent store";
NSException *exc = [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:userInfo];
@throw exc;
}
_storeCoordinator = psc;
*/
}
return _storeCoordinator;
}
#pragma mark - iCloud Related Methods -
// Subscribe to NSPersistentStoreDidImportUbiquitousContentChangesNotification
- (void)persistentStoreDidImportUbiquitousContentChanges:(NSNotification*)note
{
NSLog(@"%s", __PRETTY_FUNCTION__);
NSLog(@"%@", note.userInfo.description);
NSManagedObjectContext *moc = self.mainContext;
[moc performBlock:^{
[moc mergeChangesFromContextDidSaveNotification:note];
DLog(@"NSPersistentStoreDidImportUbiquitousContentChangesNotification executed");
/*
// 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 {
NSManagedObjectContext *moc = self.mainContext;
[moc performBlockAndWait:^{
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.
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifCoreDataStoreWillChange" object:nil];
DLog(@"storeWillChange notification fire");
}
// Subscribe to NSPersistentStoreCoordinatorStoresDidChangeNotification
- (void)storesDidChange:(NSNotification *)note
{
// here is when you can refresh your UI and
// load new data from the new store
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifCoreDataStoreDidChange" object:nil];
DLog(@"storeDidChange notification fire");
}
#pragma mark - Entity Fetching Methods -
-(NSArray *)fetchEntityOfType:(NSString *)entityType UsingPredicated:(NSPredicate *)predicate sortBy:(NSString *)sortKey ascendingOrder:(BOOL)ascendingOrder
{
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:entityType inManagedObjectContext:[[MLSAlbumsDataModel sharedModel] mainContext]];
NSSortDescriptor *sortDescriptor = nil;
if(sortKey)
{
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascendingOrder];
}
else
{
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"updatedAt" ascending:ascendingOrder];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entityDescription;
if(predicate)
{
request.predicate = predicate;
}
request.sortDescriptors = @[sortDescriptor];
NSError *error = nil;
NSArray *results = [[[MLSAlbumsDataModel sharedModel] mainContext] executeFetchRequest:request error:&error];
if(results == nil)
{
DLog(@"Error getting entity of type '%@' using predicate '%@', sortKey '%@' ascendingOrder %d", entityType, predicate, sortKey, ascendingOrder);
}
return results;
}
Run Code Online (Sandbox Code Playgroud)
我试图在iPad模拟器上运行应用程序(我相信它是iOS 8模拟器)并在运行iOS 7.x的iPad设备上运行
我在模拟器上创建了一个用户输入名称的相册,但我没有看到iPad设备显示新创建的相册.我也试过逆转角色,iPad设备创建,iOS模拟器也没有结果.
我确实看到了我的日志消息:
storeDidChange notification fire
SQLITE STORE PATH: /Users/xxxxxxx/Library/Developer/CoreSimulator/Devices/3DC17576-92E9-4EAF-B77A-41340AE28F92/data/Containers/Data/Application/E51085CE-3772-4DF1-A503-1C243497091A/Documents/Albums.sqlite
Run Code Online (Sandbox Code Playgroud)
如果我在模拟器中最小化应用程序并再次打开它(不按Xcode中的"停止"按钮),我会看到以下消息:
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](808): CoreData: Ubiquity: nobody~sim301AE3E8-16B2-5A08-917D-7B55D1879BE4:iCloudStore
Using local storage: 1
Run Code Online (Sandbox Code Playgroud)
我读到"使用本地存储:0"是理想的应该是什么?并且1表示本地设备数据存储而不是iCloud数据存储.
当我创建一个专辑,保存它,停止模拟器,然后再次启动应用程序,我的专辑消失,但在我创建一个新专辑后,所有以前的专辑再次神奇地重新出现.这有点奇怪.如果我不使用iCloud并将我的代码恢复到之前的设置,我可以创建并查看我的相册,无论我是否最小化我的应用程序,或重新启动应用程序,但是我没有iCloud同步,我需要.
我在任何地方都犯过任何错误吗?
很抱歉这篇文章很长,但有没有人让iCloud为iOS 8和Xcode 6工作?
我真的可以使用一些帮助.
1)iOS 8是否需要使用此容器标识符?(Xcode 6为我生成的):
com.apple.developer.icloud-container-identifiers
Run Code Online (Sandbox Code Playgroud)
这不是iOS 7的样子吗?iOS 7更像是:
com.apple.developer.ubiquity-container-identifiers
Run Code Online (Sandbox Code Playgroud)
2)在运行之前我需要一个iCloud Drive帐户吗?
超级迷茫@ _ @
Zha*_*ang 21
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设备和运行OS X 10 Yosemite的Mac之间共享文档.
所以,我决定咬紧牙关并将我的iCloud帐户升级到iCloud驱动器(免费升级).
升级到iCloud驱动器后,通过一些Xcode 6更改重新运行我的应用程序,它现在正在运行.
需要注意的一些重要事项:
由于上述原因,我改为使用具有此模式的Ubiquity容器:
iCloud中.$(CFBundleIdentifier)
所以类似于:
iCloud.com.xxxxxxxx.iCloudCoreDataDemo
Run Code Online (Sandbox Code Playgroud)
其中"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;
}
Run Code Online (Sandbox Code Playgroud)
如果你看到"欢呼?" 那么没关系,您还应该在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
Run Code Online (Sandbox Code Playgroud)
请注意两个重要的行:
Using local storage: 1
Run Code Online (Sandbox Code Playgroud)
后来成为:
Using local storage: 0
Run Code Online (Sandbox Code Playgroud)
本地存储1表示它当前正在使用本地存储,而本地存储0表示它已将数据移动到iCloud存储.
我希望这对其他人都有好处.
好的,所以我刚刚发现了一些东西,并设法让它只适用于iOS 7.我仍然没有想到如何在iOS 8中做到这一点,但我注意到一些重要的事情.
在运行iOS 8.0.2的iPhone 5上,iCloud设置菜单中没有" 文档和数据 "选项.
但是,在运行iOS 7的iPad上,我看到了"文档和数据"选项.
也许这就是它在iOS 8上不起作用的原因,我们不再拥有文档和数据存储?
无论如何,这是我发现的iOS 7唯一解决方案.
我在这里找到了这个页面
其中一条线说:
果然,我进入了我的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
Run Code Online (Sandbox Code Playgroud)
@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"];
}
Run Code Online (Sandbox Code Playgroud)
#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
Run Code Online (Sandbox Code Playgroud)
#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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16764 次 |
| 最近记录: |