How to model my CloudKit data

眉间皱痕 提交于 2021-02-07 10:07:36

问题


In my app I decided to use CloudKit as my sync-backend. My app is not about projects, but for simplicity let's say so...

So... In my app users will have multiple projects. Each of those contains multiple entities associated with that project. For example tasks, but also reminders and so on.

All this data will be stored in the users private database. Nothing will be in the public database.

Now a user can have multiple projects.

My first question: Should each project be in it's own CKRecordZone? I didn't see a benefit of doing so?!? Can somebody explain to me what the benefit of having multiple record zones is? So currently all the projects are in ONE zone.

Next, I'd like the user to be able to share ALL his data with somebody else. The problem currently is that as the project is currently the root record in my database, I'd need to create a share for each of those projects, right?!? In my app it doesn't really make sense to invite users to each project separately, so I'd like to somehow archive that. Would it make sense, to create a new root-record that has the projects as childs and then the user would invite somebody to this new root-record?

Final question... is there something like a Sack-Team or so to ask questions about CloudKit? Would seem to be easier than starting a new question here on stackoverflow as my questions are quite specific to my app...


回答1:


Good questions. Here's what I recommend.

Zone

First off, you only need one zone. But to share records from it, it must be a custom zone (you can't use the _defaultZone). Honestly, zones in CloudKit are weird and I'm not sure why they exist. Apple seems to be passing database sharding challenges on to their developers. :)

Create a custom zone like this:

let customZone = CKRecordZone(zoneName: "projectZone")

// Save the zone in the private database
let container = CKContainer(identifier: "...")
let privateDB = container.privateCloudDatabase

privateDB.save(customZone){ zone, error in
  if let error = error{
    print("Zone creation error: \(String(describing: error))")
  }else{
    print("Zone created: \(zone)")
  }
}

Record Types

I would create record types like this:

  • Project (root record)
  • Task
  • Reminder

Sharing

One of the nice things about CloudKit is that you can create relationships between records. This means you can automatically share the children of a root record without having to set up CKShares for each child individually.

Below is an example that walks through how you would set those fields on the records.

//Get a reference to the zone you created
let zoneID = CKRecordZoneID(zoneName: "projectZone", ownerName: CKCurrentUserDefaultName)

//Create a project record
let projectRecord = CKRecord(recordType: "Project", zoneID: zoneID)
projectRecord.setValue("My Cool Project", forKey: "name")

//Create a task record
let taskRecord = CKRecord(recordType: "Task", zoneID: zoneID)
taskRecord.setValue("My Task Name", forKey: "name")

//Create an association between the task and its parent project
let parentReference = CKReference(record: projectRecord, action: .deleteSelf)
taskRecord.setValue(parentReference, forKey: "project")

//When sharing, allow this task to be automatically shared if the parent project is shared
taskRecord.setParent(projectRecord)

All of this presupposes that you create fields for your Project and Task record types of name (type: String). Then on the Task record type, you would have a project field of type Reference.

I hope that helps and will at least get you started. I'm not aware of a CloudKit Slack channel, but if you hear about one, let me know! :)



来源:https://stackoverflow.com/questions/52058053/how-to-model-my-cloudkit-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!