CloudKit Fetch a Record

In this lesson, you learn how to perform the CloudKit operation that fetch a record from the CloudKit’s public database and display it in a textView. Here is a QuickTime movie of the CloudKit operation in action.

caution Code presented on this page assume you are using Xcode 6.4 and Swift version 1.2. So if you are using a newer version of Swift, it may produce errors. Fix them by using Xcode’s Fix-it tool. I assume you are a registered member of Apple’s iOS Developer Program, and you have a real iPhone/iPad device to test the CloudKit code presented here.

Modify The Main View

The first thing you have to do is modify the storyboard scene and its class file so they look like this:

cloudkit-figure7-0

Next, reconnect the Find button to the Find() function, reset the Main View Controller scene’s constraints, and enter this code in the Find() function:

@IBAction func find() {
        // Dismiss the keyboard
        itemName.resignFirstResponder()

        if thisApp.userSignedIn == false {
            // The app user's iCloud account is not authenticated
            textView.text = "iCloud is not available.\n\nPlease do the following:\n\n" +
                "1. Sign into your iCloud account\n" +
                "2. Turn on iCloud Drive via the Settings app\n" +
            "3. Relaunch the app"

            // Don't execute code below this if block
            return
        }

        if itemName.text.isEmpty {
            textView.text = "The item name is required."
            return
        }

        var photoUrl: NSURL!
        let item = DatabaseHeleper()
        textView.text = "Searching..."

        // Setup a query
        let predicate = NSPredicate(format: "itemName BEGINSWITH %@", itemName.text)
        let query = CKQuery(recordType: "Item", predicate: predicate)

        // Execute the query
        db.performQuery(query, inZoneWithID: nil) { results, error in
            if (error != nil) {
                NSOperationQueue.mainQueue().addOperationWithBlock {
                    self.textView.text = "Search error: \(error.localizedDescription)"
                }
            } else {
                if results.count == 0 {
                    // The query returned no records, inform the user in the textView
                    NSOperationQueue.mainQueue().addOperationWithBlock {
                        self.textView.text = "\(results.count) record found for this item.\n"
                        self.imageView.image = nil
                    }
                    return
                }

                // The query returned one or more records, create an array for them
                var listItems = [DatabaseHeleper]()

                for record in results {
                    // Create an item object from the DatabaseHelper class
                    let item = DatabaseHeleper()

                    // Put the CKAsset in a constant
                    let asset: CKAsset = record.valueForKey("itemImage") as! CKAsset

                    // Extract the image from the asset and put it in a constant
                    let photo = UIImage(contentsOfFile: asset.fileURL.path!)

                    // Set the item object's properties
                    item.itemName = record.valueForKey("itemName") as! String
                    item.itemPhoto = photo!

                    // Add the itema object in the listItems array
                    listItems.append(item)

                    // On the main thread, display item name and photo in the view's controls
                    NSOperationQueue.mainQueue().addOperationWithBlock {
                        self.itemName.text = item.itemName
                        self.imageView.image = item.itemPhoto
                        self.textView.text = "\(results.count) record found for this item.\n"
                    }
                }
            }
        }
}

That’s it! Comments are welcomed! 🙂