当应用进入前台时重新加载 CloudKit 数据
Reloading CloudKit data when app comes to foreground
我正在尝试理解 CloudKit,但如果我最终将它变成一个应用程序,我将无法解决现实世界中的问题。
我有一个由 CloudKit 填充的 tableviewcontroller,工作正常。当您点击 table 视图控制器中的一个条目时,我有一个细节 viewcontroller 会被推送。 detailviewcontroller 从 CloudKit 中提取了初始 tableviewcontroller 中没有的额外数据。所有这些都工作得很好。
现在,细节viewcontroller 允许更改图像并将其保存回public 数据库。这也很好用。
我正在处理的场景是考虑多人在一个应用程序中使用这个核心功能。如果一个人上传了一张照片(覆盖其中一条记录的现有照片),如果另一个用户当前在后台运行该应用程序会怎样?如果他们打开应用程序,他们将看到他们在该页面上看到的最后一张照片,而不是新照片。所以我想在应用程序返回前台时从 CloudKit 重新加载数据,但我一定是做错了什么,因为它不起作用。使用模拟器和我的实际 phone,我可以在一台设备上更改照片,而另一台设备(模拟器或 phone)在进入前台时不会更新数据。
这是我正在使用的代码:ViewController.swift 中的第一个:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
println("viewDidLoad")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "activeAgain", name: UIApplicationWillEnterForegroundNotification, object: nil)
然后是 activeAgain 函数:
func activeAgain() {
println("Active again")
fetchItems()
self.tblItems.reloadData()
println("Table reloaded")
}
然后是 fetchItems 函数:
func fetchItems() {
let container = CKContainer.defaultContainer()
let publicDatabase = container.publicCloudDatabase
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Items", predicate: predicate)
publicDatabase.performQuery(query, inZoneWithID: nil) { (results, error) -> Void in
if error != nil {
println(error)
}
else {
println(results)
for result in results {
self.items.append(result as! CKRecord)
}
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.tblItems.reloadData()
self.tblItems.hidden = false
})
}
}
}
我尝试向 viewWillAppear 添加重新加载功能,但这并没有真正帮助:
override func viewWillAppear(animated: Bool) {
tblItems.reloadData()
}
下面是详细代码ViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "activeAgain", name: UIApplicationWillEnterForegroundNotification, object: nil)
self.imageScrollView.contentSize = CGSizeMake(1000, 1000)
self.imageScrollView.frame = CGRectMake(0, 0, 1000, 1000)
self.imageScrollView.minimumZoomScale = 1.0
self.pinBoardScrollView.maximumZoomScale = 8.0
showImage()
然后是 showImage 函数:
func showImage() {
imageView.hidden = true
btnRemoveImage.hidden = true
viewWait.hidden = true
if let editedImage = editedImageRecord {
if let imageAsset: CKAsset = editedImage.valueForKey("image") as? CKAsset {
imageView.image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
imageURL = imageAsset.fileURL
self.title = "Image"
imageView.hidden = false
btnRemoveImage.hidden = false
btnSelectPhoto.hidden = true
}
}
}
和 activeAgain 函数:
func activeAgain() {
showImage()
println("Active again")
}
这些 ViewController 在 return 时都没有从 CloudKit 重新加载数据。这就像它缓存了第一个 ViewController 的 table 数据和 DetailViewController 的图像,它正在使用它而不是下载实际的 CloudKit 数据。我很困惑,所以我想我最好试试这个论坛(我的第一个 post!)。希望我包含了足够有用的必需信息。
您的 showImage 函数正在使用 editedImage CKRecord。您是否还重新加载了该记录?否则该记录中的 Image 字段将仍然包含旧的 CKAsset。
除了在您觉得合适的时候重新加载,您还可以通过创建 CloudKit 订阅来推送更改。然后,当您的数据处于活动状态并被其他人更改时,它甚至会发生变化。
我正在尝试理解 CloudKit,但如果我最终将它变成一个应用程序,我将无法解决现实世界中的问题。
我有一个由 CloudKit 填充的 tableviewcontroller,工作正常。当您点击 table 视图控制器中的一个条目时,我有一个细节 viewcontroller 会被推送。 detailviewcontroller 从 CloudKit 中提取了初始 tableviewcontroller 中没有的额外数据。所有这些都工作得很好。
现在,细节viewcontroller 允许更改图像并将其保存回public 数据库。这也很好用。
我正在处理的场景是考虑多人在一个应用程序中使用这个核心功能。如果一个人上传了一张照片(覆盖其中一条记录的现有照片),如果另一个用户当前在后台运行该应用程序会怎样?如果他们打开应用程序,他们将看到他们在该页面上看到的最后一张照片,而不是新照片。所以我想在应用程序返回前台时从 CloudKit 重新加载数据,但我一定是做错了什么,因为它不起作用。使用模拟器和我的实际 phone,我可以在一台设备上更改照片,而另一台设备(模拟器或 phone)在进入前台时不会更新数据。
这是我正在使用的代码:ViewController.swift 中的第一个:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
println("viewDidLoad")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "activeAgain", name: UIApplicationWillEnterForegroundNotification, object: nil)
然后是 activeAgain 函数:
func activeAgain() {
println("Active again")
fetchItems()
self.tblItems.reloadData()
println("Table reloaded")
}
然后是 fetchItems 函数:
func fetchItems() {
let container = CKContainer.defaultContainer()
let publicDatabase = container.publicCloudDatabase
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Items", predicate: predicate)
publicDatabase.performQuery(query, inZoneWithID: nil) { (results, error) -> Void in
if error != nil {
println(error)
}
else {
println(results)
for result in results {
self.items.append(result as! CKRecord)
}
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.tblItems.reloadData()
self.tblItems.hidden = false
})
}
}
}
我尝试向 viewWillAppear 添加重新加载功能,但这并没有真正帮助:
override func viewWillAppear(animated: Bool) {
tblItems.reloadData()
}
下面是详细代码ViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "activeAgain", name: UIApplicationWillEnterForegroundNotification, object: nil)
self.imageScrollView.contentSize = CGSizeMake(1000, 1000)
self.imageScrollView.frame = CGRectMake(0, 0, 1000, 1000)
self.imageScrollView.minimumZoomScale = 1.0
self.pinBoardScrollView.maximumZoomScale = 8.0
showImage()
然后是 showImage 函数:
func showImage() {
imageView.hidden = true
btnRemoveImage.hidden = true
viewWait.hidden = true
if let editedImage = editedImageRecord {
if let imageAsset: CKAsset = editedImage.valueForKey("image") as? CKAsset {
imageView.image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
imageURL = imageAsset.fileURL
self.title = "Image"
imageView.hidden = false
btnRemoveImage.hidden = false
btnSelectPhoto.hidden = true
}
}
}
和 activeAgain 函数:
func activeAgain() {
showImage()
println("Active again")
}
这些 ViewController 在 return 时都没有从 CloudKit 重新加载数据。这就像它缓存了第一个 ViewController 的 table 数据和 DetailViewController 的图像,它正在使用它而不是下载实际的 CloudKit 数据。我很困惑,所以我想我最好试试这个论坛(我的第一个 post!)。希望我包含了足够有用的必需信息。
您的 showImage 函数正在使用 editedImage CKRecord。您是否还重新加载了该记录?否则该记录中的 Image 字段将仍然包含旧的 CKAsset。
除了在您觉得合适的时候重新加载,您还可以通过创建 CloudKit 订阅来推送更改。然后,当您的数据处于活动状态并被其他人更改时,它甚至会发生变化。