Posts

Post not yet marked as solved
0 Replies
442 Views
This session provides sample code for NavigationSplitView to display a selected item in details view, and refers to the Backyard Birds sample app; NavigationSplitView { List(backyardsData.backyards, selection: $selectedBackyard) { backyard in BackyardCell(backyard: backyard) } .listStyle(.carousel) } detail: { if let selectedBackyard { BackyardView(backyard: selectedBackyard) } else { BackyardUnavailableView() } } However, the sample code does not work on watchOS 10 beta 1 or 2, and even the sample app Backyard Birds does not use this pattern in code (this links to Watch ContentView file on Apple's GitHub repo). To make sure I wasn't crazy, I've tried to navigate to details view when the data set is: a @State var with array of items a class conforming to ObservableObject and holding a @Published array of items (similar to what Backyard Birds is doing) FetchedResults from CoreData None of them do anything when a “cell” is tapped. My conclusion is that it isn't yet implemented [right]. Has anyone else got it to work?
Posted Last updated
.
Post marked as solved
6 Replies
2.0k Views
The problem When the UICloudSharingController is invoked on an existing share with participants, the controller should be showing the row/button to "Add people" but it doesn't. This problem is (still) present in iOS 15.1 beta 3 released Oct 6th 2021. The problem first manifested in one of the early betas of iOS 15.0 (possibly beta4). I have previously filed this as FB9648211 and I am getting desperate because “Recent similar reports:“ is always “None”, and this thing never gets on the Known issues list on the iOS/iPadOS beta Release Notes. What this means This means that you can only invite 1 person to a CKShare (even though the theoretical max is 100) until Apple fixes this. The problem affects any app that uses this controller, even those that have been in the App Store for a long time. Side info Apple's Notes also use UICloudSharingController but it is customized beyond capabilities of the public API, and that one does show "Add People", while the “public API” one does not. So just checking this controller within "Notes" is not indicative of the problem. To test and verify To test and verify, you can use any app that uses UICloudSharingController that is not produced by Apple. You can even use Apple's sample code from github: https://github.com/apple/cloudkit-sample-sharing Steps: Share a record with someone (makes them a participant with the role “user“, does not matter if they accept the invite or not) After UICloudSharingController dismisses, share that record again. You will see the controller show with the title "People", it will list you as the Owner if the first row, then the original invitee, but no “Add people“ button below them This screenshot shows the UICloudSharingController not displaying the "Add people" button below the list of share participants:
Posted Last updated
.
Post not yet marked as solved
2 Replies
647 Views
An app running on device that successfully registered for remote notifications with device token is not getting remote notifications from CloudKit: it is not getting triggered for CKRecordZoneSubscription in a custom zone in the private database it is not getting triggered for CKDatabaseSubscription in the shared database The same app is running smoothly on two other 15.1 devices Is anyone else experiencing this? What could be the cause of this?
Posted Last updated
.
Post not yet marked as solved
0 Replies
509 Views
CloudKit documentation states that tokens for CKFetchDatabaseChangesOperation and CKFetchRecordZoneChangesOperation aren't compatible and should be segregated in app's cache. I have written a class to help persist these tokens in UserDefaults (code below). The class constructs strings to be used as UserDefaults keys based on the following logic: For zones, zoneID.ownerName + zoneID.zoneName, which results in something like _defaultOwner__Employees For databases, "db" + database.databaseScope.rawValue, which results in something like db3 for shared database While I'm quite happy how this works, I've realized that this exposes iCloud userIDs when you persist a zone from a shared database. How big of a security problem is this? Any suggestions what I could do differently? Code: (also available as GitHub gist) import CloudKit final class ChangeTokenCache {     // MARK: - Zone support     /// Determines a unique UserDefaults key for storing zone change tokens     /// like from CKFetchRecordZoneChangesOperation     private static func userDefaultsKey(_ zoneID: CKRecordZone.ID) -> String {         return "token_" + zoneID.ownerName + zoneID.zoneName     }     /// Persists a zone change token in standard UserDefaults     static func setZoneToken(_ zoneID: CKRecordZone.ID, token: CKServerChangeToken?) {         setToken(userDefaultsKey(zoneID), token: token)     }     /// Fetches a zone change token from standard UserDefaults     static func getZoneToken(_ zoneID: CKRecordZone.ID) -> CKServerChangeToken? {         return getToken(userDefaultsKey(zoneID))     }     // MARK: - Database support     /// Determines a unique UserDefaults key for storing database change tokens     /// like from CKFetchDatabaseChangesOperation     private static func userDefaultsKey(_ database: CKDatabase) -> String {         return "token_db\(database.databaseScope.rawValue)"     }     /// Persists a database change token in standard UserDefaults     static func setDatabaseToken(_ database: CKDatabase, token: CKServerChangeToken?) {         setToken(userDefaultsKey(database), token: token)     }     /// Fetches a database change token from standard UserDefaults     static func getDatabaseToken(_ database: CKDatabase) -> CKServerChangeToken? {         return getToken(userDefaultsKey(database))     }     // MARK: - Actual workers     /// Private method that archives a token as data and persists that to UserDefaults     private static func setToken(_ userDefaultsKey: String, token: CKServerChangeToken?) {         if let token = token,            let data = try? NSKeyedArchiver.archivedData(withRootObject: token, requiringSecureCoding: false) {             UserDefaults.standard.set(data, forKey: userDefaultsKey)         } else {             UserDefaults.standard.removeObject(forKey: userDefaultsKey)         }     }     /// Private method that gets data from UserDefaults and unarchives it as a token     private static func getToken(_ userDefaultsKey: String) -> CKServerChangeToken? {         guard let data = UserDefaults.standard.value(forKey: userDefaultsKey) as? Data else { return nil }         var token: CKServerChangeToken?         do {             token = try NSKeyedUnarchiver.unarchivedObject(ofClass: CKServerChangeToken.self, from: data)         } catch {             token = nil         }         return token     } }
Posted Last updated
.
Post marked as solved
1 Replies
929 Views
The “Discoverable Design“ session showcases the app Toasty, and it's “Recipes“ has a grid of items where the first one is an invitation to add a new photo (i.e. a static cell). To replicate that concept in my collectionView, I need advice how best to approach it. My collectionView has a single section and is powered by a UICollectionViewDiffableDataSource, which is populated from a NSFetchedResultsController and relies on CellRegistration. In addition, the user can change the sort order, which updates fetchedResultsController's sortDescriptors and performs a fetch. My failed approach was focused on the dataSource snapshot built in fetchedResultsController's didChangeContentWith. First I appended the snapshot with a dummy entry, and then appended all fetchedObjects. I made sure that the dataSource constructor used a different cell registration for the (0,0) IndexPath. This however resulted in indexPath mismatches between the collectionView and FRC, and I don't think remapping indexPaths is the way to go. Point me in the right direction? Is there a way to configure the collectionView layout for this?
Posted Last updated
.