如何将 CloudKit 记录数据从“TableView-Controller B”传递到“View-Controller C”?
Posted
技术标签:
【中文标题】如何将 CloudKit 记录数据从“TableView-Controller B”传递到“View-Controller C”?【英文标题】:How to pass the CloudKit records data from "TableView-Controller B" to "View-Controller C"? 【发布时间】:2017-07-01 20:15:21 【问题描述】:我已经从我的CloudKit
获得记录数据并成功显示在TableViewController-B
,但是我如何将CloudKit's records(strings, images)
传递给下一个ViewController-C
?
ps. not tableViewcontroller-C
我的第一个TableViewController-B
import UIKit
import CloudKit
class BTableViewControoler: UITableViewController
var myclouds:[CKRecord] = []
var imageCache = NSCache<CKRecordID, NSURL>()
var recordType: String!
override func viewDidLoad()
super.viewDidLoad()
recordsFromCloud()
func recordsFromCloud()
let cloudContainer = CKContainer.default()
let publicDatabase = cloudContainer.publicCloudDatabase
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: recordType, predicate: predicate)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let queryOperation = CKQueryOperation(query: query)
queryOperation.desiredKeys = ["name", "address", "GpNumber"]
queryOperation.queuePriority = .veryHigh
queryOperation.resultsLimit = 50
queryOperation.recordFetchedBlock = (record) -> Void in
self.myclouds.append(record)
queryOperation.queryCompletionBlock = (cursor, error) -> Void in
if let error = error print("Failed data - \(error.localizedDescription)")
return
print("Successfully data")
publicDatabase.add(queryOperation)
//fetchRecords End
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return myclouds.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MainCell
let newInFo = myclouds[indexPath.row]
cell.mainLabel.text = newInFo.object(forKey: "name") as? String
cell.mainNumber.text = newInFo.object(forKey: "GpNumber") as? String
cell.mainLocation.text = newInFo.object(forKey: "address") as? String
cell.mainImage.image = UIImage(named: "photoalbum")
//get image
if let imageFileURL = imageCache.object(forKey: myclouds.recordID)
if let imageData = try? Data.init(contentsOf: imageFileURL as URL)
cell.mainImage?.image = UIImage(data: imageData)
else
let publicDatabase = CKContainer.default().publicCloudDatabase
let fetchRecordsImageOperation = CKFetchRecordsOperation(recordIDs: [newInFo.recordID])
fetchRecordsImageOperation.desiredKeys = ["image"]
fetchRecordsImageOperation.queuePriority = .veryHigh
fetchRecordsImageOperation.perRecordCompletionBlock =
(record, recordID, error) -> Void in
if let error = error
print("Failed image:\(error.localizedDescription)")
return
if let newinfoRecord = record
OperationQueue.main.addOperation()
if let image = newinfoRecord.object(forKey: "image")
let imageAsset = image as! CKAsset
if let imageData = try? Data.init(contentsOf: imageAsset.fileURL)
cell.mainImage.image = UIImage(data: imageData)
self.imageCache.setObject(imageAsset.fileURL as NSURL, forKey: newInFo.recordID)
//record end
publicDatabase.add(fetchRecordsImageOperation)
//else end
return cell
//cell end
//Segue To Next View
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetailSegue"
if let indexPath = tableView.indexPathForSelectedRow
let toDetailVC = segue.destination as! showDetailVC
toDetailVC.DisData = newinfo[indexPath.row]
我的 ViewController-C
import UIKit
import CloudKit
class showDetailVC: UIViewController
@IBOutlet weak var detailpic: UIImageView!
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var infoLabel: UILabel!
@IBOutlet weak var mynumberLabel: UILabel!
var DisData: CKRecord?
var getType: String!
override func viewDidLoad()
super.viewDidLoad()
detailpic.image = UIImage(named: "photoalbum")
infoLabel.text = DisData?.object(forKey: "address") as? String
nameLabel.text = DisData?.object(forKey: "name") as? String
mynumberLable.text = DisData?.object(forKey: "GpNumber") as? String
我使用var DisData
从tableViewController-B
获取CKRecord
但它不适用于DisData?.object(forKey: "name") as? String
的方法
并且图像也无法弄清楚如何显示它。
我应该再次在ViewController-C
中使用UITableViewController-B's
func recordsFromCloud
吗???或任何其他获得Cloudkit's records
的聪明方法,请帮忙。
【问题讨论】:
【参考方案1】:创建一个名为 selectedRecord 的变量
var selectedRecord: CKRecord!
添加委托方法 didSelectRowatindexPath
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: IndexPath)
selectedRecord = myclouds[indexPath.row]
performSegueWithIdentifier("showDetailSegue", sender: nil)
把prepareforsegue改成这个
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetailSegue"
let toDetailVC = segue.destination as! showDetailVC
toDetailVC.DisData = selectedRecord
在showDetailVC
中将DisData的类型从CKRecord?
改为CKRecord!
var DisData: CKRecord!
如果你想得到你的钥匙,请声明queryOperation
外面 recordsFromCloud()
然后,在showDetailVC
中为Keys创建一个变量
var forKeys: [String]!
然后将以下行添加到prepareforsegue
toDetailVC.forKeys = queryOperation.desiredKeys
【讨论】:
它仍然不工作,没有错误但不显示任何东西,仍在努力。谢谢你的想法 它现在正在工作。我需要使queryOperation.desiredKeys = ["name", "address", "GpNumber"]
匹配showDetailVC
字符串就是这样,但图像无法显示在showDetailVC
我想需要更改代码detailpic.image = UIImage(named: "photoalbum")
但不知道该怎么做,你能修复代码?非常感谢您的帮助。
能不能再解释一下,queryOperation.desiredKeys = ["name", "address", "GpNumber"] 匹配showDetailVC是什么意思
是的!在我的项目中,我的showDetailVC
'infoLabel.text = DisData?.object(forKey: "Gpaddress") as? String`nameLabel.text = DisData?.object(forKey: "GpName") as? String
mynumberLable.text = DisData?.object(forKey: "Gpnumber") as? String
forKeyes 和我之前发的不一样,因为我想让我的问题代码更容易被助手阅读。
所以您想将键 queryOperation.desireyKeys 传递给 showDetailVC?以上是关于如何将 CloudKit 记录数据从“TableView-Controller B”传递到“View-Controller C”?的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 从 Cloudkit 公共数据库中获取所有记录