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.
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 ...