Search code examples
ioscloudkit

CloudKit perform


i have an issue with CloudKit in my App. The Data loads perfectly when the view is loaded initially. But when I "Pull to Refresh" I get a "fatal error: Index out of range". Strange thing is that there is no difference in Code (at least for me). When I pull to refresh, it does not even run "perform" ("B" does not get printed). Debugger does not show any error.

Do you have a clue?

Thanks in advance!

Nico

viewDidLoad:

loadCloudData()

handlePullToRefresh:

func handlePullToRefresh() {
    loadCloudData()
}

loadCloudData:

func loadCloudData() {
        DispatchQueue.main.async {
            self.showMessage(titleText: NSLocalizedString("Loading ...", comment: "SwiftMessage Loading Title"), text: NSLocalizedString("Loading PixelCodes from Cloud", comment: "SwiftMessage Loading Title"), backgroundColor: UIColor.tileYellow(), textColor: UIColor.darkGray, image: #imageLiteral(resourceName: "cloud"))
        }

        dataCloud = [CKRecord]()
        let query = CKQuery(recordType: PixelCodeType.recordType, predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
        query.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]

        print("A")

        databasePublic.perform(query, inZoneWith: nil) { (results:[CKRecord]?, error:Error?) in
            print("B")
            if error != nil {
                print("PixelCode from Cloud not Loaded!\n\(error!.localizedDescription)")
                self.couldLoadCloadData = false
                DispatchQueue.main.async {
                    SwiftMessages.hideAll()

                    if self.refreshControl != nil {
                        if self.refreshControl!.isRefreshing {
                            self.refreshControl!.endRefreshing()
                        }
                    }

                    //"Cloud" active
                    self.segmentedControl.setEnabled(true, forSegmentAt: 1)
                }
                self.handleError(title: NSLocalizedString("Error!", comment: "SwiftMessage error title"), text: error!.localizedDescription, errorTitle: "Cloud Loading Error:loadCloudData()", error: error)
            } else {
                if let data = results {
                    print("pixelCodes updated")
                    self.dataCloud = data

                    if results!.isEmpty {
                        self.couldLoadCloadData = true
                        self.isCloudDataLoaded = false
                    } else {
                        self.couldLoadCloadData = true
                        self.isCloudDataLoaded = true
                    }

                    self.uploadTimes()

                    DispatchQueue.main.async {
                        if self.refreshControl != nil {
                            if self.refreshControl!.isRefreshing {
                                self.refreshControl!.endRefreshing()
                            }
                        }
                        SwiftMessages.hideAll()

                        //"Cloud" active
                        self.segmentedControl.setEnabled(true, forSegmentAt: 1)

                        self.tableView.reloadData()
                    }
                }
            }
        }
    }

Solution

  • The first thing that your loadCloudData function does is set the dataCloud array to an empty array, but you don't call reloadData on the tableview so the number of items in the array and the number of items that the tableview thinks is in the array is different.

    You should either call reloadData after you clear the array or not clear the array.