Reputation: 1978
This is actually a Swift Language type of question
I am using Firebase to read/write data
I would like to design a routine in swift that will return eventually. The caller must wait for the routine to complete, so its not a asynchronous, background call actually. Ideally the caller should also be able to:
Determine success or error returns and also process return values
Timeout on the wait if the calling function is taking too long
Inside the function the hold-up is merely an event to Firebase . For example:
func eventuallyReturnFirebase() {
//some stuff
someObj.observeEventType(.ChildAdded, withBlock: {
snapshot in
print("\(snapshot.key) -> \(snapshot.value)")
if (snapshot.key == "foo") {
// we found value for foo
}
if (snapshot.key == "bar") {
// we found value for bar
}
})
//now we can return foo and bar back to caller or some error if we did not
}
Can someone highlight what the Swift language offers in terms of designing such a function and how must the caller be used as well? Hopefully also addressing the 2 ideal conditions as well
Upvotes: 2
Views: 363
Reputation: 1431
If you need to write synchronous wrapper around asynchronous call - you can use semaphores.
I.e. you can write something like this (I'm omiting certain things like types information, so it's kind of swift-like pseudo-code, but this should be enough to get the idea):
func eventuallyReturnFirebase() {
let semaphore = dispatch_semaphore_create(0) //creating a "closed" semaphore
var foo, bar //variables that will hold your return values
someObj.observeEventType(.ChildAdded, withBlock: {
snapshot in
print("\(snapshot.key) -> \(snapshot.value)")
if (snapshot.key == "foo") {
// we found value for foo
}
if (snapshot.key == "bar") {
// we found value for bar
}
//setting values for foo and bar
foo = ...
bar = ...
dispatch_semaphore_signal(semaphore) // incrementing semaphore counter
})
let timeout = dispatch_time(DISPATCH_TIME_NOW, DefaultTimeoutLengthInNanoSeconds)
if dispatch_semaphore_wait(semaphore, timeout) != 0 { // waiting until semaphore conter becomes greater than 0
print("timed out")
}
return foo, bar
}
Upvotes: 2
Reputation: 31016
I'd suggest looking at NSCondition
as a way of getting both results you want.
The routine that's called starts a timer, starts an asynchronous process, then waits on a condition before returning. The condition is signalled as either the last action of the asynchronous process or by the firing of the timer.
Once the signal allows the routine to continue, it decides whether it was terminated because of time or has something to return.
Upvotes: 1