ICloud and CoreData

I am trying to use iCloud with my iOS app. I have an application running on separate devices, but when I added iCloud, nothing happened. I looked all over the internet and found only one example that I did not understand. My application is iOS 5.0 and uses basic data to store pages. Below is my application delegate and my presentation in which I show it. Sorry for the lack of knowledge when it comes to iPhone dev. Please help. http://goddess-gate.com/dc2/index.php/post/452

Thank you

If someone knows / has a full working iCloud + CoreData working draft, I believe that I can understand this. Right now, I just have code that I don’t even know how they are called ... If I have a complete project, I can go through it so that I can fully understand how it works.

The problem is that I don’t think that something is being called to update the view with data, and I don’t believe that it sends it to the cloud, but I don’t know what to call ...

PageFlipperAppDelegate.h

#import <UIKit/UIKit.h> #import "PageView.h" #import "SlideShowViewController.h" #import "PagesCollectionViewController.h" #import "UiWindowSubclass.h" @interface PageFlipperAppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (nonatomic, retain, readonly) PagesCollectionViewController *collectionViewController; - (void)saveContext; - (NSURL *)applicationDocumentsDirectory; @end 

PageFlipperAppDelegate.m

  #import "PageFlipperAppDelegate.h" @implementation PageFlipperAppDelegate @synthesize window; @synthesize managedObjectContext, managedObjectModel, persistentStoreCoordinator,collectionViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque]; [NSThread sleepForTimeInterval:2.75]; collectionViewController = [[PagesCollectionViewController alloc] initWithManagedObjectContext:[self managedObjectContext]]; [(UINavigationController *)[[self window] rootViewController] pushViewController:collectionViewController animated:NO]; [collectionViewController release]; [[self window] makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { //stopping timer since we're going to background // [(UiWindowSubclass *)self.window stopTimer]; } - (void)applicationDidBecomeActive:(UIApplication *)application { } - (void)applicationDidEnterBackground:(UIApplication *)application { [self saveContext]; } - (void)applicationWillEnterForeground:(UIApplication *)application { } - (void)applicationWillTerminate:(UIApplication *)application { [self saveContext]; } - (void)dealloc { [window release]; [managedObjectContext release]; [managedObjectModel release]; [persistentStoreCoordinator release]; [super dealloc]; } - (void)awakeFromNib { } - (void)saveContext { NSError *error = nil; if ([self managedObjectContext]) { if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } #pragma mark - Core Data stack - (NSManagedObjectContext *)managedObjectContext { if (managedObjectContext != nil) { return managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { //if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0")) { NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [moc performBlockAndWait:^{ [moc setPersistentStoreCoordinator: coordinator]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator]; }]; managedObjectContext = moc; } return managedObjectContext; } /** Returns the managed object model for the application. If the model doesn't already exist, it is created from the application model. */ - (NSManagedObjectModel *)managedObjectModel { if (!managedObjectModel) { NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"PageFlipper" withExtension:@"momd"]; managedObjectModel = [[NSManagedObjectModel alloc] 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 store added to it. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"PageFlipper.sqlite"]; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSPersistentStoreCoordinator* psc = persistentStoreCoordinator; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSFileManager *fileManager = [NSFileManager defaultManager]; // Migrate datamodel NSDictionary *options = nil; // this needs to match the entitlements and provisioning profile NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:@"G88FQ4WK29.com.brandonsdesigngroup.3Doodles"]; NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"data"]; if ([coreDataCloudContent length] != 0) { // iCloud is available cloudURL = [NSURL fileURLWithPath:coreDataCloudContent]; options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, @"3Doodles.store", NSPersistentStoreUbiquitousContentNameKey, cloudURL, NSPersistentStoreUbiquitousContentURLKey, nil]; } else { // iCloud is not available options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; } NSError *error = nil; [psc lock]; if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } [psc unlock]; dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"asynchronously added persistent store!"); [[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil]; }); }); return persistentStoreCoordinator; } - (void)mergeiCloudChanges:(NSNotification*)note forContext:(NSManagedObjectContext*)moc { [moc mergeChangesFromContextDidSaveNotification:note]; NSNotification* refreshNotification = [NSNotification notificationWithName:@"RefreshAllViews" object:self userInfo:[note userInfo]]; [[NSNotificationCenter defaultCenter] postNotification:refreshNotification]; } - (void)mergeChangesFrom_iCloud:(NSNotification *)notification { NSManagedObjectContext* moc = [self managedObjectContext]; // this only works if you used NSMainQueueConcurrencyType // otherwise use a dispatch_async back to the main thread yourself [moc performBlock:^{ [self mergeiCloudChanges:notification forContext:moc]; }]; } #pragma mark - Application Documents directory /** Returns the URL to the application Documents directory. */ - (NSURL *)applicationDocumentsDirectory { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } @end 

