diff --git a/CHANGELOG.md b/CHANGELOG.md index cf34102..8ef1907 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -140,4 +140,10 @@ * Bumps RxSwift dependency version to 6.x.x (6.9.0 at the time of the release) by @alexvbush * Adds Swift Package Manager (SPM) setup by @alexvbush -* Improves CocoaPods and Carthage setup by @alexvbush \ No newline at end of file +* Improves CocoaPods and Carthage setup by @alexvbush + +### Version 1.1.0 + +* Adds convenience helpers for interoperating async/await with the RxSwift backbone: `Single.fromAsync` / `Observable.fromAsync` to drop an `async` call into an Rx chain, `Task` lifecycle-cancellation helpers (`cancelOnDeactivate(interactor:)`, `cancelOnStop(_:)`, `cancel(with:)`), and async `Workflow` steps (`onAsyncStep` on the root workflow and on `Step`) (#51) +* Makes Swift Package Manager the canonical build and moves the Carthage Xcode project under `ios/` so it no longer shadows `Package.swift` at the repo root (#55) +* CI: resolves the iOS simulator at runtime instead of pinning a model name (#54), and restricts the workflow token to read-only (#52) diff --git a/README.md b/README.md index 2372f11..5213001 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,52 @@ When you integrate RIBs into your project, it will automatically bring the follo These dependencies are automatically managed by your chosen package manager and will be resolved to compatible versions. +## async/await Interop with RxSwift + +RxSwift is the backbone of RIBs. These are convenience helpers for interoperating with Swift's `async`/`await` from inside the existing Rx lifecycle and workflow model — they let an `async` call drop into an Rx chain, bind a `Task` to a RIB's lifecycle, and add `async` steps to a `Workflow`, all without leaving Rx. + +### Calling an async function from an Rx chain + +`Single.fromAsync` and `Observable.fromAsync` wrap an `async` call as a cold Rx sequence, so it composes with the operators you already use. The work starts on subscription, and its `Task` is cancelled when the subscription is disposed: + +```swift +someObservable + .flatMapLatest { id in + Single.fromAsync { try await service.fetch(id) } + } + .observe(on: MainScheduler.instance) + .subscribe(onNext: { ... }) + .disposeOnDeactivate(interactor: self) +``` + +### Binding a Task to a RIB lifecycle + +When you do reach for a bare `Task`, these `Task` helpers cancel it when a RIB scope ends, mirroring the existing `Disposable.disposeOnDeactivate` / `disposeOnStop` / `disposeWith` methods: + +```swift +Task { try await work() }.cancelOnDeactivate(interactor: self) +Task { try await work() }.cancelOnStop(worker) +Task { try await work() }.cancel(with: workflow) +``` + +A `Task` starts running as soon as it's created, so these helpers only cancel it later — they don't delay or prevent it from starting. If the scope is already inactive, the task is cancelled right away. + +### Async steps in a Workflow + +`onAsyncStep` is a convenience over `onStep` that lets a step's work be `async`, on both the root `Workflow` and any `Step`. Async and Rx steps interleave freely, and the chain still ends in a single `subscribe(...).disposeOnDeactivate(...)`: + +```swift +workflow + .onStep { rootItem in rootItem.waitForLogin() } // Rx step + .onAsyncStep { loggedInItem, _ in // async step + (loggedInItem, try await service.fetchClient(id: 42)) + } + .onStep { item, client in item.routeToClientDetails(client) } + .commit() + .subscribe(rootActionableItem) + .disposeOnDeactivate(interactor: self) +``` + ## Related projects If you like RIBs, check out other related open source projects from our team: diff --git a/RIBs.podspec b/RIBs.podspec index 38f8ecd..83e3dc4 100644 --- a/RIBs.podspec +++ b/RIBs.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RIBs' - s.version = '1.0.0' + s.version = '1.1.0' s.summary = 'Uber\'s cross-platform mobile architecture.' s.description = <<-DESC RIBs is the cross-platform architecture behind many mobile apps at Uber. This architecture framework is designed for mobile apps with a large number of engineers and nested states. diff --git a/RIBs/Info.plist b/RIBs/Info.plist index 4c0d218..a5ae6f9 100644 --- a/RIBs/Info.plist +++ b/RIBs/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass