skip to Main Content

I am using NSPersistentCloudKitContainer, to integrate CoreData with CloudKit.

What I want to achieve is to prompt the user to go to iCloud settings to manage their storage when there is a sync error, and we realize the user doesn’t have enough iCloud storage.

I am using the following code snippet, to monitor the sync progress.

// https://crunchybagel.com/nspersistentcloudkitcontainer/
private func initEventChangedNotification() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(eventChangedNotification),
        name: NSPersistentCloudKitContainer.eventChangedNotification,
        object: nil
    )
}

@objc func eventChangedNotification(_ notification: Notification) {
    CoreDataStack.eventChangedNotification(notification)
}

static func eventChangedNotification(_ notification: Notification) {
    guard let event = notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event else {
        return
    }

    if let error = event.error {
        print(">>>> error = (error)")
        if let ckError = error as? CKError {
            print(">>>> ckError.errorCode = (ckError.errorCode)")
            print(">>>> ckError.localizedDescription = (ckError.localizedDescription)")
        }
        
        error_log(error)
        return
    }
    
    let isFinished = event.endDate != nil
    ...
}

I run the above code with my iCloud storage is full.

What I am expecting, is to receive quotaExceeded (Error code 25)

However, what I am receiving is partialfailure (Error code 2)

Here’s the logging

>>>> error = Error Domain=CKErrorDomain Code=2 "(null)"
>>>> ckError.errorCode = 2
>>>> ckError.localizedDescription = The operation couldn’t be completed. (CKErrorDomain error 2.)

However, when I run another app in the same device, using the same iCloud account, this is how it looks like.

enter image description here

  1. It is able to detect quotaExceeded (Error code 25)
  2. Tapping on ‘Sync now’ triggers the sync operation to run immediately. How are they able to achieve this? I thought we have no control over when the sync runs?

May I know, how can we reliably detect when a user runs out of iCloud storage?

Thank you

2

Answers


  1. It’s likely this app is using CloudKit API directly rather than NSPersistentCloudKitContainer. Therefore it could perform a sync anytime, and find out if the quota has been exceeded or not by just test upload a small CKRecord to see if it is possible.

    Login or Signup to reply.
  2. Did you find a solution? I have the same issue with detecting if a users iCloud is full. In my case I use both NSPersistentCloudKitContainer and an iCloud container for images. I just need a reliable way to detect when they have run out of space.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search