启用iCloud时第一次启动时iOS应用程序冻结 [英] iOS Application freezing on first launch when iCloud is enabled

查看:121
本文介绍了启用iCloud时第一次启动时iOS应用程序冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的iOS应用程序中启用了iCloud,首次启动应用程序时,应用程序冻结约5秒钟,当我按任何视图的应用程序。我按照教程在我的应用中启用iCloud并同步数据使用核心数据。我在添加iCloud同步之前没有这个问题。这只发生在第一次启动,而不是在应用程序的其他启动。 iCloud同步会发生。问题是应用程序冻结。

I enabled iCloud in my iOS app and on first launch of the app the app freezes for about 5 seconds when i press on any view in the app. I followed this tutorial to enable iCloud in my app and synchronize data using core data. I did not have this problem before adding iCloud synchronization. This only happens on first launch, not on other launches of the app. iCloud synchronization does occur. The problem is the app freezing.

以下是管理我的应用程式委托同步作业的程式码。

Here is the code that manages the synchronization in my app delegate.

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    /*if (persistentStoreCoordinator == nil) {
        NSURL *storeURL = [NSURL fileURLWithPath:[self dataStorePath]];

        persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

        NSError *error;
        if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            NSLog(@"Error adding persistent store %@, %@", error, [error userInfo]);
            abort();
        }
    }
    return persistentStoreCoordinator;*/

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    if ((persistentStoreCoordinator != nil)) {
        return persistentStoreCoordinator;
    }

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSPersistentStoreCoordinator *psc = persistentStoreCoordinator;

    // Set up iCloud in another thread:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // ** Note: if you adapt this code for your own use, you MUST change this variable:
        NSString *iCloudEnabledAppID = @"48S27G4A2S.com.maxned.iDownloadBlog";

        // ** Note: if you adapt this code for your own use, you should change this variable:
        NSString *dataFileName = @"DataStore.sqlite";

        // ** Note: For basic usage you shouldn't need to change anything else

        NSString *iCloudDataDirectoryName = @"Data.nosync";
        NSString *iCloudLogsDirectoryName = @"Logs";
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
        NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];

        if (iCloud)
        {
            //NSLog(@"iCloud is working");

            NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];

            /*NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
            NSLog(@"dataFileName = %@", dataFileName);
            NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
            NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);
            NSLog(@"iCloud = %@", iCloud);
            NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);*/

            if ([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
                NSError *fileSystemError;
                [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
                       withIntermediateDirectories:YES
                                        attributes:nil
                                             error:&fileSystemError];

                if (fileSystemError != nil) {
                    NSLog(@"Error creating database directory %@", fileSystemError);
                }
            }

            NSString *iCloudData = [[[iCloud path]
                                     stringByAppendingPathComponent:iCloudDataDirectoryName]
                                    stringByAppendingPathComponent:dataFileName];

            //NSLog(@"iCloudData = %@", iCloudData);

            NSMutableDictionary *options = [NSMutableDictionary dictionary];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
            [options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
            [options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];

            [psc lock];

            [psc addPersistentStoreWithType:NSSQLiteStoreType
                configuration:nil
                URL:[NSURL fileURLWithPath:iCloudData]
                options:options
                error:nil];

            [psc unlock];

        } else {

            NSLog(@"iCloud is NOT working - using a local store");
            NSMutableDictionary *options = [NSMutableDictionary dictionary];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

            [psc lock];

            [psc addPersistentStoreWithType:NSSQLiteStoreType
                configuration:nil
                URL:localStore
                options:options
                error:nil];

            [psc unlock];

        }

        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];
        });
    });

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    return persistentStoreCoordinator;
}

/*- (NSManagedObjectContext *)managedObjectContext
{
    if (managedObjectContext == nil) {
        NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
        if (coordinator != nil) {
            managedObjectContext = [[NSManagedObjectContext alloc] init];
            [managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
    }
    return managedObjectContext;
}*/

- (NSManagedObjectContext *)managedObjectContext
{
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

    if (coordinator != nil) {
        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;
}

- (void)mergeChangesFrom_iCloud:(NSNotification *)notification
{
    //NSLog(@"Merging in changes from iCloud...");

    NSManagedObjectContext* moc = [self managedObjectContext];

    [moc performBlock:^{

        [moc mergeChangesFromContextDidSaveNotification:notification];

        NSNotification* refreshNotification = [NSNotification notificationWithName:@"SomethingChanged"
            object:self
            userInfo:[notification userInfo]];

        [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
    }];
}


推荐答案

将代码放到另一个线程中。

To fix this problem I changed the code to put it in another thread.

dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{

            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
            NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];

            if (iCloud)
            {
                //NSLog(@"iCloud is working");

                NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];

                /*NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
                 NSLog(@"dataFileName = %@", dataFileName);
                 NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
                 NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);
                 NSLog(@"iCloud = %@", iCloud);
                 NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);*/

                if ([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
                    NSError *fileSystemError;
                    [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
                           withIntermediateDirectories:YES
                                            attributes:nil
                                                 error:&fileSystemError];

                    if (fileSystemError != nil) {
                        NSLog(@"Error creating database directory %@", fileSystemError);
                    }
                }

                NSString *iCloudData = [[[iCloud path]
                                         stringByAppendingPathComponent:iCloudDataDirectoryName]
                                        stringByAppendingPathComponent:dataFileName];

                //NSLog(@"iCloudData = %@", iCloudData);

                NSMutableDictionary *options = [NSMutableDictionary dictionary];
                [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
                [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
                [options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
                [options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];

                [psc lock];

                [psc addPersistentStoreWithType:NSSQLiteStoreType
                                  configuration:nil
                                            URL:[NSURL fileURLWithPath:iCloudData]
                                        options:options
                                          error:nil];

                [psc unlock];

            } else {

                NSLog(@"iCloud is NOT working - using a local store");
                NSMutableDictionary *options = [NSMutableDictionary dictionary];
                [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
                [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

                [psc lock];

                [psc addPersistentStoreWithType:NSSQLiteStoreType
                                  configuration:nil
                                            URL:localStore
                                        options:options
                                          error:nil];

                [psc unlock];
            }
        });

这篇关于启用iCloud时第一次启动时iOS应用程序冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