Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iCloud and CoreData

I am trying to use iCloud with my iOS app. I have the app working on the individual devices but when I added iCloud nothing happened. I have looked all over the web and have found only one example which I did not understand. My app is iOS 5.0 and use core data to store the pages. Below is my app delegate and my view which I display it in. 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 anyone know/has a full working project of iCloud+CoreData I belive I can figure it out. Right now I just have code snip it's which I don't even know how they get called... If I have a full project I can step through it, so I can fully understand how it works.

The problem is I don't think anything is being called to update the view with the data and I don't belive it is sending 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's 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's 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's Documents directory

    /**
     Returns the URL to the application's 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
like image 209
BDGapps Avatar asked Dec 12 '22 05:12

BDGapps


1 Answers

On the Apple developer forums the iPhoneCoreDataRecipes sample code is posted, which includes iCloud.

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

like image 108
thvanarkel Avatar answered Jan 04 '23 12:01

thvanarkel