A Promise wrapper for Meteor iOS
=======
This lib combines the awesome Meteor iOS lib by Martijn Walraven and Tom Lokhorst's Promise implementation Promissum. It features full promise functionality and a way to give Meteor iOS something more that just an AnyObject?
and NSError?
.
=======
Incorporating promises in meteor will become very simple:
import Promissum
import Meteor
import MeteorPromissum
let Meteor = METCoreDataDDPClient(serverURL: NSURL(string: "wss://meteor-ios-todos.meteor.com/websocket"))
Meteor.connect()
Meteor.callMethodWithNamePromise("doSomething", parameters: nil)
.then { (result: String) in
print("YAY! It worked!")
print("Result: \(result)")
}
.trap { error in
print("Oops, got an error \(error)")
}
In this example I call a Meteor method doSomething
, and expect the result type to become String
. Right now all Javascript primitives are supported: Void
, String
, Bool
and NSNumber
(for Float
, Int
and others). I plan on fixing supporting Float
's and Int
's directly instead of NSNumber
.
If you plan on more than one result type, allthough I would highly discurage, you always can use AnyObject
and cast it yourself.
When the return type doesn't match the requested one, the method will throw an MeteorError.UnexpectedResultType
. It'll also do some magic in handling some basic Meteor errors like EndpointNotFound
If you plan on returning null in Javascript, you can also use the Optional version of callMethodWithNamePromiseOptional
. This'll wrap T
in Optional<T>
, so the result would become i.e. String?
or NSNumber?
.
Meteor.callMethodWithNamePromiseOptional("doSomething", parameters: nil)
.then { (result: String?) in
if let result = result {
print("Got some result: \(result)")
} else {
print("Got null result, but method succeeded.")
}
}
.trap { error in
print("Oops, got an error \(error)")
}
Right now, all result types are inferred by the Swift compiler. So you need provide a type for T
in one these three ways:
- Save the promise result in a variable:
let promise: Promise<String, MeteorError> = Meteor.callMethodWithNamePromise(...)
- Make the type inferrable by giving the result type when returning:
func doSomePromise() -> Promise<String, MeteorError> {
return Meteor.callMethodWithNamePromise(...)
}
- Provide the type in
then
/map
/flatMap
Meteor.callMethodWithNamePromise(...)
.then { (string: String) in
}
// Or:
Meteor.callMethodWithNamePromise(...)
.map { (string: String) in
}
This structure also works for creating subscriptions:
Meteor.addSubscriptionPromise("someSubscription", parameters: ["Foo", "Bar"])
.then { subscription in
print("YAY! Subscribed")
}
.trap {
print("Meh. Got error:( \($0)")
}
Of course the Promissum lib provides a whole lot of other functions that could aggegrate you calls. For instance: wait for multiple calls:
// Wait for both a call and a subscription
whenBoth(Meteor.callMethodWithNamePromise("doSomething", parameters: nil), Meteor.addSubscriptionPromise("someSubscription", parameters: ["Foo", "Bar"]))
.then { (success: Bool, subscription: METSubscription) in
print("YAY! Both succeeded!")
}
.trap {
print("Meh, these error occurred: \($0)")
}
or map
/flatMap
your results:
let subscriptionAfterCheck = Meteor.callMethodWithNamePromise("doSomeChecking", parameters: nil)
.flatMap { (success: Bool) in
if success {
return Meteor.addSubscriptionPromise("someSubscription", parameters: ["Foo", "Bar"])
}
return Promise(error: SomeNSError)
}
Figuring you already have Meteor iOS installed, this lib depends on Promissum
. Since I only support Cocoapods for now, I highly recommend importing both via you Podfile
like this:
pod 'Meteor'
pod 'Promissum'
pod 'MeteorPromises', :git => 'https://github.com/Q42/Meteor-Promissum.git', :tag => '0.0.4'
I know, I should get my spec up at Cocoapods.
It actually only is a category file that contains some extensions. You could also just import Meteor+Promises.swift in you project.