ios - 当应用程序进入前台时重新加载 CloudKit 数据

标签 ios swift ios8 cloudkit

我正在尝试了解 CloudKit,但如果我最终将其转变为应用程序,我在解决现实问题时遇到了问题。

我有一个由 CloudKit 填充的 tableviewcontroller,它工作得很好。我有一个详细 View Controller ,当您点击 TableView Controller 中的条目之一时会推送该 Controller 。 DetailViewController 从 CloudKit 中提取初始 TableViewController 中不存在的附加数据。所有这些都工作得很好。

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

我正在处理的场景是考虑这个核心功能被多人在应用程序中使用。如果一个人上传照片(覆盖其中一条记录的现有照片),如果另一个用户当前在后台运行该应用程序,会发生什么情况?如果他们打开应用程序,他们将看到他们在该页面上看到的最后一张照片,而不是新照片。所以我想当应用程序返回前台时从 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")
}

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

最佳答案

您的 showImage 函数正在使用editedImage CKRecord。您是否也重新加载了该记录?否则,该记录中的 Image 字段仍将包含旧的 CKAsset。

除了在您感觉合适的时候重新加载之外,您还可以通过创建 CloudKit 订阅来推送更改。然后,当您的数据处于事件状态并被其他人更改时,您的数据甚至会发生更改。

关于ios - 当应用程序进入前台时重新加载 CloudKit 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30060110/

相关文章:

json - 在 Swift 中使用大缩进调用 json

ios - 使用数组中的字符串淡入/淡出标签

ios - 发送到不可变对象(immutable对象)的变异方法?

ios - 实时更新 UserDefaults 更改

swift - Carthage:打开模块的导入文件 * 权限被拒绝

swift - 对已被自定义 View 替换的 NSMenuItem 应用约束

objective-c - uitableviewcell 分隔符在 ios 8 中移动

ios - 如何将 Storyboard 中的多个按钮连接到一个 Action ?

iphone - 使用 UIPickerView 而不是 UITextView

ios - 下载前检查 NSURL 的资源是否存在