Syntactic sugar to convert block based callbacks into RxSwift Observables
Are you tied down to a callback based API, wishfully looking on at RxSwift? RxParseCallback makes adopting RxSwift in your project way easier!
It let's you turn
API.doTheThing { [weak self] thing in
guard strongSelf = self else { return }
strongSelf.thing.value = thing
}
into
API.rx.doTheThing.bindTo(self.thing)
✨ Isn't that beautiful?
Here's a real life example, that wraps the Facebook iOS SDK's login function
func login(withReadPermissions permissions: [String] = ["email", "public_profile", "user_friends"]) -> Observable<FBSDKLoginManagerLoginResult> {
return ParseRxCallbacks.createWithCallback({ observer -> Void in ⬅️ is interesting
FBSDKLoginManager().logIn(withReadPermissions: permissions,
from: nil,
// so is ⬇️
handler: ParseRxCallbacks.parseUnwrappedOptionalCallback(observer))
})
}
The handler
param is of type (FBSDKLoginManagerLoginResult?, Error?) -> Void
, and calling ParseRxCallbacks.parseUnwrappedOptionalCallback(observer)
returns (T?, Error?) -> Void
. Which conforms to the handler's (FBSDKLoginManagerLoginResult?, Error?) -> Void
(the compiler infers T
to be FBSDKLoginManagerLoginResult
) #connectingmagic
RxParseCallback
is tiny — it's just one file — 55 lines
These are the currently supported methods of installation
Create a Package.swift
file.
import PackageDescription
let package = Package(
name: "MyProjectThat<3sRx",
targets: [],
dependencies: [
.Package(url: "https://github.com/AndrewSB/RxParseCallback.git", majorVersion: 1)
]
)
$ swift build
Add this to Cartfile
github "AndrewSB/RxParseCallback" ~> 1.0
$ carthage update
First make sure you have access to RxSwift
in your project.
Then you can grab the Source/RxParseCallback.swift file, and drag it into your project.
func createWithCallback(_ callback: @escaping ((AnyObserver<T>) -> Void)) -> Observable<T>
Allows you to create an observable from a block. This is the meat of this µ Library. Inside the callback, you get a AnyObserver<T>
, to which you can send any events you want propogated through the returned Observable<T>
Most APIs have callbacks that look something like (T?, Error?)
. So there are three functions that help parsing data out of that common pattern.
func parseCallback<T>(_ observer: AnyObserver<T>) -> (T, Error?)
This works for callbacks that have callbacks that return (T, Error?)
. So you pass in the AnyObserver<T>
given to you from the createWithCallback
, and it satisfies the type requirment of (T, Error?)
func parseOptionalCallback<T>(_ observer: AnyObserver<T?>) -> (T?, Error?)
Same as above, but it accepts callbacks that pass in (T?, Error?)
instead.
func parseUnwrappedOptionalCallback<T>(_ observer: AnyObserver<T>) -> (T?, Error?)
Same as above, but it also goes ahead and (safely) unwraps the T?
into a T
if the error was nil.
If both the error and T
are nil
, it sends an error through on the Observable, called noObjectNorErrorIncluded
RxParseCallback is under the MIT license. See the LICENSE file for more info.