Posts

Post not yet marked as solved
1 Replies
0 Views
You can find the information you are looking using the CKRecordZone.ID and a little bit of logic! Since the Zone ID contains the owner name, you can just compare that to the active user (CKCurrentUserDefaultName) to see if we are writing into our own database or someone else’s (since users can’t create zones in other user’s databases, that means if we don’t own it we are targeting the sharedDB). I generally recommend to treat the CKRecordZone.ID as just as critical information alongside of the CKRecord’s metadata, even if you aren’t using multiple databases, since without it you lose the ability to accurately target records if you are to expand into multiple zones/databases in the future — I go as far as tombstoning this information along with the CKRecord.ID after local deletion since it can become a nightmare to deal with offline/failed deletes without it.
Post marked as solved
1 Replies
0 Views
The best way to go about this is to schedule a local notification to trigger whenever the timer is set to expire. When your application is about to move into the background, calculate a timestamp based on the current time and time left, schedule the notification, and then stop all work in your application related to the countdown (like UI loops or any other in-app work). If the user leaves the app or locks the phone, they will receive a notification at that time to bring them back into the app. When your app moves back into the foreground, update your your based on the current time: if any of their timers expired, show the UI as completed; if not, start a new loop to manage the countdown UI from the current point with the time left. Unfortunately iOS will not give you enough time running in the background to keep a timer active. You get a few moments to do clean up work (like what I mention above) but nothing more — even attempting to request more time from the system will not give you the length you are looking for… and if you keep doing work too long in the background, iOS will terminate just your application. Ideally, unless you are updating the UI on screen (like a visual countdown), you shouldn’t be running an ongoing task like this— it’s better to schedule these events out ahead of time: there’s much less work for the system to do and much less for you to manage this way. Using notifications you can get several customizations to help integrate with system features like Wind Down and some even more interesting ones in iOS 15 — you can’t get something exactly like clock which is a part of the system, but you CAN get something good!
Post marked as solved
18 Replies
0 Views
You are my heroes! Though I can't get it to build on device with this set, it's nice to be able to at least use Previews (and simulator) when I'm working.
Post marked as solved
1 Replies
0 Views
You said "iCloud" and "data limit" but the services under the umbrella and those terms are all different based on the tags (across two different services). It really boils down to what the user is doing, what service you are using, and what your system looks like: If they are creating / managing a document: let them know what is happening and allow only local saves until resolved or a specific amount of free space opens; you can take an existing cloud-based document and move it to a cache so to prevent data loss or just store it locally. UIDocument and its lifecycle is pretty rich with error handling so there's a lot of opportunity to handle this situation. If you are using CloudKit, there are different options based on what you are doing and what you mean. If the user has run out of space, you should tell them and then either cache changes locally (to push up when done), treat the situation as if the user has logged out, or just prevent edits if there's no local store mechanism in place. If your app has hit a data transfer/requests quota, you have larger foundational development problems with your CloudKit mechanism and you should look at addressing those problems (I haven't yet, in two years with many many users, hit my apps CK quota). There is no way to donate data to the user, this is a situation in which they need to resolve and the good news is that the system will be prompting them all over outside of our app. Ideally, you'd let them know once per session, what the app is doing until that problem is resolved, and continue to let their interaction move forward.
Post not yet marked as solved
1 Replies
0 Views
Have you had any luck here? I'm looking into this as well and from what I can tell, Apple does this very thing when switching between the List and Grid view in Notes.
Post not yet marked as solved
36 Replies
0 Views
ShapeEdit! ShapeEdit!
Post not yet marked as solved
6 Replies
0 Views
Bug in SwiftUI lifecycle — Apple acknowledged it in a ticket I put out but that's as far as I've gotten.
Post not yet marked as solved
2 Replies
0 Views
Testing NavigationLink(destination:tag:selection:) on iOS 13 results in behavior that's similar: Selection Occurs, the publisher fires the proper tag. Selection is lost, the publisher fires nil twice So it looks like in iOS 14 we are now getting some sort of weird hybrid behavior. And using .tag on iOS 13 with List selection doesn't work at all so there must have been some work done to try and extend the capabilities.
Post marked as solved
2 Replies
0 Views
Sounds good to me! Thanks!
Post not yet marked as solved
13 Replies
0 Views
Ah I totally see what you're saying! Very frustrating.I wish we could get more insight to why this error is being put up. And why CloudKit error is lacking the data to actually resolve it because I'm surely going to hit this issue in the future.I'm really confused because I'm not sure what is actually related to the chain on the parent record, besides its existance. Did you figure that out?
Post not yet marked as solved
13 Replies
0 Views
Yep, that's essentially the same thing that I am doing and I get no kickback unless I attempt to delete a parent with children, and even in that case I'm provided with a different error under the CKErrorReferenceViolation branch. I even just tested it and am not having issues what-so-ever. Currently using a custom zone in the private container, made using the save method on the privateDB (I assume all capabilities enabled). Using CKModifyRecordsOperation to push my changes to the record, just as you are.Oh, but I did just dig up that I change the default savePolicy property on the Operation! The default CKModifyRecordsOperation.RecordSavePolicy is .ifServerRecordUnchanged but for this type of operation it should probably be set to .changedKeys. Then keys you're not interacting with won't be touched.
Post not yet marked as solved
13 Replies
0 Views
> Now device number 2 comes along and also creates a record named Drinks but does not have the one on the server yet (obviously). Also device 2 does not create Milk and Juice (or any children for that matter). So device 2 sends its version of Drinks to the server, and I get the server record changed error. How would I handle it? In this case, I'd cache the server records metadata of drinks in my local cache. Later (hopefully soon) I'll get a notification and my fetch zone changes operation will pull down Milk & Juice.My 2 cents is that this error calls for an active & major resolution to ensure the devices are back in sync before waiting on the next fetch to travel down with specific records that need updating. If something happens and you can't get those fetches (CloudKit or device move offline, record changes lost, device termination, etc), it can make resolving your records with a users new changes to the local store a nightmare as they queue on either side. It also can/tends to affect large sets of records.I now assume that the entire local store of relevant objects on device number 2 is entirely out of sync with the cloud records, so instead of trying to resolve it on a scoped single record or record chain basis (Drink, Milk & Juice), I pull down every record in both parent, child record types in the zone and compare, merge them into my current device model with varying degrees of specificity. This helps to avoid records ghosting out on Device 2, while existing on Device 1 and in the cloud. The assumption here being the worst: you'll never get those record changes (changesets have been lost in some way, things have gotten too complex to resolve, or the user is making major conflicts before fetches complete [which sum up the situations when I'd most often experience this error]).From there I split untouched model objects away from those that are new, newer on device, or deleted (aided by a tombstone) and push those changes back into the cloud store. The goal being to resolve all changes in this store in one change cycle. Device 1, 3, 4 receive the updated changes from the Cloud notification or launch fetch changes operation to bring them both to partiy with each other. If one of those devices enters a similar state in the meantime as 2, they can do the same flush, repeating the cycle.Edit, I completely misintpreted your original question: That's (seemingly) bizarre behavior that I'm not getting and can't find information on the net about. When I push a locally created parent record from an object, nil recordChangeTag (which also lacks the CK metadata that exists on its cloud record version and has children records in the cloud) it successfully merges, no fuss. This is one of the first things I tested after I enabled sharing by making sure document titles synced!I definitly do not get a kickback requiring me to pull down the cloud metadata at all.
Post not yet marked as solved
10 Replies
0 Views
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.