Search code examples
swiftcloudkittvos

Test for presence or absence of a record in CloudKit with Swift 2


I am writing a tvOS app. I want to test to see if there's a record in CloudKit database.

I am trying to do this by seeing if there is a record with an specific eventID.

Ideally, I want to call a function that returns true or false:

if isEventInWatchListFile(eventID) {
 // ... do things
}

What I have tried is the following:

 var results = [AnyObject]()
 var onList:Bool?

 . . .

    func isEventInWatchListFile(eventID: String) -> Bool {

        let container = CKContainer(identifier: "the container")
        let privateDB = container.privateCloudDatabase

        let predicate = NSPredicate(format: "eventID == %@",eventID)
        let query = CKQuery(recordType: "UserWatchlist", predicate: predicate)

        privateDB.performQuery(query, inZoneWithID: nil) { results , error in
            guard let results = results else {
                // error handler to come
                return
            }

            if results[0]["eventID"] != nil {

              self.onList = true

            } else {

              self.onList = false
            }
        }

        return self.onList!
    }

This crashes with "fatal error: unexpectedly found nil while unwrapping an Optional value". I think this is because onList is locked up in a closure. I have two questions:

1) Is it possible to pass out onList to the return statement, and, if so, how? I've read up on closures in Swift, but not sure how to apply what I've read.

2) Is there a better way to do the test I want to do? My approach seems clunky to me.

I am very new to iOS and Swift. Any help greatfully received.


Solution

  • If I read your code correctly, your statement

    return self.onList!
    

    will always fail, because you are setting the value asynchronously and the default (nil) value is passed to the return before the asynchronous operation ends.

    Instead of func isEventInWatchListFile(eventID: String) -> Bool you could create something like func doSomethingEventInWatchListFile(eventID: String, funcToRunIfEventIsInTheWatchList: () -> Void). Then you would have:

            if results[0]["eventID"] != nil {
    
              funcToRunIfEventIsInTheWatchList()
    
            } else ...