是否可以创建一个 class 来模仿 CKRecord?
Is it possible to create a class that will imitate a CKRecord?
所以我正在创建一个应用程序,它将大量重复使用一些记录,所以我想出了一个主意:
import CloudKit
class Class: CKRecord {
override init(recordType: String = "Class") {
super.init(recordType: recordType)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var name: String? {
get {
return value(forKey: "name") as? String
} set {
setValue(newValue!, forKey: "name")
}
}
var classDescription: String? {
get {
return value(forKey: "description") as? String
} set {
setValue(newValue!, forKey: "description")
}
}
var posts: [CKReference]? {
get {
return value(forKey: "posts") as? [CKReference]
} set {
setValue(newValue!, forKey: "posts")
}
}
var users: [CKReference]? {
get {
return value(forKey: "users") as? [CKReference]
} set {
setValue(newValue!, forKey: "users")
}
}
}
后来我在 tableViewCONtroler 中创建了一个函数,当执行 viewDidLoad 和刷新 tableView 时 运行(getAllRecords() 是一个 returns 所有 class 记录的函数这个cas并且它有效):
func refresh() {
queue.addOperation {
self.database.getAllRecords(withRecordType: "Class", withDesiredKeys: ["posts", "name"], sortForkey: "name", ascending: false, withResultLimit: CKQueryOperationMaximumResults, operations: 1){ records, error in
if error == nil {
self.classes = records as! [Class]
OperationQueue.main.addOperation {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
}
}
然后我创建了单元格:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "class", for: indexPath)
// Configure the cell...
cell.textLabel?.text = (classes[indexPath.row].name)!
return cell
}
现在的问题是我收到一条错误消息:
fatal error: Down-casted Array element failed to match the target type
2016-12-23 22:44:38.681456 EdApp[4524:2186068] fatal error: Down-casted Array element failed to match the target type
我做错了什么?它甚至可以工作吗?谢谢!
getAllRecords 将 return 一个 CKRecords 数组。它不会是 Class 类型。 (这对于 class 来说是一个非常糟糕的名称)您不能将它强制转换为 Class。
您可以将其映射到您的 Class,但这并不容易。您需要从 CKRecord 获取编码的系统字段并使用编码器创建您的 class。
我认为将 CKRecord 设为 Class 的 属性 并为接受该 CKRecord 的 Class 创建一个 init 会更容易。然后,您可以将您的记录映射到 Class,例如:
self.classes = records.map { Class(记录:$0)}
我可以建议你看一下 https://github.com/evermeer/EVCloudKitDao 它有一种机制可以自动将 class 转换为 CKRecord 并返回。它将消除大量用于获取和设置属性的管道代码。
所以我正在创建一个应用程序,它将大量重复使用一些记录,所以我想出了一个主意:
import CloudKit
class Class: CKRecord {
override init(recordType: String = "Class") {
super.init(recordType: recordType)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var name: String? {
get {
return value(forKey: "name") as? String
} set {
setValue(newValue!, forKey: "name")
}
}
var classDescription: String? {
get {
return value(forKey: "description") as? String
} set {
setValue(newValue!, forKey: "description")
}
}
var posts: [CKReference]? {
get {
return value(forKey: "posts") as? [CKReference]
} set {
setValue(newValue!, forKey: "posts")
}
}
var users: [CKReference]? {
get {
return value(forKey: "users") as? [CKReference]
} set {
setValue(newValue!, forKey: "users")
}
}
}
后来我在 tableViewCONtroler 中创建了一个函数,当执行 viewDidLoad 和刷新 tableView 时 运行(getAllRecords() 是一个 returns 所有 class 记录的函数这个cas并且它有效):
func refresh() {
queue.addOperation {
self.database.getAllRecords(withRecordType: "Class", withDesiredKeys: ["posts", "name"], sortForkey: "name", ascending: false, withResultLimit: CKQueryOperationMaximumResults, operations: 1){ records, error in
if error == nil {
self.classes = records as! [Class]
OperationQueue.main.addOperation {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
}
}
然后我创建了单元格:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "class", for: indexPath)
// Configure the cell...
cell.textLabel?.text = (classes[indexPath.row].name)!
return cell
}
现在的问题是我收到一条错误消息:
fatal error: Down-casted Array element failed to match the target type 2016-12-23 22:44:38.681456 EdApp[4524:2186068] fatal error: Down-casted Array element failed to match the target type
我做错了什么?它甚至可以工作吗?谢谢!
getAllRecords 将 return 一个 CKRecords 数组。它不会是 Class 类型。 (这对于 class 来说是一个非常糟糕的名称)您不能将它强制转换为 Class。
您可以将其映射到您的 Class,但这并不容易。您需要从 CKRecord 获取编码的系统字段并使用编码器创建您的 class。
我认为将 CKRecord 设为 Class 的 属性 并为接受该 CKRecord 的 Class 创建一个 init 会更容易。然后,您可以将您的记录映射到 Class,例如: self.classes = records.map { Class(记录:$0)}
我可以建议你看一下 https://github.com/evermeer/EVCloudKitDao 它有一种机制可以自动将 class 转换为 CKRecord 并返回。它将消除大量用于获取和设置属性的管道代码。