Выполнение операции CKFetchRecordsOperation в UIApplicationStateBackground - PullRequest
0 голосов
/ 15 ноября 2018

Мое приложение настроено для получения удаленных уведомлений CloudKit. Иногда он получает эти уведомления, пока работает в фоновом режиме. Я ничего еще не сделал с этими уведомлениями - я просто передал UIBackgroundFetchResultNewData обработчику завершения. Причина в том, что я не думал, что смогу просто загрузить из CloudKit в фоновом режиме - я думал, что это можно сделать только с помощью Background Fetch или настройки специальной работы для запуска в фоновом режиме. Но сейчас я возвращаюсь к этому и вижу, что запуск CKFetchRecordsOperation и загрузка соответствующего файла CKAsset в UIApplicationStateBackground действительно работает.

Итак, мой текущий код такой:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    __ENTERING_METHOD__
    CKNotification *ckNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];
    if (ckNotification) {
        if ([ckNotification.subscriptionID isEqualToString:kCKDocumentChangeSubscription]) {
            CKRecordID *recordID = [(CKQueryNotification*)ckNotification recordID];
            if (recordID) {
                if([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {

                    if (completionHandler) {
                        completionHandler(UIBackgroundFetchResultNewData);
                    }
                }
                else {
                    CKFetchRecordsOperation *fetchRecordsOperation = [[CKFetchRecordsOperation alloc] initWithRecordIDs:@[recordID]];
                    fetchRecordsOperation.fetchRecordsCompletionBlock = ^(NSDictionary *recordsByRecordID, NSError *error) {

                        if (error) {
                            dispatch_async(dispatch_get_main_queue(), ^{
                                if (completionHandler) {
                                    completionHandler(UIBackgroundFetchResultFailed);
                                }
                            });
                        }
                        else {
                            CKRecord *ckDocumentRecord = recordsByRecordID[recordID];
                            CKAsset *documentAsset = [ckDocumentRecord objectForKey:ckDocumentAsset];
                            NSData *data = [NSData dataWithContentsOfURL:documentAsset.fileURL];
                            [self handleData:data];

                            UIBackgroundFetchResult result = (data == nil)?UIBackgroundFetchResultFailed:UIBackgroundFetchResultNewData;
                            if (completion) {
                                completion(result);
                            }
                        }

                    };
                    CKContainer *defaultContainer = [CKContainer defaultContainer];
                    CKDatabase *publicDatabase = [defaultContainer publicCloudDatabase];
                    [publicDatabase addOperation:fetchRecordsOperation];
                }
            }
            else {
                if (completionHandler) {
                    completionHandler(UIBackgroundFetchResultFailed);
                }
            }
        }
        else {
            if (completionHandler) {
                completionHandler(UIBackgroundFetchResultNoData);
            }
        }
    }
    else {
        if (completionHandler) {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }
}

И я хочу, чтобы этот код был таким:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    __ENTERING_METHOD__
    CKNotification *ckNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];
    if (ckNotification) {
        if ([ckNotification.subscriptionID isEqualToString:kCKDocumentChangeSubscription]) {
            CKRecordID *recordID = [(CKQueryNotification*)ckNotification recordID];
            if (recordID) {
                CKFetchRecordsOperation *fetchRecordsOperation = [[CKFetchRecordsOperation alloc] initWithRecordIDs:@[recordID]];
                fetchRecordsOperation.fetchRecordsCompletionBlock = ^(NSDictionary *recordsByRecordID, NSError *error) {

                    if (error) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            if (completionHandler) {
                                completionHandler(UIBackgroundFetchResultFailed);
                            }
                        });
                    }
                    else {
                        CKRecord *ckDocumentRecord = recordsByRecordID[recordID];
                        CKAsset *documentAsset = [ckDocumentRecord objectForKey:ckDocumentAsset];
                        NSData *data = [NSData dataWithContentsOfURL:documentAsset.fileURL];
                        [self handleData:data];

                        UIBackgroundFetchResult result = (data == nil)?UIBackgroundFetchResultFailed:UIBackgroundFetchResultNewData;
                        if (completion) {
                            completion(result);
                        }
                    }

                };
                CKContainer *defaultContainer = [CKContainer defaultContainer];
                CKDatabase *publicDatabase = [defaultContainer publicCloudDatabase];
                [publicDatabase addOperation:fetchRecordsOperation];
            }
            else {
                if (completionHandler) {
                    completionHandler(UIBackgroundFetchResultFailed);
                }
            }
        }
        else {
            if (completionHandler) {
                completionHandler(UIBackgroundFetchResultNoData);
            }
        }
    }
    else {
        if (completionHandler) {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }
}

Является ли выполнение CKFetchRecordsOperation и загрузка соответствующего файла CKAsset в фоновом режиме каким-либо нарушением того, что можно (или СЛЕДУЕТ) делать в фоновом режиме?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...