当应用程序到达前台时重新加载CloudKit数据

时间:2015-05-05 18:02:57

标签: ios swift ios8 cloudkit

我试图了解CloudKit,但如果我最终将其变成了应用程序,我就会遇到解决现实问题的问题。

我有一个由CloudKit填充的tableviewcontroller,工作正常。我有一个detailviewcontroller,当你点击tableview控制器中的一个条目时,它会被推送。 detailviewcontroller从CloudKit中提取了初始tableviewcontroller中没有的其他数据。所有这一切都非常好。

现在,detailviewcontroller允许更改图像并将其保存回公共数据库。这也很好。

我正在处理的场景是考虑多个人在应用中使用的这个核心功能。如果一个人上传照片(覆盖其中一个记录的现有照片),如果另一个用户当前在后台拥有该应用程序会发生什么?如果他们打开应用,他们会看到他们在该页面上看到的最后一张照片,而不是新照片。所以我想在应用程序回到前台时从CloudKit重新加载数据,但我一定做错了,因为它不能正常工作。使用模拟器和我的实际手机,我可以在一台设备上更改照片,而另一台设备(模拟器或手机)在进入前台时不会更新数据。

以下是我使用的代码:首先在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()
}

现在这里是DetailViewController.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")
}

这些ViewControllers在返回时都不会从CloudKit重新加载数据。就像它缓存了第一个ViewController的表数据和DetailViewController的图像一样,它使用它而不是下载实际的CloudKit数据。我很难过,所以我想我最好试试这个论坛(我的第一篇文章!)。希望我包含足够的必要信息以便有用。

1 个答案:

答案 0 :(得分:1)

您的showImage函数正在使用editedImage CKRecord。你还重装了那张唱片吗?否则,该记录中的Image字段仍将包含旧的CKAsset。

除了在您感觉正确的时刻重新加载之外,您还可以通过创建CloudKit订阅来推动更改。然后,当数据处于活动状态并由其他人更改时,您的数据甚至会发生变化。