(First, see comments to your reply)
I also tried modifying presentCloudSharingController as such:
func presentCloudSharingController(photo: Photo) {
self.cloudKitContainer.fetchUserRecordID { recordID, recordIDError in
if let id = recordID, nil == recordIDError {
self.cloudKitContainer.fetchShareParticipant(withUserRecordID: id) { participant, participantError in
if let p = participant, nil == participantError {
let participantIdentity = p.userIdentity
print ("CDS: Identity: \(participantIdentity.description)")
if let participantName = participantIdentity.nameComponents {
print ("CDS: Identity Name: \(participantName.description.isEmpty ? "<none>" : participantName.description)")
}
}
else { print ("CDS: Error `fetchShareParticipant") }
}
}
else { print ("CDS: Error `fetchUserRecordID") }
}
...
}
The resulting output is:
CDS: Identity: <CKUserIdentity: 0x301da83c0; userID=_bfbb377f5fb38b76ecb9b35c3d050c79:(_defaultZone:__defaultOwner__), nameComponents=, lookupInfo=<CKUserIdentityLookupInfo: 0x303765590; userRecordID=_bfbb377f5fb38b76ecb9b35c3d050c79:(_defaultZone:__defaultOwner__)>, cached=false, publicKeyVersion=2>
CDS: Identity Name: <none>
Again the nameComponents are empty.
Post
Replies
Boosts
Views
Activity
Any simple guidance or suggestions on this?
2024 here and the suggested solution doesn't work for me. I modified the Xcode template project for 'CoreData' such that the "item delete" occurs in a subview as a 'delete' button action. On delete I called one of:
extension NSManagedObjectContext {
public func singleDelete (_ object: NSManagedObject) {
self.delete(object)
try! self.save()
}
public func atomicDelete (_ object: NSManagedObject) {
self.perform {
self.delete(object)
try! self.save()
}
}
}
the atomicDelete helper extension being the suggested solution herein (less the do/catch logic). Both crashed in '#Preview' and on a simulator. Here is the subview:
extension Item {
var label: String {
"\(uuid!.uuidString.components(separatedBy: "-")[0]) (@ \(itemFormatter.string(from: timestamp!)))"
}
}
struct ItemBriefView: View { // Shown in navigationStack `List/ForEach`
@Binding var item: Item
var body: some View {
Text(item.label)
}
}
struct ItemView: View {
@Environment(\.managedObjectContext) private var context
@Environment(\.dismiss) var dismiss
var item: Item
var body: some View {
Form {
Text(item.label).padding(.bottom, 20)
Button ("Delete") {
context.atomicDelete(item)
dismiss()
}
}
}
}
The crashes are in the forced unwraps in \Item.lablel. (Telling me to use ?? is NOT a solution; I initialize every single managed object property and relationship).
Now, the solution/work-around I'm using is a wrapper view defined and used as such:
struct ItemView: View {
@Environment(\.managedObjectContext) private var context
@Environment(\.dismiss) var dismiss
var item: Item
var body: some View {
ManagedObjectDeleteWrapper (object: item) { item in
Form {
Text(item.label).padding(.bottom, 20)
Button ("Delete") {
context.singleDelete(item)
dismiss()
}
}
}
}
}
struct ManagedObjectDeleteWrapper<Object, Root> : View where Object : NSManagedObject, Root : View {
var object: Object
var root: (Object) -> Root
var body: some View {
Group {
if object.isFault { EmptyView() }
else { root (object) }
}
}
}
With this, one can detect a slight flash in the UI - which is better than a crash and the least of my SwiftUI 'oh, why is that happening' problems.
Cheers.
This approach, of mine, is nonsense as regards use of the 'UserRecord.' Rather than storing a UUID somewhere and then looking up that UUID in the CoreData just 1) wait for the CoreData to by synced from iCloud (e.g. use the 'import success' event) and then 2) filter all Users for 'is owner' (or some such flag). Still need to get the userIdentity and using a dummy{Zone|Share} seems suspect. Hopefully somebody knows the preferred approach.
Maybe just a 'Preview Cache' issue; cache has 'no parent entity' (original code); can't transition to 'parent entity' (refactored code).