viewController.h

  #import <Foundation/Foundation.h> #import "CollectionViewController.h" #import "SlideShowViewController.h" #import "PagesDataSource.h" #import "PageView.h" #import "PageViewController.h" #import "PrototypeView.h" #import "QuickStart.h" @interface PagesCollectionViewController : CollectionViewController<quickStartDismiss,NSFetchedResultsControllerDelegate> { PagesDataSource *dataSource; PageViewController *viewController; @private NSFetchedResultsController *fetchedResultsController__ ; @private NSManagedObjectContext *managedObjectContext__; } @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; - (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext; - (IBAction)add:(id)sender; -(void)setShadowAndColor; -(void)playSlideShow; @property (nonatomic, readwrite, assign) BOOL editMode; @end @interface PageView (CollectionViewItem) - (void)setRepresentedObject:(PVPage *)representedObject; - (PVPage *)representedObject; -(void)didHoldItem; -(void)duplicatePage; @end @interface PushController : UIViewController {} @end @interface toolBar : UIToolbar @end 

viewController.m

  #import "PagesCollectionViewController.h" #import "PageFlipperAppDelegate.h" @implementation toolBar - (void)drawRect:(CGRect)rect {} @end @implementation PagesCollectionViewController @synthesize editMode; @synthesize fetchedResultsController=__fetchedResultsController; @synthesize managedObjectContext=__managedObjectContext; -(void)viewWillAppear:(BOOL)animated{ if (![[NSUserDefaults standardUserDefaults] integerForKey:@"integerKey"]) { [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"integerKey"]; [[NSUserDefaults standardUserDefaults] synchronize]; QuickStart*stickieViewController = [[[QuickStart alloc]init]autorelease]; stickieViewController.delegate = self; stickieViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:stickieViewController animated:YES]; } [[self navigationController] setNavigationBarHidden:NO animated:NO]; [[self navigationController] setToolbarHidden:NO animated:NO]; [[[self navigationController] toolbar] setBarStyle:UIBarStyleBlackTranslucent]; [self setToolbarItems:[NSArray arrayWithObjects: [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease], [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(playSlideShow)]autorelease], [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease], nil]]; [(CollectionView*)[self view] setCanReloadData:YES]; [(CollectionView*)[self view]layoutSubviews]; } - (NSFetchedResultsController *)fetchedResultsController { if (__fetchedResultsController != nil) { return __fetchedResultsController; } /* Set up the fetched results controller. */ // Create the fetch request for the entity. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Edit the entity name as appropriate. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Page" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Set the batch size to a suitable number. [fetchRequest setFetchBatchSize:20]; // Edit the sort key as appropriate. NSSortDescriptor *sortDescriptorName = [[NSSortDescriptor alloc] initWithKey:@"<sort key>" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptorName, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; // Edit the section name key path and cache name if appropriate. // nil for section name key path means "no sections". NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"<section name key path>" cacheName:@"<cache name>"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; [aFetchedResultsController release]; [fetchRequest release]; [sortDescriptorName release]; [sortDescriptors release]; NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return __fetchedResultsController; } // because the app delegate now loads the NSPersistentStore into the NSPersistentStoreCoordinator asynchronously // we will see the NSManagedObjectContext set up before any persistent stores are registered // we will need to fetch again after the persistent store is loaded - (void)reloadFetchedResults:(NSNotification*)note { NSError *error = nil; if (![[self fetchedResultsController] performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } if (note) { [(CollectionView*)[self view] setCanReloadData:YES]; [(CollectionView*)[self view]layoutSubviews]; } } -(void) playSlideShow{ SlideShowViewController *slideShowViewController = [[[SlideShowViewController alloc] init]autorelease]; NSMutableArray *tempArrayOfImages = [[[NSMutableArray alloc] init]autorelease]; for (int i = 0; i < [[dataSource pages]count]; i++) { if ([[[dataSource pages] objectAtIndex:i] thumbnail] != nil) { [tempArrayOfImages addObject: [[[dataSource pages] objectAtIndex:i] thumbnail]]; } } [[self navigationController] pushViewController:slideShowViewController animated:YES]; [slideShowViewController setImagesInImageViewer:tempArrayOfImages]; } -(void)dismissQuickStart{ [self dismissModalViewControllerAnimated:YES]; } - (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext { if ((self = [super initWithNibName:@"CollectionView" bundle:nil])) { if (editMode == NO) { [self finishEditToolBars]; } [self setTitle:@"Doodles"]; viewController = [[PageViewController alloc] initWithManagedObjectContext:managedObjectContext]; dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:managedObjectContext]; CGSize itemViewMarginSize = CGSizeMake(25.0, 0.0); [(CollectionView *)[self view] setItemViewMarginSize:itemViewMarginSize]; PrototypeView *pro = [[[PrototypeView alloc] init] autorelease]; [(CollectionView *)[self view] setItemViewPrototype:pro]; [(CollectionView *)[self view] setFlowDirection:CVFlowDirectionVertical]; [(CollectionView *)[self view] setItemViewFrameSize:CGSizeMake(([(CollectionView *)[self view] bounds].size.width - 3*itemViewMarginSize.width)/3.4, ([(CollectionView *)[self view] bounds].size.height - 3*itemViewMarginSize.height)/3.6)]; [self setShadowAndColor]; } return self; } -(void)setShadowAndColor{ CollectionView *collectionView = (CollectionView *)[self view]; [collectionView setShadowColor:[UIColor blackColor]]; [collectionView setShadowRadius:6.0f]; [collectionView setShadowOpacity:0.5f]; } - (void)add:(id)sender { [dataSource add:sender]; CollectionView *collectionView = (CollectionView *)[self view]; // [collectionView reloadData]; // [collectionView scrollItemIndexToVisible:[self countOfItemsInCollectionView:collectionView]-1 animated:NO]; [collectionView.dataDelegate collectionView:collectionView didSelectItemAtIndex:[self countOfItemsInCollectionView:collectionView]-1]; //CollectionViewController *c; // [[c transitionToDetailViewController:[c collectionView:self detailViewControllerForItemAtIndex:(NSUInteger)[self countOfItemsInCollectionView:collectionView]-1] forItemView:[itemViews objectForKey:[NSString stringWithFormat:@"%u", [self countOfItemsInCollectionView:collectionView]-1]]]]; // [c transitionToDetailViewController:self forItemView:collectionView.itemViews; editMode = NO; //collectionView.canUpdateLayout = YES; collectionView.canReloadData = YES; [(CollectionView*)[self view]layoutSubviews]; } - (NSUInteger)countOfItemsInCollectionView:(CollectionView *)collectionView { return [[dataSource pages] count]; } - (id)collectionView:(CollectionView *)collectionView representedObjectAtIndex:(NSUInteger)itemIndex { return [[dataSource pages] objectAtIndex:itemIndex]; } - (void)collectionView:(CollectionView *)collectionView didSelectItemAtIndex:(NSUInteger)itemIndex { if (editMode == YES) { [collectionView yellowdidSelectItemAtIndex:itemIndex]; // NSLog(@"edit"); }else{ PVPage *selectedPage = [[[dataSource pages] objectAtIndex:itemIndex]autorelease]; PageView *pageView = [[[PageView alloc] init] autorelease]; [pageView setRepresentedPage:selectedPage]; // UIImage *i = [UIImage imageWithData: [[pageView representedPage] thumbnail]]; // UIImageView *ii = [[[UIImageView alloc] initWithImage:i]autorelease]; [viewController setView:pageView]; // [(PageView*)[viewController view] setBackgroundStrokes:ii]; //NSLog(@"selected page %@",selectedPage); // [[[self navigationController] toolbar] setHidden:YES]; // [[[self navigationController] navigationBar] setHidden:YES]; // [[[self tabBarController] tabBar] setHidden:YES]; PageFlipperAppDelegate *appDelegate = (PageFlipperAppDelegate *)[[UIApplication sharedApplication] delegate]; // [(UiWindowSubclass *)appDelegate.window startTimer]; [(UINavigationController *)[(UiWindowSubclass*)[appDelegate window] rootViewController] pushViewController:viewController animated:YES]; // viewController = nil; // [[self navigationController] setToolbarHidden:NO]; } } - (BOOL)collectionView:(CollectionView *)collectionView canDeleteItemAtIndex:(NSUInteger)itemIndex { NSLog(@"itemIndex %u",itemIndex); return YES; } - (void)collectionView:(CollectionView *)collectionView didDeleteItemAtIndex:(NSUInteger)itemIndex { [dataSource removePageAtIndex:itemIndex]; } -(void)trash{ // NSLog(@"trash"); [(CollectionView *)[self view] trashitems]; } -(void)done{ [(CollectionView *)[self view] yellowdidSelectItemAtIndexUndo]; [(CollectionView *)[self view] shakedidRemoveSelectItemAtIndex]; [(CollectionView *)[self view] donereset]; [self finishEditToolBars]; } -(void) finishEditToolBars{ [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)] autorelease]]; [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(didHoldItem)] autorelease]]; editMode = NO; } -(void)duplicatePage{ NSArray *tempArray = [[[(CollectionView*)[self view] selectedItemsArray]copy]autorelease]; // for (int i =0; i<[[(CollectionView*)[self view] selectedItemsArray]count]; i++) { // [(CollectionView *)[self view] yellowdidSelectItemAtIndex:i]; // // } [dataSource duplicatePage:[[[NSArray alloc] initWithArray:tempArray]autorelease]]; CollectionView *collectionView = (CollectionView *)[self view]; editMode = NO; [self done]; // [(CollectionView *)[self view] yellowdidSelectItemAtIndexUndo]; collectionView.canReloadData = YES; [collectionView layoutSubviews]; } -(void)didHoldItem{ [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done)] autorelease]]; // [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(trash)] autorelease]]; toolBar* tools = [[toolBar alloc] initWithFrame:CGRectMake(0, 0, 133, 44.01)]; tools.barStyle = UIBarStyleBlackTranslucent; tools.opaque = NO; //tools.backgroundColor = [UIColor clearColor]; // create the array to hold the buttons, which then gets added to the toolbar NSMutableArray* buttons = [[NSMutableArray alloc] initWithCapacity:3]; // create a standard "add" button UIBarButtonItem* bi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(trash)]; bi.style = UIBarButtonItemStyleBordered; [buttons addObject:bi]; [bi release]; // create a spacer bi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; [buttons addObject:bi]; [bi release]; // create a standard "refresh" button bi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize target:self action:@selector(duplicatePage)]; bi.style = UIBarButtonItemStyleBordered; [buttons addObject:bi]; [bi release]; // stick the buttons in the toolbar [tools setItems:buttons animated:NO]; [buttons release]; // and put the toolbar in the nav bar self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:tools] autorelease]; [tools release]; [(CollectionView*)[self view] setOldItemIndex:-1]; editMode = YES; [(CollectionView*)[self view] setEditMode:YES]; [(CollectionView*)[self view] shakedidSelectItemAtIndex]; } -(void)didReceiveMemoryWarning{ // NSLog(@"mem"); } - (void)dealloc { [dataSource release],dataSource = nil; [viewController release],viewController = nil; [super dealloc]; } -(void)viewDidAppear:(BOOL)animated{ [ (CollectionView*) [self view] setCanReloadData:YES]; [(CollectionView*) [self view] layoutSubviews]; } -(void) viewDidLoad{ CollectionView *collectionView = (CollectionView *)[self view]; collectionView.canReloadData = YES; [(CollectionView*)[self view]layoutSubviews]; editMode = NO; collectionView.editMode = NO; } @end 
