9 Replies
      Latest reply on Nov 10, 2019 6:24 PM by PBK
      Macho Man Randy Savage Level 3 Level 3 (375 points)

        So working on an app that uses CloudKit (private database). Now, the app is allowed to run in "local mode" if the user is not using iCloud or has disabled iCloud for my app.

         

        Now imaging this case:

        1) iCloud is not enabled for my app and the user starts creating data.

        2) The user subsequently enables iCloud for my app.

        3) My app gets a CKAccountChangedNotification.

        4) My app starts uploading local data the user created before iCloud was enabled to CloudKit.

        5) My app gets a CKErrorQuotaExceeded when uploading data.

        6) My app displays an alert, telling the user he has run out of iCloud storage and he can either Buy More in iCloud Settings or turn off iCloud for the app to run in "Local mode."

         

        So now my app is in this state where iCloud is enabled but the user has no iCloud storage left. I don't see any API to tell if iCloud storage changed. If the user goes to Settings, buys more storage, and goes back to my app, I'd like to retry sending the local data back to Cloudkit for initial sync. I guess I just have to retry the operation every time the app is launched and show the error over and over again until the user does something about it (disable iCloud in Settings or buy more storage)?

         

        Ideally, I'd like to give the user an option to turn off iCloud (for my app only) in app when the error is hit, because telling them to navigate to Settings to turn off iCloud is hard for a lot of people. Or present a system provided view controller offerring them to upgrade their iCloud storage plan. CKStoragePurchaserViewController?

         

        #pragma mark - CKStoragePurchaserViewControllerDelegate
        -(void)storagePurchaserViewControllerDidPurchaseAdditionalStorage:(CKStoragePurchaserViewController*)vc
        {
           //retry sync.
        }
        
        -(void)storagePurchaserViewControllerDidDisableICloudFunctionality:(CKStoragePurchaserViewController*)vc
        {
            //iCloud is now off, run the app in local mode.
        }
        • Re: CloudKit Notification for Checking if User Upgraded iCloud Storage Space for error handling?
          JimmyCricket Level 1 Level 1 (10 points)

          From a UX perspective, I'd only tell them they hit their quota a single time, give them the option to hop into Settings or disable iCloud syncing within your app, and leave it at that. At most, after explicitly tellng them the first time, I'd just show some sort of icon near the relevant setting (SF symbol exclamationmark.icloud would work well).

           

          Then I'd say it's safe to just keep hitting CloudKit with the same request until it succeeds, keeping any additional errors silenced.

            • Re: CloudKit Notification for Checking if User Upgraded iCloud Storage Space for error handling?
              Macho Man Randy Savage Level 3 Level 3 (375 points)

              >Then I'd say it's safe to just keep hitting CloudKit with the same request until it succeeds, keeping any additional errors silenced.

               

              This may be the only way to deal with the issue under the current API. Would be nice to offer them an option to purchase additional storage or at least turn off iCloud in app or to do something other than manually explaining to the user their options: "You need to go to Settings -> iCloud -> App name and turn off iCloud for this app." Unless there is an API to direct them the proper location in Settings I can call from a button in the alert, but I don't think there is? Having them leave the app isn't a great experience either though.

               

              I could have my own preference to turn off iCloud in app when iCloud is enabled so I could workaround this so I'd treat the user as having iCloud disabled if he disables it in *my ui* (lots of people don't know how to turn off iCloud for a particular app). But then I'm adding an extra layer of complexity on the user if he ever bought more storage later and wanted to re-enable it (has to turn on my preference, and manage the one in Settings). So yeah, I guess I just have to keep hitting Cloudkit and show the out of storage error. I probably would display it more than once (because people forget, why isn't this working?!). Maybe once a week. Once a month?

               

              >At most, after explicitly tellng them the first time, I'd just show some sort of icon near the relevant setting (SF symbol exclamationmark.icloud would work well).

               

              Having to carve out UI for this is a decent amount of extra work. Not sure what Setting I'd put it next to, since my app cannot provide any UI that toggles iCloud availability (as mentioned above, adding an extra preference on top of iCloud preference in Settings is not exactly ideal). Would be nice if I could pop the icon in the status bar.

                • Re: CloudKit Notification for Checking if User Upgraded iCloud Storage Space for error handling?
                  JimmyCricket Level 1 Level 1 (10 points)

                  I don't think you need to worry about them leaving the app if you're explicitly giving them an action to perform that can only been done outside of it; they'll come back as long as the task they leave the app for is in the same vein of work and not very complicated. I remember there was once a URL scheme to pop a user into the Account settings, but I'm not too sure if it's still working at this point.

                   

                  Foregoing an actual toggle for enabling and disabling iCloud within your app independent of the system controls, I'd really recommend having some sort of view that can pop into your settings (or somewhere within your UI) whenever there's an unexpected issue with cloud services. While not the same situation, Apple's Setting's app will put a rows at the top of the list when there's immediate action that needs to be taken by the user (like Billing Issues, Updates Pending, see: payment-and-shipping-settings--467x500.jpg). Those dialogs are pretty simple and just work towards helping the user solve the problem.

                   

                  While iCloud should be seamless, problems like this should be available for the user to fix at their own digression after telling them the first time. Otherwise your users will get frustrated with the experience and drop off when they can't find any sort of UI mechanism reflecting that something isn't working to help match their interpretations. Throttling the alert dialogs is a good idea, but each time you show it and the user actively doesn't take action, the less impact it'll have on each reappearance.

                  • Re: CloudKit Notification for Checking if User Upgraded iCloud Storage Space for error handling?
                    PBK Level 7 Level 7 (3,295 points)

                    TMI.  But they don't 'leave the app' if you:

                     

                                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"App-Prefs:"] options:[NSDictionary dictionary] completionHandler:nil];
                    
                • Re: CloudKit Notification for Checking if User Upgraded iCloud Storage Space for error handling?
                  PBK Level 7 Level 7 (3,295 points)

                  You are already starting out this way:

                   

                  1) iCloud is not enabled for my app and the user starts creating data.

                  2) The user subsequently enables iCloud for my app.

                   

                  If you hit that 'quota exceeded' error then issue an alert to the user saying that they are being switched back to the default setting.  Switch them back (#1) so that they have to do #2 again.  No need to test anything.