Running a CKFetchRecordsOperation while in UIApplicationStateBackground
My app is setup to receive CloudKit remote notifications. Sometimes it receives these notifications while it is running in the background. I have not done anything with these notifications yet - I have simply passed UIBackgroundFetchResultNewData to the completion handler. The reason is that I didn't think I could simply download from CloudKit while in the background - I thought that could only be done via Background Fetch or setting up a special job to run in the background. But I am revisiting this now, and I see that running the CKFetchRecordsOperation and downloading the related CKAsset file while in UIApplicationStateBackground actually does seem to work.
So my current code is this:
- (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);
And I want this code to be this:
- (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);
Does running a CKFetchRecordsOperation and downloading the related CKAsset file while in the background constitute any sort of a violation of what can (or SHOULD) be done in the background?
ios core-data background-process cloudkit remote-notifications
add a comment |
My app is setup to receive CloudKit remote notifications. Sometimes it receives these notifications while it is running in the background. I have not done anything with these notifications yet - I have simply passed UIBackgroundFetchResultNewData to the completion handler. The reason is that I didn't think I could simply download from CloudKit while in the background - I thought that could only be done via Background Fetch or setting up a special job to run in the background. But I am revisiting this now, and I see that running the CKFetchRecordsOperation and downloading the related CKAsset file while in UIApplicationStateBackground actually does seem to work.
So my current code is this:
- (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);
And I want this code to be this:
- (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);
Does running a CKFetchRecordsOperation and downloading the related CKAsset file while in the background constitute any sort of a violation of what can (or SHOULD) be done in the background?
ios core-data background-process cloudkit remote-notifications
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49
add a comment |
My app is setup to receive CloudKit remote notifications. Sometimes it receives these notifications while it is running in the background. I have not done anything with these notifications yet - I have simply passed UIBackgroundFetchResultNewData to the completion handler. The reason is that I didn't think I could simply download from CloudKit while in the background - I thought that could only be done via Background Fetch or setting up a special job to run in the background. But I am revisiting this now, and I see that running the CKFetchRecordsOperation and downloading the related CKAsset file while in UIApplicationStateBackground actually does seem to work.
So my current code is this:
- (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);
And I want this code to be this:
- (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);
Does running a CKFetchRecordsOperation and downloading the related CKAsset file while in the background constitute any sort of a violation of what can (or SHOULD) be done in the background?
ios core-data background-process cloudkit remote-notifications
My app is setup to receive CloudKit remote notifications. Sometimes it receives these notifications while it is running in the background. I have not done anything with these notifications yet - I have simply passed UIBackgroundFetchResultNewData to the completion handler. The reason is that I didn't think I could simply download from CloudKit while in the background - I thought that could only be done via Background Fetch or setting up a special job to run in the background. But I am revisiting this now, and I see that running the CKFetchRecordsOperation and downloading the related CKAsset file while in UIApplicationStateBackground actually does seem to work.
So my current code is this:
- (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);
And I want this code to be this:
- (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);
Does running a CKFetchRecordsOperation and downloading the related CKAsset file while in the background constitute any sort of a violation of what can (or SHOULD) be done in the background?
ios core-data background-process cloudkit remote-notifications
ios core-data background-process cloudkit remote-notifications
edited Nov 15 '18 at 18:00
SAHM
asked Nov 15 '18 at 5:09
SAHMSAHM
1,46533266
1,46533266
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49
add a comment |
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49
add a comment |
0
active
oldest
votes
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53312793%2frunning-a-ckfetchrecordsoperation-while-in-uiapplicationstatebackground%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53312793%2frunning-a-ckfetchrecordsoperation-while-in-uiapplicationstatebackground%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
CKAssets are used to store large files (Apple recommends anything more than a few kilobytes in size, but no more than 250MB) in iCloud and associate them with specific CKRecords. When downloading a record with a CKAsset, the asset’s data is temporarily saved to disk, but it is not guaranteed to stay there long, and may be cleaned up when the system needs to free memory. So it is definitely a good idea to get the data from the asset as soon as the record is downloaded. The file can be accessed from the asset’s fileURL property.
– Kousic
Nov 22 '18 at 5:49