+4
source share
5 answers

Apple Developer Forums provide sample iPhoneCoreDataRecipes code that includes iCloud.

https://devforums.apple.com/thread/126670?tstart=0

+4
source

This year, you can watch the WWDC 2012 Session 227 lecture (you can freely access these videos using your Apple Developer account), which will show how to use Core Data and iCloud together, illustrating the correct application architecture, the way Core Data and iCloud should talk to each other and explain all this through a complete sample project.

Edit

The full source of the project is available only to registered Apple developers to everyone . this page .

+3
source

This is a very controversial topic ... I need to add iCloud with Core Data in my next application, but it's a little difficult to get started. I did nothing, but I found these documents very useful:

+2
source

It is not just controversial, it does not work, not yet enough. If you can encode a sample, you will most likely find that it only works occasionally. I'm sorry that I could not write what he decided, and here's how you use it - maybe someone else, but since March 2012 I doubt it.

However, it is interesting and instructive to encode the sample, and the rest on the dev site, so you can find out what iCloud / core data is.

Many of us hammer a bit to strengthen it.

You can try the Dox from Ray Wenderlich a fantastic site. But you will most likely find yourself in the same disappointment. Sometimes it works, mostly not.

+2
source

Blackpixel has lifted the version of Master Data Tanks with iCloud on Github . It may have improvements over the dev forums.

I used the dev version of the forums and found that it works, but it takes some time to synchronize. Read the comments there (19 pages and count) and decide about it.

+2
source

Source: https://habr.com/ru/post/1397202/


All Articles