ios – CloudKit – Fetching the consumer creatorUserRecordID per NSManagedObject utilizing NSPersistentCloudKitContainer

ios – CloudKit – Fetching the consumer creatorUserRecordID per NSManagedObject utilizing NSPersistentCloudKitContainer


I wasn’t certain the right way to phrase the query. I do know it is deceptive.

Context:

I am utilizing NSPersistentCloudKitContainer for my private and non-private database. The CoreData mannequin has two configurations: Native, Cloud. Native corresponds to the personal CloudKit database and Cloud to the general public CloudKit database. Each configurations comprise all objects: Listing, ListItem, and Like.

Listing has a to-many relationship to ListItem (with inverse).
ListItem has a to-many relationship to Like (with inverse).

The personal database implementation is working as anticipated.

A consumer can create lists and checklist objects. Every of those objects may be set as public or personal utilizing the attribute isPublic.

I’ve a singleton object that displays modifications to Lists and ListItems utilizing the NSManagedObjectContextDidChange notification. If the consumer updates the isPublic attribute to true a duplicate of the Listing or ListItem is created within the public database. If the consumer units isPublic to false, the Listing or ListItem has an isTrashed attribute that is set to true within the public database (unsure when to truly delete the information from the general public database however, that is for an additional query).

The consumer also can view all ListItems within the public database utilizing a NSFetchedResultsController to load knowledge and for monitor modifications.

Downside

I can show all public ListItems utilizing a UITableView and a NSFetchedResultsController. I’ve a customized UITableViewCell that shows the consumer who created the ListItem’s username and likes like so:

  1. Get the creatorUserRecordID for the NSManagedObject utilizing NSPersistentCloudKitContainer.document(for:)
  2. Get the Person CKRecord for the creatorUserRecordID utilizing CKContainer.default().publicCloudDatabase.document(for:)
  3. Entry the username of the Person CKRecord

I do that async name for each UITableViewCell. Is that this appropriate? If that’s the case, I will must implement a caching mechanism.

Not solely that, what if the async name fails? Now, I’ve a UITableView cell that has a clean username. Ought to I prefetch the username for all objects within the NSFetchedResultsController beforehand? That could possibly be 1000’s of objects that have not even been displayed and will increase loading time.

I suppose my downside is absolutely validation that I am going about this the right means.

Is it appropriate to async fetch the Person CKRecord of every ListItem or is there a greater technique to entry the consumer who created the NSManagedObject?

Ought to I create a customized Person NSManagedObject?

I might additionally wish to show the usernames of every consumer who preferred the checklist merchandise. Does this imply for each like I will must do the identical course of? Which means I will have an API name for every username of every checklist merchandise and every like of every checklist merchandise ((1 + x) * y API calls; x = variety of likes, y = variety of checklist objects).

Say I am displaying 100 ListItems with a mean of 20 likes. Which means I will make:

(1 + 20) * 100 = 2100 API calls (with out caching)

That hits the 40 requests/second restrict with lower than 2 checklist objects.

If extra info is required or extra code, let me know.

It looks like my best choice is to create a customized Person object in my CoreData mannequin for the reason that NSPersistentCloudKitContainer setup is fetching relationships for me.

Pattern Code (UITableViewCell)

public func configure(listItem: ListItem, setting: Atmosphere) {
    self.listItem = listItem
    self.setting = setting
    self.userRecordId = self.setting?.coreDataStack.creatorUserRecordID(for: listItem)
    
    self.fetchUserTask?.cancel()
    
    self.fetchUserTask = Process {
        guard let userRecordId = self.userRecordId,
              let userRecord = strive? await CKContainer.default().publicCloudDatabase.document(for: userRecordId) else {
                self.userNameLabel.textual content = "I am server poor. You may't view this info."
            return
        }
        
        if !Process.isCancelled {
            Process { @MainActor in
                self.userRecord = userRecord
                self.userNameLabel.textual content = self.userRecord?["username"]
            }
        }
    }
    
    self.contentTextView.textual content = listItem.title
    
    self.dateCreatedLabel.textual content = DateFormatter.localizedString(
        from: listItem.modifiedAt!,
        dateStyle: .medium,
        timeStyle: .brief
    )
    
    let likes = self.listItem?.likes
    self.likeButton.setTitle("(likes?.rely ?? 0)", for: .regular)
    
    if let likes = likes?.allObjects as? [Like] {
        for like in likes {
            guard let userRecordId = self.setting?.coreDataStack.creatorUserRecordID(for: like) else {
                self.likeButton.isEnabled = false
                proceed
            }
            
            if userRecordId.recordName == CKCurrentUserDefaultName {
                self.likeButton.isEnabled = false
                break
            }
        }
    }
}

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 
rooshohttps://www.roosho.com
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here


Latest Articles

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog.