diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml deleted file mode 100644 index 3e840cb..0000000 --- a/.github/workflows/android.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: CI Android - -on: [push, pull_request] - -jobs: - build: - name: JDK ${{ matrix.java_version }} - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./android - strategy: - matrix: - # TODO Add 9, 10, 11, 12, and 13 after Kotlin 1.3.60 - java_version: [11] - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install JDK - uses: actions/setup-java@v2 - with: - distribution: 'zulu' - java-version: ${{ matrix.java_version }} - - name: Install Android SDK - uses: malinskiy/action-android/install-sdk@release/0.1.1 - - name: Gradle Wrapper Validation - uses: gradle/wrapper-validation-action@v1 - - name: Configure Gradle - # Gradle configuration install deps - run: ./gradlew help - - name: Spot check - run: ./gradlew spotlessCheck --stacktrace - - name: Build Project - run: ./gradlew assemble --stacktrace - - name : Testing - run: ./gradlew test --stacktrace - - name: Final Checks - run: ./gradlew check --stacktrace - - name: Upload snapshot - run: ./gradlew publish -PmavenCentralUsername="${{ secrets.SonatypeUsername }}" -PmavenCentralPassword="${{ secrets.SonatypePassword }}" - if: success() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request' && matrix.java_version == '11' diff --git a/.github/workflows/iOS.yml b/.github/workflows/iOS.yml new file mode 100644 index 0000000..d0929ad --- /dev/null +++ b/.github/workflows/iOS.yml @@ -0,0 +1,50 @@ +name: CI iOS + +on: [push, pull_request] + +jobs: + build-and-test: + runs-on: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.1' + + - name: Install CocoaPods + run: gem install cocoapods + + - name: Install pod dependencies + working-directory: ./Example + run: pod install || pod install --repo-update + + - name: Run tests with coverage + working-directory: ./Example + run: | + xcodebuild \ + -workspace RIBs.xcworkspace \ + -scheme RIBs-Example \ + -sdk iphonesimulator \ + -destination 'platform=iOS Simulator,name=iPhone 16' \ + -enableCodeCoverage YES \ + clean test + + - name: Extract and print coverage + run: | + RESULT_BUNDLE=$(find ~/Library/Developer/Xcode/DerivedData -type d -name "*.xcresult" | sort | tail -n 1) + + echo "Found result bundle at: $RESULT_BUNDLE" + + xcrun xccov view --report --json "$RESULT_BUNDLE" > coverage.json + cat coverage.json + + xcrun xccov view --report "$RESULT_BUNDLE" + + - name: Lint podspec + run: | + pod lib lint RIBs.podspec \ + --skip-tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 4425daa..cf34102 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,3 +67,77 @@ * [Android] Clear cached CoroutineScope instance once its job completes * [Android] Make all TestDispatchers in TestRibDispatchers use the same TestCoroutineScheduler +### Version 0.14.0 +* [Android] Bump Kotlin, Gradle, and other dependencies versions. +* [Android] Provide option to bind multiple Workers at once on specific RibDispatchers AndroidAndroid related tickets +* [Android] Use Kotlin contracts to remove var and !! usage in RibCoroutineWorker +* [Android] [Draft] Add capability for binding multiple Workers in specified CoroutineDispatcher AndroidAndroid related tickets +* [Android] Enable explicit api mode for Kotlin libraries AndroidAndroid related tickets +* [Android] Provide a more idiomatic Java API for RibDispatchers +* [Android] Upgrade code formatters versions AndroidAndroid related tickets +* [Android] Create README for Compose Demo AndroidAndroid related tickets +* [Android] [Rib Worker] Specify CoroutineDispatcher for onStart/onStop and provide WorkerBinder monitoring option AndroidAndroid related tickets +* [Android] Reduce Rx <-> Coroutines interop and allow unconfined coroutines to run eagerly inside Workers onStart +* [Android] Redesign RouterAndState to avoid router caching +* [Android] Fix router navigator events source compatibility +* [Android] Enable strict explicit API mode on rib-base +* [Android] Introduce RibCoroutineWorker AndroidAndroid related tickets +* [Android] Replacing some Behavior/Publish Relay usage in core artifacts with coroutines + +### Version 0.14.1 +* [Android] Open lifecycleFlow, thus enabling it for mocking +* [Android] [WorkerBinder] Guard against potential Worker.coroutineContext being null while using Mockito + +### Version 0.14.2 +* [Android] Fix potential for deadlocks in `Worker` binding. by @psteiger in https://github.com/uber/RIBs/pull/582 +* [Android] Add Rib Worker demo app by @FranAguilera in https://github.com/uber/RIBs/pull/575 + +### Version 0.15.0 +* Only complete the worker's scope after calling `Worker.onStop` by @psteiger in https://github.com/uber/RIBs/pull/585 +* Improve KDoc on `ActivityLifecycleEvent` by explaining ordering semantics. by @psteiger in https://github.com/uber/RIBs/pull/586 +* Make use of `jvmToolchain` for building the project. by @psteiger in https://github.com/uber/RIBs/pull/583 +* Revamp Gradle scripts by @psteiger in https://github.com/uber/RIBs/pull/588 +* Deprecate old worker by @FranAguilera in https://github.com/uber/RIBs/pull/597 +* Allow overriding default CoroutineDispatcher for WorkerBinder calls by @FranAguilera in https://github.com/uber/RIBs/pull/596 +* Update README.md by @FranAguilera in https://github.com/uber/RIBs/pull/600 +* Deprecate WorkerUnbinder by @FranAguilera in https://github.com/uber/RIBs/pull/601 +* Expose ribActionEvents stream by @FranAguilera in https://github.com/uber/RIBs/pull/599 + +### Version 0.15.1 +* [Android] Remove use of @JvmDefault in favor of using -Xjvm-default=all by @psteiger in https://github.com/uber/RIBs/pull/576 + +### Version 0.15.2 +* [Android] Set view tree owners for RibActivity + +### Version 0.15.3 +* Add RibCoroutineWorker.bind that receives multiple workers by @FranAguilera in https://github.com/uber/RIBs/pull/607 +* Change default CoroutineContext from empty to default for the RibCoroutineWorker<>Worker conversion by @FranAguilera in https://github.com/uber/RIBs/pull/608 +* Add `RibCoroutineWorker` factory method with `CoroutineScope` as receiver by @psteiger in https://github.com/uber/RIBs/pull/610 +* Update coroutines 1.7.3 by @tyvsmith in https://github.com/uber/RIBs/pull/609 +* Bump kotlinx.coroutines.test to 1.7.3 by @psteiger in https://github.com/uber/RIBs/pull/611 + +### Version 0.15.4 +* Set JvmVersion to 1.8 + +### Version 0.16.0 +* Get rid of suppressions for "invisible_reference" and "invisible_member" by @psteiger in https://github.com/uber/RIBs/pull/618 +* Introduce `TestScope.test(RibCoroutineWorker)` test helper utility. by @psteiger in https://github.com/uber/RIBs/pull/620 + +### Version 0.16.1 +* [Android] Remove duplicate method by @jbarr in https://github.com/uber/RIBs/pull/621 + +### Version 0.16.2 +* Make suspend functions callable inside `test(worker) { }` by @psteiger in https://github.com/uber/RIBs/pull/624 +* [RibCoroutineWorker] In `asWorker()`, keep scope alive until lifecycl… by @psteiger in https://github.com/uber/RIBs/pull/625 + +### Version 0.16.3 +* Fix Flipper Ribtree Plugin memory leak by @mamykin-andrey in https://github.com/uber/RIBs/pull/630 +* Support classes that are both `Worker` and `RibCoroutineWorker` in co… by @psteiger in https://github.com/uber/RIBs/pull/629 +* Increase buffer capacity for mutableRouterEvents flow within RibEvents by @RahulDMello in https://github.com/uber/RIBs/pull/635 +* Add test asserting Rx subscription is disposed after `RibCoroutineWor… by @psteiger in https://github.com/uber/RIBs/pull/628 + +### Version 1.0.0 + +* 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 diff --git a/Cartfile b/Cartfile index b974c62..7e913d3 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "ReactiveX/RxSwift" ~> 6.0.0 +github "ReactiveX/RxSwift" ~> 6.5.0 diff --git a/Example/.ruby-version b/Example/.ruby-version new file mode 100644 index 0000000..fd2a018 --- /dev/null +++ b/Example/.ruby-version @@ -0,0 +1 @@ +3.1.0 diff --git a/Example/Gemfile b/Example/Gemfile new file mode 100644 index 0000000..a55e88c --- /dev/null +++ b/Example/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem 'cocoapods' diff --git a/Example/Gemfile.lock b/Example/Gemfile.lock new file mode 100644 index 0000000..ab81a50 --- /dev/null +++ b/Example/Gemfile.lock @@ -0,0 +1,118 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.7) + base64 + nkf + rexml + activesupport (7.2.2.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + claide (1.1.0) + cocoapods (1.16.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.16.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.27.0, < 2.0) + cocoapods-core (1.16.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + drb (2.2.3) + escape (0.0.4) + ethon (0.15.0) + ffi (>= 1.15.0) + ffi (1.17.2) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-darwin) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.9.0) + mutex_m + i18n (1.14.7) + concurrent-ruby (~> 1.0) + json (2.13.2) + logger (1.7.0) + minitest (5.25.5) + molinillo (0.8.0) + mutex_m (0.3.0) + nanaimo (0.4.0) + nap (1.1.0) + netrc (0.11.0) + nkf (0.2.0) + public_suffix (4.0.7) + rexml (3.4.2) + ruby-macho (2.5.1) + securerandom (0.4.1) + typhoeus (1.5.0) + ethon (>= 0.9.0, < 0.16.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.27.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) + +PLATFORMS + arm64-darwin + ruby + x86_64-darwin + +DEPENDENCIES + cocoapods + +BUNDLED WITH + 2.6.9 diff --git a/Example/Podfile b/Example/Podfile new file mode 100644 index 0000000..6c660d9 --- /dev/null +++ b/Example/Podfile @@ -0,0 +1,8 @@ +use_frameworks! + +platform :ios, '15.0' + +target 'RIBs_Example' do + pod 'RIBs', :path => '../', :testspecs => ['Tests'] + +end diff --git a/Example/RIBs.xcodeproj/project.pbxproj b/Example/RIBs.xcodeproj/project.pbxproj new file mode 100644 index 0000000..45519b9 --- /dev/null +++ b/Example/RIBs.xcodeproj/project.pbxproj @@ -0,0 +1,430 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 7EAB71912E635DC2003F72CC /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 7EAB71902E635DC2003F72CC /* Podfile */; }; + F72111BE3D6D8AF7B540B2D5 /* Pods_RIBs_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 904C7089FA30546DB519E5B6 /* Pods_RIBs_Example.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 180A55BB288F867100F8D4F9 /* Pods-RIBs_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RIBs_Example.debug.xcconfig"; path = "Target Support Files/Pods-RIBs_Example/Pods-RIBs_Example.debug.xcconfig"; sourceTree = ""; }; + 5B75D54D9C6B380B38955F59 /* RIBs.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = RIBs.podspec; path = ../RIBs.podspec; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* RIBs_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RIBs_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 79412201A539E9C0ACDDCA67 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 7EAB71902E635DC2003F72CC /* Podfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podfile; sourceTree = ""; }; + 8352C4F16B235B2430F102DC /* Pods-RIBs_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RIBs_Example.release.xcconfig"; path = "Target Support Files/Pods-RIBs_Example/Pods-RIBs_Example.release.xcconfig"; sourceTree = ""; }; + 84C807AE5AA5710BFA3EE5FC /* Pods-RIBs_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RIBs_Tests.release.xcconfig"; path = "Target Support Files/Pods-RIBs_Tests/Pods-RIBs_Tests.release.xcconfig"; sourceTree = ""; }; + 904C7089FA30546DB519E5B6 /* Pods_RIBs_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RIBs_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 949E322ACAC2F0C08D385499 /* Pods-RIBs_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RIBs_Tests.debug.xcconfig"; path = "Target Support Files/Pods-RIBs_Tests/Pods-RIBs_Tests.debug.xcconfig"; sourceTree = ""; }; + AAA32BF7EA12B9DB046667D1 /* Pods_RIBs_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RIBs_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B641A7AB7F95727B09B517A7 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F72111BE3D6D8AF7B540B2D5 /* Pods_RIBs_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 7EAB71902E635DC2003F72CC /* Podfile */, + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for RIBs */, + 607FACD11AFB9204008FA782 /* Products */, + CABD681E5A6B1DC77376FADA /* Pods */, + AF9368EF7F28AA62E9AF9E91 /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* RIBs_Example.app */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for RIBs */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for RIBs"; + path = RIBs; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 5B75D54D9C6B380B38955F59 /* RIBs.podspec */, + B641A7AB7F95727B09B517A7 /* README.md */, + 79412201A539E9C0ACDDCA67 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + AF9368EF7F28AA62E9AF9E91 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 904C7089FA30546DB519E5B6 /* Pods_RIBs_Example.framework */, + AAA32BF7EA12B9DB046667D1 /* Pods_RIBs_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CABD681E5A6B1DC77376FADA /* Pods */ = { + isa = PBXGroup; + children = ( + 180A55BB288F867100F8D4F9 /* Pods-RIBs_Example.debug.xcconfig */, + 8352C4F16B235B2430F102DC /* Pods-RIBs_Example.release.xcconfig */, + 949E322ACAC2F0C08D385499 /* Pods-RIBs_Tests.debug.xcconfig */, + 84C807AE5AA5710BFA3EE5FC /* Pods-RIBs_Tests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* RIBs_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "RIBs_Example" */; + buildPhases = ( + 81989F6C76DF86427C0EABB8 /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + E26351EB8A5DF7958986D037 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RIBs_Example; + productName = RIBs; + productReference = 607FACD01AFB9204008FA782 /* RIBs_Example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0900; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "RIBs" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* RIBs_Example */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 7EAB71912E635DC2003F72CC /* Podfile in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 81989F6C76DF86427C0EABB8 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RIBs_Example-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E26351EB8A5DF7958986D037 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RIBs_Example/Pods-RIBs_Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/RIBs/RIBs.framework", + "${BUILT_PRODUCTS_DIR}/RxRelay/RxRelay.framework", + "${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RIBs.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxRelay.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RIBs_Example/Pods-RIBs_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 180A55BB288F867100F8D4F9 /* Pods-RIBs_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = RIBs/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8352C4F16B235B2430F102DC /* Pods-RIBs_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = RIBs/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "RIBs" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "RIBs_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Example/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs-Example.xcscheme b/Example/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs-Example.xcscheme new file mode 100644 index 0000000..09de0f6 --- /dev/null +++ b/Example/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs-Example.xcscheme @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/RIBs/AppDelegate.swift b/Example/RIBs/AppDelegate.swift new file mode 100644 index 0000000..047538f --- /dev/null +++ b/Example/RIBs/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// RIBs +// +// Created by Roman Brovko on 04/29/2025. +// Copyright (c) 2025 Roman Brovko. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Example/RIBs/Base.lproj/LaunchScreen.xib b/Example/RIBs/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..7a861dd --- /dev/null +++ b/Example/RIBs/Base.lproj/LaunchScreen.xib @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/RIBs/Base.lproj/Main.storyboard b/Example/RIBs/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f6d8a66 --- /dev/null +++ b/Example/RIBs/Base.lproj/Main.storyboard @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/RIBs/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/RIBs/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..7006c9e --- /dev/null +++ b/Example/RIBs/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,53 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Example/RIBs/Info.plist b/Example/RIBs/Info.plist new file mode 100644 index 0000000..eb18faa --- /dev/null +++ b/Example/RIBs/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + + + diff --git a/Example/RIBs/ViewController.swift b/Example/RIBs/ViewController.swift new file mode 100644 index 0000000..56acd89 --- /dev/null +++ b/Example/RIBs/ViewController.swift @@ -0,0 +1,24 @@ +// +// ViewController.swift +// RIBs +// +// Created by Roman Brovko on 04/29/2025. +// Copyright (c) 2025 Roman Brovko. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + +} + diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..ce9302c --- /dev/null +++ b/Package.resolved @@ -0,0 +1,34 @@ +{ + "object": { + "pins": [ + { + "package": "CwlCatchException", + "repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git", + "state": { + "branch": null, + "revision": "07b2ba21d361c223e25e3c1e924288742923f08c", + "version": "2.2.1" + } + }, + { + "package": "CwlPreconditionTesting", + "repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git", + "state": { + "branch": null, + "revision": "0139c665ebb45e6a9fbdb68aabfd7c39f3fe0071", + "version": "2.2.2" + } + }, + { + "package": "RxSwift", + "repositoryURL": "https://github.com/ReactiveX/RxSwift", + "state": { + "branch": null, + "revision": "5dd1907d64f0d36f158f61a466bab75067224893", + "version": "6.9.0" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift index c4a9143..53d3f9b 100644 --- a/Package.swift +++ b/Package.swift @@ -1,27 +1,31 @@ -// swift-tools-version:5.1 +// swift-tools-version:5.5 import PackageDescription let package = Package( name: "RIBs", platforms: [ - .iOS(.v9), + .iOS("15.0"), ], products: [ .library(name: "RIBs", targets: ["RIBs"]), ], dependencies: [ - .package(url: "https://github.com/ReactiveX/RxSwift", from: "6.0.0"), + .package(url: "https://github.com/ReactiveX/RxSwift", "6.9.0"..<"7.0.0"), + .package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", from: "2.2.2"), // for testTarget only ], targets: [ .target( name: "RIBs", - dependencies: ["RxSwift", "RxRelay"], - path: "ios/RIBs" + dependencies: [ + .product(name: "RxSwift", package: "RxSwift"), + .product(name: "RxRelay", package: "RxSwift") + ], + path: "RIBs" ), .testTarget( name: "RIBsTests", - dependencies: ["RIBs"], - path: "ios/RIBsTests" + dependencies: ["RIBs", "CwlPreconditionTesting"], + path: "RIBsTests" ), ] ) diff --git a/README.md b/README.md index 076bed4..2372f11 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ RIBs

-[![Android CI](https://github.com/uber/RIBs/actions/workflows/android.yml/badge.svg?branch=main)](https://github.com/uber/RIBs/actions/workflows/android.yml) +[![CI](https://github.com/uber/RIBs-iOS/actions/workflows/iOS.yml/badge.svg?branch=main)](https://github.com/uber/RIBs-iOS/actions/workflows/iOS.yml) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![Maven Central](https://img.shields.io/maven-central/v/com.uber.rib/rib-android.svg)](https://search.maven.org/artifact/com.uber.rib/rib-android) [![Cocoapods Compatible](https://img.shields.io/cocoapods/v/RIBs.svg)](https://cocoapods.org/pods/ribs) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage) +> ⚠️ **Alert:** RIBs for Android [separate repo](https://github.com/uber/ribs) + RIBs is the cross-platform architecture framework behind many mobile apps at Uber. The name RIBs is short for Router, Interactor and Builder, which are core components of this architecture. This framework is designed for mobile apps with a large number of engineers and nested states. The RIBs architecture provides: @@ -22,7 +23,7 @@ To get started with RIBs, please refer to the [RIBs documentation](https://githu To get more hands on with RIBs, we have written a [series of tutorials](https://github.com/uber/RIBs/wiki) that run you through the main aspects of the architecture with hands-on examples. -To read about the backstory on why we created RIBs, see [this blog post](https://eng.uber.com/new-rider-app/) we wrote when releasing RIBs in production the first time and see [this short video](https://www.youtube.com/watch?v=Q5cTT0M0YXg) where we discussed how the RIBs architecture works. +To read about the backstory on why we created RIBs, see [this blog post](https://www.uber.com/blog/new-rider-app-architecture/) we wrote when releasing RIBs in production the first time and see [this short video](https://www.youtube.com/watch?v=Q5cTT0M0YXg) where we discussed how the RIBs architecture works. #### What is the difference between RIBs and MV*/VIPER? @@ -43,40 +44,59 @@ There are some other novel things about RIBs. However, these could also be imple For usage of the tooling built around RIBs, please see the [Tooling section](https://github.com/uber/RIBs/wiki#rib-tooling) in our documentation. -## Installation for Android +## Installation for iOS -To integrate the recommended minimum setup for RIBs add the following to your `build.gradle`: +### Swift Package Manager (Recommended) -```gradle -dependencies { - annotationProcessor 'com.uber.rib:rib-compiler-test:0.13.3' - implementation 'com.uber.rib:rib-android:0.13.3' - testImplementation 'com.uber.rib:rib-test:0.13.3' -} -``` -There are a number of extension packages available as well including Kotlin extensions, Jetpack Compose support, Coroutines support +To integrate RIBs into your project using Swift Package Manager: +1. In Xcode, go to **File** → **Add Package Dependencies** +2. Enter the repository URL: `https://github.com/uber/RIBs-iOS.git` +3. Select the version constraint: `~> 1.0` +4. Click **Add Package** -## Installation for iOS -#### CocoaPods +Alternatively, you can add it to your `Package.swift`: + +```swift +dependencies: [ + .package(url: "https://github.com/uber/RIBs-iOS.git", from: "1.0.0") +] +``` + +### CocoaPods To integrate RIBs into your project add the following to your `Podfile`: ```ruby -pod 'RIBs', '~> 0.9' +pod 'RIBs', '~> 1.0' ``` -#### Carthage +### Carthage To integrate RIBs into your project using Carthage add the following to your `Cartfile`: ```ruby -github "uber/RIBs" ~> 0.9 +github "uber/RIBs" ~> 1.0 ``` +## Dependencies + +When you integrate RIBs into your project, it will automatically bring the following dependencies: + +### Core Dependencies +- **RxSwift** (~> 6.0) - Reactive programming library for Swift +- **RxRelay** (~> 6.0) - Reactive relays for state management + +### Platform Requirements +- **iOS 15.0+** - Minimum deployment target +- **Swift 5.0+** - Required Swift version + +These dependencies are automatically managed by your chosen package manager and will be resolved to compatible versions. + ## Related projects If you like RIBs, check out other related open source projects from our team: +- [RIBs-Android](https://github.com/uber/RIBs): Android version of RIBs framework implementation - [Needle](https://github.com/uber/needle): a compile-time safe Swift dependency injection framework. - [Motif](https://github.com/uber/motif): An abstract on top of Dagger offering simpler APIs for nested scopes. - [Swift Concurrency](https://github.com/uber/swift-concurrency): a set of concurrency utility classes used by Uber, inspired by the equivalent [java.util.concurrent](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html) package classes. diff --git a/RELEASING.md b/RELEASING.md index c6ab11f..5cda042 100755 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,19 +1,3 @@ -Releasing -========= - -Android -------- - - 1. Change the version in `gradle.properties` to a non-SNAPSHOT version. - 2. Update the `README.md` with the new version. - 3. Update the `CHANGELOG.md` for the impending release. - 4. `git commit -am "Prepare for release X.Y.Z."` (where X.Y.Z is the new version) - 5. `git tag -a X.Y.Z -m "Version X.Y.Z"` (where X.Y.Z is the new version) - 6. `./gradlew clean publish --no-daemon --no-parallel && ./gradlew closeAndReleaseRepository` - 7. Update the `gradle.properties` to the next SNAPSHOT version. - 8. `git commit -am "Prepare next development version."` - 9. `git push && git push --tags` - iOS --- diff --git a/RIBs.podspec b/RIBs.podspec index 6659224..38f8ecd 100644 --- a/RIBs.podspec +++ b/RIBs.podspec @@ -1,16 +1,23 @@ Pod::Spec.new do |s| s.name = 'RIBs' - s.version = '0.9.3' + s.version = '1.0.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. DESC - s.homepage = 'https://github.com/uber/RIBs' + s.homepage = 'https://github.com/uber/RIBs-iOS' s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE.txt' } s.author = { 'uber' => 'mobile-open-source@uber.com' } - s.source = { :git => 'https://github.com/uber/RIBs.git', :tag => 'v' + s.version.to_s } - s.ios.deployment_target = '9.0' - s.source_files = 'ios/RIBs/Classes/**/*' - s.dependency 'RxSwift', '~> 6.0.0' - s.dependency 'RxRelay', '~> 6.0.0' + s.source = { :git => 'https://github.com/uber/RIBs-iOS.git', :tag => s.version.to_s } + s.ios.deployment_target = '15.0' + s.swift_version = '5.0' + s.source_files = 'RIBs/Classes/**/*' + s.dependency 'RxSwift', '~> 6.0' + s.dependency 'RxRelay', '~> 6.0' + + s.test_spec 'Tests' do |test_spec| + test_spec.source_files = 'RIBsTests/**/*.swift' + test_spec.dependency 'CwlPreconditionTesting' + end + end diff --git a/ios/RIBs.xcodeproj/project.pbxproj b/RIBs.xcodeproj/project.pbxproj similarity index 99% rename from ios/RIBs.xcodeproj/project.pbxproj rename to RIBs.xcodeproj/project.pbxproj index b5ae108..049e88a 100644 --- a/ios/RIBs.xcodeproj/project.pbxproj +++ b/RIBs.xcodeproj/project.pbxproj @@ -560,7 +560,7 @@ ); INFOPLIST_FILE = RIBs/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.uber.RIBs; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; @@ -587,7 +587,7 @@ ); INFOPLIST_FILE = RIBs/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.uber.RIBs; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; diff --git a/ios/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs.xcscheme b/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs.xcscheme similarity index 100% rename from ios/RIBs.xcodeproj/xcshareddata/xcschemes/RIBs.xcscheme rename to RIBs.xcodeproj/xcshareddata/xcschemes/RIBs.xcscheme diff --git a/ios/RIBs/Classes/Builder.swift b/RIBs/Classes/Builder.swift similarity index 100% rename from ios/RIBs/Classes/Builder.swift rename to RIBs/Classes/Builder.swift diff --git a/ios/RIBs/Classes/ComponentizedBuilder.swift b/RIBs/Classes/ComponentizedBuilder.swift similarity index 100% rename from ios/RIBs/Classes/ComponentizedBuilder.swift rename to RIBs/Classes/ComponentizedBuilder.swift diff --git a/ios/RIBs/Classes/DI/Component.swift b/RIBs/Classes/DI/Component.swift similarity index 100% rename from ios/RIBs/Classes/DI/Component.swift rename to RIBs/Classes/DI/Component.swift diff --git a/ios/RIBs/Classes/DI/Dependency.swift b/RIBs/Classes/DI/Dependency.swift similarity index 100% rename from ios/RIBs/Classes/DI/Dependency.swift rename to RIBs/Classes/DI/Dependency.swift diff --git a/ios/RIBs/Classes/Extensions/Foundation+Extensions.swift b/RIBs/Classes/Extensions/Foundation+Extensions.swift similarity index 100% rename from ios/RIBs/Classes/Extensions/Foundation+Extensions.swift rename to RIBs/Classes/Extensions/Foundation+Extensions.swift diff --git a/ios/RIBs/Classes/Interactor.swift b/RIBs/Classes/Interactor.swift similarity index 100% rename from ios/RIBs/Classes/Interactor.swift rename to RIBs/Classes/Interactor.swift diff --git a/ios/RIBs/Classes/LaunchRouter.swift b/RIBs/Classes/LaunchRouter.swift similarity index 100% rename from ios/RIBs/Classes/LaunchRouter.swift rename to RIBs/Classes/LaunchRouter.swift diff --git a/ios/RIBs/Classes/LeakDetector/Executor.swift b/RIBs/Classes/LeakDetector/Executor.swift similarity index 100% rename from ios/RIBs/Classes/LeakDetector/Executor.swift rename to RIBs/Classes/LeakDetector/Executor.swift diff --git a/ios/RIBs/Classes/LeakDetector/LeakDetector.swift b/RIBs/Classes/LeakDetector/LeakDetector.swift similarity index 95% rename from ios/RIBs/Classes/LeakDetector/LeakDetector.swift rename to RIBs/Classes/LeakDetector/LeakDetector.swift index 8e896b0..0f797aa 100644 --- a/ios/RIBs/Classes/LeakDetector/LeakDetector.swift +++ b/RIBs/Classes/LeakDetector/LeakDetector.swift @@ -54,7 +54,12 @@ public protocol LeakDetectionHandle { public class LeakDetector { /// The singleton instance. - public static let instance = LeakDetector() + public static private(set) var instance = LeakDetector() + + // This is used internally to be able to set mock instance in unit-tests. The public API and behavior of the public static LeakDetector instance above does not change. + static func setInstance(_ newInstance: LeakDetector) { + instance = newInstance + } /// The status of leak detection. /// @@ -170,8 +175,6 @@ public class LeakDetector { } return LeakDetector.disableLeakDetectorOverride }() - - private init() {} } fileprivate class LeakDetectionHandleImpl: LeakDetectionHandle { diff --git a/ios/RIBs/Classes/MultiStageComponentizedBuilder.swift b/RIBs/Classes/MultiStageComponentizedBuilder.swift similarity index 100% rename from ios/RIBs/Classes/MultiStageComponentizedBuilder.swift rename to RIBs/Classes/MultiStageComponentizedBuilder.swift diff --git a/ios/RIBs/Classes/PresentableInteractor.swift b/RIBs/Classes/PresentableInteractor.swift similarity index 100% rename from ios/RIBs/Classes/PresentableInteractor.swift rename to RIBs/Classes/PresentableInteractor.swift diff --git a/ios/RIBs/Classes/Presenter.swift b/RIBs/Classes/Presenter.swift similarity index 100% rename from ios/RIBs/Classes/Presenter.swift rename to RIBs/Classes/Presenter.swift diff --git a/ios/RIBs/Classes/Router.swift b/RIBs/Classes/Router.swift similarity index 100% rename from ios/RIBs/Classes/Router.swift rename to RIBs/Classes/Router.swift diff --git a/ios/RIBs/Classes/ViewControllable.swift b/RIBs/Classes/ViewControllable.swift similarity index 100% rename from ios/RIBs/Classes/ViewControllable.swift rename to RIBs/Classes/ViewControllable.swift diff --git a/ios/RIBs/Classes/ViewableRouter.swift b/RIBs/Classes/ViewableRouter.swift similarity index 100% rename from ios/RIBs/Classes/ViewableRouter.swift rename to RIBs/Classes/ViewableRouter.swift diff --git a/ios/RIBs/Classes/Worker/Worker.swift b/RIBs/Classes/Worker/Worker.swift similarity index 100% rename from ios/RIBs/Classes/Worker/Worker.swift rename to RIBs/Classes/Worker/Worker.swift diff --git a/ios/RIBs/Classes/Workflow/Workflow.swift b/RIBs/Classes/Workflow/Workflow.swift similarity index 100% rename from ios/RIBs/Classes/Workflow/Workflow.swift rename to RIBs/Classes/Workflow/Workflow.swift diff --git a/ios/RIBs/Info.plist b/RIBs/Info.plist similarity index 96% rename from ios/RIBs/Info.plist rename to RIBs/Info.plist index 992c476..4c0d218 100644 --- a/ios/RIBs/Info.plist +++ b/RIBs/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.3 + 1.0.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/ios/RIBs/RIBs.h b/RIBs/RIBs.h similarity index 100% rename from ios/RIBs/RIBs.h rename to RIBs/RIBs.h diff --git a/ios/RIBsTests/ComponentizedBuilderTests.swift b/RIBsTests/ComponentizedBuilderTests.swift similarity index 84% rename from ios/RIBsTests/ComponentizedBuilderTests.swift rename to RIBsTests/ComponentizedBuilderTests.swift index f70c1be..d087729 100644 --- a/ios/RIBsTests/ComponentizedBuilderTests.swift +++ b/RIBsTests/ComponentizedBuilderTests.swift @@ -16,6 +16,7 @@ @testable import RIBs import XCTest +import CwlPreconditionTesting class ComponentizedBuilderTests: XCTestCase { @@ -29,10 +30,16 @@ class ComponentizedBuilderTests: XCTestCase { } let _: MockSimpleRouter = sameInstanceBuilder.build(withDynamicBuildDependency: (), dynamicComponentDependency: ()) - - expectAssertionFailure { + + let options = XCTExpectedFailure.Options() + options.issueMatcher = { issue in + issue.type == .assertionFailure + } + + let assertionFailureException = catchBadInstruction { let _: MockSimpleRouter = sameInstanceBuilder.build(withDynamicBuildDependency: (), dynamicComponentDependency: ()) } + XCTAssertNotNil(assertionFailureException, "Builder should not return the same instance for the same component. Assertion failure is triggered.") } func test_componentForCurrentPass_builderReturnsNewInstance_verifyNoAssertion() { diff --git a/ios/RIBsTests/DI/ComponentTests.swift b/RIBsTests/DI/ComponentTests.swift similarity index 100% rename from ios/RIBsTests/DI/ComponentTests.swift rename to RIBsTests/DI/ComponentTests.swift diff --git a/ios/RIBsTests/Extensions/Foundation+ExtensionsTests.swift b/RIBsTests/Extensions/Foundation+ExtensionsTests.swift similarity index 100% rename from ios/RIBsTests/Extensions/Foundation+ExtensionsTests.swift rename to RIBsTests/Extensions/Foundation+ExtensionsTests.swift diff --git a/ios/RIBsTests/Info.plist b/RIBsTests/Info.plist similarity index 100% rename from ios/RIBsTests/Info.plist rename to RIBsTests/Info.plist diff --git a/RIBsTests/Interactor/InteractorTests.swift b/RIBsTests/Interactor/InteractorTests.swift new file mode 100644 index 0000000..5797869 --- /dev/null +++ b/RIBsTests/Interactor/InteractorTests.swift @@ -0,0 +1,172 @@ +// +// InteractorTests.swift +// RIBs +// +// Created by Alex Bush on 6/22/25. +// + +@testable import RIBs +import XCTest +import RxSwift + +final class InteractorTests: XCTestCase { + + private var interactor: InteractorMock! + + override func setUp() { + super.setUp() + + interactor = InteractorMock() // NOTE: we're using InteractorMock here to test the underlying parent class, Interactor, behavior so this is appropriate here. + } + + func test_interactorIsInactiveByDefault() { + XCTAssertFalse(interactor.isActive) + let _ = interactor.isActiveStream.subscribe { isActive in + XCTAssertFalse(isActive) + } + } + + func test_isActive_whenStarted_isTrue() { + // give + // when + interactor.activate() + // then + XCTAssertTrue(interactor.isActive) + let _ = interactor.isActiveStream.subscribe { isActive in + XCTAssertTrue(isActive) + } + } + + func test_isActive_whenDeactivated_isFalse() { + // given + interactor.activate() + // when + interactor.deactivate() + // then + XCTAssertFalse(interactor.isActive) + let _ = interactor.isActiveStream.subscribe { isActive in + XCTAssertFalse(isActive) + } + } + + func test_didBecomeActive_isCalledWhenStarted() { + // given + // when + interactor.activate() + // then + XCTAssertEqual(interactor.didBecomeActiveCallCount, 1) + } + + func test_didBecomeActive_isNotCalledWhenAlreadyActive() { + // given + interactor.activate() + XCTAssertEqual(interactor.didBecomeActiveCallCount, 1) + // when + interactor.activate() + // then + XCTAssertEqual(interactor.didBecomeActiveCallCount, 1) + } + + func test_willResignActive_isCalledWhenDeactivated() { + // given + interactor.activate() + // when + interactor.deactivate() + // then + XCTAssertEqual(interactor.willResignActiveCallCount, 1) + } + + func test_willResignActive_isNotCalledWhenAlreadyInactive() { + // given + interactor.activate() + interactor.deactivate() + XCTAssertEqual(interactor.willResignActiveCallCount, 1) + // when + interactor.deactivate() + // then + XCTAssertEqual(interactor.willResignActiveCallCount, 1) + } + + func test_isActiveStream_completedOnInteractorDeinit() { + // given + var isActiveStreamCompleted = false + interactor.activate() + let _ = interactor.isActiveStream.subscribe { _ in } onCompleted: { + isActiveStreamCompleted = true + } + + // when + interactor = nil + // then + XCTAssertTrue(isActiveStreamCompleted) + + } + + // MARK: - BEGIN Observables Attached/Detached to/from Interactor + func test_observableAttachedToInactiveInteactorIsDisposedImmediately() { + // given + var onDisposeCalled = false + let subjectEmiitingValues: PublishSubject = .init() + let observable = subjectEmiitingValues.asObservable().do { _ in } onDispose: { + onDisposeCalled = true + } + // when + observable.subscribe().disposeOnDeactivate(interactor: interactor) + // then + XCTAssertTrue(onDisposeCalled) + } + + func test_observableIsDisposedOnInteractorDeactivation() { + // given + var onDisposeCalled = false + let subjectEmiitingValues: PublishSubject = .init() + let observable = subjectEmiitingValues.asObservable().do { _ in } onDispose: { + onDisposeCalled = true + } + interactor.activate() + observable.subscribe().disposeOnDeactivate(interactor: interactor) + // when + interactor.deactivate() + // then + XCTAssertTrue(onDisposeCalled) + } + + func test_observableIsDisposedOnInteractorDeinit() { + // given + var onDisposeCalled = false + let subjectEmiitingValues: PublishSubject = .init() + let observable = subjectEmiitingValues.asObservable().do { _ in } onDispose: { + onDisposeCalled = true + } + interactor.activate() + observable.subscribe().disposeOnDeactivate(interactor: interactor) + XCTAssertFalse(onDisposeCalled) + // when + interactor = nil + // then + XCTAssertTrue(onDisposeCalled) + } + // MARK: Observables Attached/Detached to/from Interactor END - + + // MARK: - BEGIN Observables Confined to Interactor + func test_observableConfinedToInteractorOnlyEmitsValueWhenInteractorIsActive() { + // given + var emittedValue: Int? + let subjectEmiitingValues: PublishSubject = .init() + let confinedObservable = subjectEmiitingValues.asObservable().confineTo(interactor) + let _ = confinedObservable.confineTo(interactor) + let _ = confinedObservable.subscribe { newValue in + emittedValue = newValue + } + + subjectEmiitingValues.onNext(1) + XCTAssertNil(emittedValue) + // when + interactor.activate() + subjectEmiitingValues.onNext(2) + // then + XCTAssertNotNil(emittedValue) + XCTAssertEqual(emittedValue, 2) + } + // MARK: Observables Confined to Interactor - +} diff --git a/RIBsTests/Interactor/PresentableInteractorTests.swift b/RIBsTests/Interactor/PresentableInteractorTests.swift new file mode 100644 index 0000000..7505703 --- /dev/null +++ b/RIBsTests/Interactor/PresentableInteractorTests.swift @@ -0,0 +1,40 @@ +// +// PresentableInteractorTests.swift +// RIBs +// +// Created by Alex Bush on 6/23/25. +// + +@testable import RIBs +import XCTest +import RxSwift + +protocol TestPresenter {} + +final class PresenterMock: TestPresenter {} + +final class PresentableInteractorTests: XCTestCase { + + private var interactor: PresentableInteractor! + + override func setUp() { + super.setUp() + + } + + func test_deinit_doesNotLeakPresenter() { + // given + let presenterMock = PresenterMock() + let disposeBag = DisposeBag() + interactor = PresentableInteractor(presenter: presenterMock) + var status: LeakDetectionStatus = .DidComplete + LeakDetector.instance.status.subscribe { newStatus in + status = newStatus + }.disposed(by: disposeBag) + + // when + interactor = nil + // then + XCTAssertEqual(status, .InProgress) + } +} diff --git a/ios/RIBsTests/LaunchRouterTests.swift b/RIBsTests/LaunchRouterTests.swift similarity index 100% rename from ios/RIBsTests/LaunchRouterTests.swift rename to RIBsTests/LaunchRouterTests.swift diff --git a/RIBsTests/LeakDetector/LeakDetectorMock.swift b/RIBsTests/LeakDetector/LeakDetectorMock.swift new file mode 100644 index 0000000..dc767b4 --- /dev/null +++ b/RIBsTests/LeakDetector/LeakDetectorMock.swift @@ -0,0 +1,39 @@ +// +// LeakDetectorMock.swift +// RIBs +// +// Created by Alex Bush on 7/26/25. +// + +@testable import RIBs +import Foundation +import RxSwift +import UIKit + +final class LeakDetectionHandleMock: LeakDetectionHandle { + var cancelCallCount = 0 + func cancel() { + cancelCallCount += 1 + } +} + +final class LeakDetectorMock: LeakDetector { + + var expectDeallocateCallCount = 0 + override func expectDeallocate(object: AnyObject, inTime time: TimeInterval) -> LeakDetectionHandle { + expectDeallocateCallCount += 1 + return LeakDetectionHandleMock() + } + + var expectViewControllerDisappearCallCount = 0 + override func expectViewControllerDisappear(viewController: UIViewController, inTime time: TimeInterval) -> LeakDetectionHandle { + expectViewControllerDisappearCallCount += 1 + return LeakDetectionHandleMock() + } + + var statusCallCount = 0 + override var status: Observable { + statusCallCount += 1 + return super.status + } +} diff --git a/ios/RIBsTests/Mocks.swift b/RIBsTests/Mocks.swift similarity index 76% rename from ios/RIBsTests/Mocks.swift rename to RIBsTests/Mocks.swift index ad8a8a0..08fe1bd 100644 --- a/ios/RIBsTests/Mocks.swift +++ b/RIBsTests/Mocks.swift @@ -44,27 +44,28 @@ class ViewControllableMock: ViewControllable { let uiviewController = UIViewController(nibName: nil, bundle: nil) } -class InteractorMock: Interactable { - var isActive: Bool { - return active.value - } - - var isActiveStream: Observable { - return active.asObservable() - } - - private let active = BehaviorRelay(value: false) - - init() {} - - // MARK: - Lifecycle - - func activate() { - active.accept(true) +class InteractorMock: Interactor { + var didBecomeActiveHandler: (() -> ())? + var didBecomeActiveCallCount: Int = 0 + var willResignActiveHandler: (() -> ())? + var willResignActiveCallCount: Int = 0 + + override func didBecomeActive() { + didBecomeActiveCallCount += 1 + super.didBecomeActive() + + if let didBecomeActiveHandler = didBecomeActiveHandler { + didBecomeActiveHandler() + } } - - func deactivate() { - active.accept(false) + + override func willResignActive() { + willResignActiveCallCount += 1 + super.willResignActive() + + if let willResignActiveHandler = willResignActiveHandler { + willResignActiveHandler() + } } } diff --git a/ios/RIBsTests/MultiStageComponentizedBuilderTests.swift b/RIBsTests/MultiStageComponentizedBuilderTests.swift similarity index 88% rename from ios/RIBsTests/MultiStageComponentizedBuilderTests.swift rename to RIBsTests/MultiStageComponentizedBuilderTests.swift index e912d75..917005f 100644 --- a/ios/RIBsTests/MultiStageComponentizedBuilderTests.swift +++ b/RIBsTests/MultiStageComponentizedBuilderTests.swift @@ -16,6 +16,7 @@ @testable import RIBs import XCTest +import CwlPreconditionTesting class MultiStageComponentizedBuilderTests: XCTestCase { @@ -64,13 +65,15 @@ class MultiStageComponentizedBuilderTests: XCTestCase { _ = sameInstanceBuilder.finalStageBuild(withDynamicDependency: 92393) - expectAssertionFailure { + let finalStageBuildFatalErrorException = catchBadInstruction { _ = sameInstanceBuilder.finalStageBuild(withDynamicDependency: 92393) } + XCTAssertNotNil(finalStageBuildFatalErrorException, "fatalError expected") - expectAssertionFailure { + let componentForCurrentBuildPassAssertionFailureException = catchBadInstruction { _ = sameInstanceBuilder.componentForCurrentBuildPass } + XCTAssertNotNil(componentForCurrentBuildPassAssertionFailureException, "Assertion failure expected") } } diff --git a/RIBsTests/Router/RouterTests.swift b/RIBsTests/Router/RouterTests.swift new file mode 100644 index 0000000..2ab8a20 --- /dev/null +++ b/RIBsTests/Router/RouterTests.swift @@ -0,0 +1,180 @@ +// +// Copyright (c) 2017. Uber Technologies +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import RxSwift +import XCTest +@testable import RIBs + +final class RouterMock: Routing { + + var interactable: Interactable + + var children: [Routing] + + init(interactor: Interactable) { + self.interactable = interactor + self.children = [] + } + + var attachChildCallCount = 0 + func attachChild(_ child: Routing) { + attachChildCallCount += 1 + } + + var detachChildCallCount = 0 + func detachChild(_ child: Routing) { + detachChildCallCount += 1 + } + + var lifecycle: Observable { + return Observable.just(.didLoad) + } + + var loadCallCount = 0 + func load() { + loadCallCount += 1 + } +} + +final class RouterTests: XCTestCase { + + private var router: Router! + private var lifecycleDisposable: Disposable = Disposables.create() + private var leakDetectorMock: LeakDetectorMock = LeakDetectorMock() + + // MARK: - Setup + + override func setUp() { + super.setUp() + + leakDetectorMock = LeakDetectorMock() + LeakDetector.setInstance(leakDetectorMock) + + } + + override func tearDown() { + super.tearDown() + + lifecycleDisposable.dispose() + } + + // MARK: - Tests + + func test_load_verifyLifecycleObservable() { + router = Router(interactor: InteractableMock()) + var currentLifecycle: RouterLifecycle? + var didComplete = false + lifecycleDisposable = router + .lifecycle + .subscribe(onNext: { lifecycle in + currentLifecycle = lifecycle + }, onCompleted: { + currentLifecycle = nil + didComplete = true + }) + + XCTAssertNil(currentLifecycle) + XCTAssertFalse(didComplete) + + router.load() + + XCTAssertEqual(currentLifecycle, RouterLifecycle.didLoad) + XCTAssertFalse(didComplete) + + router = nil + + XCTAssertNil(currentLifecycle) + XCTAssertTrue(didComplete) + } + + func test_attachChild() { + // given + router = Router(interactor: InteractableMock()) + let mockChildInteractor = InteractableMock() + let mockChildRouter = RouterMock(interactor: mockChildInteractor) + + // when + router.attachChild(mockChildRouter) + + // then + XCTAssertEqual(router.children.count, 1) + XCTAssertEqual(mockChildInteractor.activateCallCount, 1) + XCTAssertEqual(mockChildRouter.loadCallCount, 1) + } + + func test_attachChild_activatesSubtreeOfTheChild() { + // given + router = Router(interactor: InteractableMock()) + let childInteractor = InteractableMock() + let childRouter = Router(interactor: childInteractor) + let grandChildInteractor = InteractableMock() + let grandChildRouter = RouterMock(interactor: grandChildInteractor) + childRouter.attachChild(grandChildRouter) + router.load() + + // when + router.attachChild(childRouter) + + // then + XCTAssertEqual(grandChildInteractor.activateCallCount, 1) + XCTAssertEqual(grandChildRouter.loadCallCount, 1) + } + + func test_detachChild() { + // given + router = Router(interactor: InteractableMock()) + let mockChildInteractor = InteractableMock() + let mockChildRouter = RouterMock(interactor: mockChildInteractor) + router.attachChild(mockChildRouter) + + // when + router.detachChild(mockChildRouter) + + // then + XCTAssertEqual(router.children.count, 0) + XCTAssertEqual(mockChildInteractor.deactivateCallCount, 1) + } + + func test_detachChild_deactivatesSubtreeOfTheChild() { + // given + router = Router(interactor: InteractableMock()) + let childInteractor = Interactor() + let childRouter = Router(interactor: childInteractor) + let grandChildInteractor = InteractableMock() + let grandChildRouter = RouterMock(interactor: grandChildInteractor) + router.load() + router.attachChild(childRouter) + childRouter.attachChild(grandChildRouter) + grandChildInteractor.isActive = true + + // when + router.detachChild(childRouter) + + // then + XCTAssertEqual(grandChildInteractor.deactivateCallCount, 1) + } + + func test_deinit_triggers_leakDetection() { + // given + let interactor = InteractableMock() + router = Router(interactor: interactor) + router.load() + // when + router = nil + // then + XCTAssertEqual(leakDetectorMock.expectDeallocateCallCount, 1) + } +} diff --git a/RIBsTests/Router/ViewableRouterTests.swift b/RIBsTests/Router/ViewableRouterTests.swift new file mode 100644 index 0000000..88d3f0e --- /dev/null +++ b/RIBsTests/Router/ViewableRouterTests.swift @@ -0,0 +1,56 @@ +// +// ViewableRouterTests.swift +// RIBs +// +// Created by Alex Bush on 7/26/25. +// + +import RxSwift +import XCTest +@testable import RIBs +import CwlPreconditionTesting + + +final class ViewControllerMock: ViewControllable { + + var uiviewController: UIViewController { + return UIViewController() + } +} + +final class ViewableRouterTests: XCTestCase { + + private var router: ViewableRouter, ViewControllerMock>! + private var leakDetectorMock: LeakDetectorMock = LeakDetectorMock() + + override func setUp() { + super.setUp() + + leakDetectorMock = LeakDetectorMock() + LeakDetector.setInstance(leakDetectorMock) + } + + func test_leakDetection() { + // given + let interactor = PresentableInteractor(presenter: PresenterMock()) + let viewController = ViewControllerMock() + router = ViewableRouter(interactor: interactor, viewController: viewController) + router.load() + // when + interactor.deactivate() + // then + XCTAssertEqual(leakDetectorMock.expectViewControllerDisappearCallCount, 1) + } + + func test_deinit_triggers_leakDetection() { + // given + let interactor = PresentableInteractor(presenter: PresenterMock()) + let viewController = ViewControllerMock() + router = ViewableRouter(interactor: interactor, viewController: viewController) + router.load() + // when + router = nil + // then + XCTAssertEqual(leakDetectorMock.expectDeallocateCallCount, 2) + } +} diff --git a/ios/RIBsTests/Worker/WorkerTests.swift b/RIBsTests/Worker/WorkerTests.swift similarity index 100% rename from ios/RIBsTests/Worker/WorkerTests.swift rename to RIBsTests/Worker/WorkerTests.swift diff --git a/ios/RIBsTests/Workflow/WorkflowTests.swift b/RIBsTests/Workflow/WorkflowTests.swift similarity index 100% rename from ios/RIBsTests/Workflow/WorkflowTests.swift rename to RIBsTests/Workflow/WorkflowTests.swift diff --git a/ios/RIBsTests/RouterTests.swift b/ios/RIBsTests/RouterTests.swift deleted file mode 100644 index d31d0c5..0000000 --- a/ios/RIBsTests/RouterTests.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) 2017. Uber Technologies -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import RxSwift -import XCTest -@testable import RIBs - -final class RouterTests: XCTestCase { - - private var router: Router! - private var lifecycleDisposable: Disposable! - - // MARK: - Setup - - override func setUp() { - super.setUp() - - router = Router(interactor: InteractableMock()) - } - - override func tearDown() { - super.tearDown() - - lifecycleDisposable.dispose() - } - - // MARK: - Tests - - func test_load_verifyLifecycleObservable() { - var currentLifecycle: RouterLifecycle? - var didComplete = false - lifecycleDisposable = router - .lifecycle - .subscribe(onNext: { lifecycle in - currentLifecycle = lifecycle - }, onCompleted: { - currentLifecycle = nil - didComplete = true - }) - - XCTAssertNil(currentLifecycle) - XCTAssertFalse(didComplete) - - router.load() - - XCTAssertEqual(currentLifecycle, RouterLifecycle.didLoad) - XCTAssertFalse(didComplete) - - router = nil - - XCTAssertNil(currentLifecycle) - XCTAssertTrue(didComplete) - } -} diff --git a/ios/test.md b/ios/test.md deleted file mode 100755 index 46ba254..0000000 --- a/ios/test.md +++ /dev/null @@ -1,34 +0,0 @@ -Releasing -========= - -Android -------- - - 1. Change the version in `gradle.properties` to a non-SNAPSHOT version. - 2. Update the `CHANGELOG.md` for the impending release. - 3. Update the `README.md` with the new version. - 4. `git commit -am "Prepare for release X.Y.Z."` (where X.Y.Z is the new version) - 5. `git tag -a X.Y.Z -m "Version X.Y.Z"` (where X.Y.Z is the new version) - 6. `./gradlew clean uploadArchives` - 7. Update the `gradle.properties` to the next SNAPSHOT version. - 8. `git commit -am "Prepare next development version."` - 9. `git push && git push --tags` - 10. Visit [Sonatype Nexus](https://oss.sonatype.org/) and promote the artifact. - -iOS ---- - -Releasing -========= - -Note: This may vary based on your distribution mechanism. Assuming CocoaPods: - - 1. Change the version in `Name.podspec` to reflect a new version. - 2. Update the `CHANGELOG.md` for the impending release. - 3. Update the `README.md` with the new version. - 4. Verify formatting with swiftlint (swiftformat.sh) - 5. `git commit -am "Release X.Y.Z."` (where X.Y.Z is the new version) - 6. `git tag "X.Y.Z"` (where X.Y.Z is the new version) - 7. `git push --tags` - 8. `pod trunk push Name.podspec` - \ No newline at end of file diff --git a/ios/tutorials/tutorial4/Podfile b/ios/tutorials/tutorial4/Podfile deleted file mode 100644 index 980817e..0000000 --- a/ios/tutorials/tutorial4/Podfile +++ /dev/null @@ -1,10 +0,0 @@ -platform :ios, '9.0' - -use_frameworks! -inhibit_all_warnings! - -target 'TicTacToe' do - pod 'RIBs', :path => '../../../' - pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' -end diff --git a/ios/swiftformat.sh b/swiftformat.sh similarity index 100% rename from ios/swiftformat.sh rename to swiftformat.sh diff --git a/test.md b/test.md new file mode 100755 index 0000000..c923b71 --- /dev/null +++ b/test.md @@ -0,0 +1,17 @@ +iOS +--- + +Releasing +========= + +Note: This may vary based on your distribution mechanism. Assuming CocoaPods: + + 1. Change the version in `Name.podspec` to reflect a new version. + 2. Update the `CHANGELOG.md` for the impending release. + 3. Update the `README.md` with the new version. + 4. Verify formatting with swiftlint (swiftformat.sh) + 5. `git commit -am "Release X.Y.Z."` (where X.Y.Z is the new version) + 6. `git tag "X.Y.Z"` (where X.Y.Z is the new version) + 7. `git push --tags` + 8. `pod trunk push Name.podspec` + \ No newline at end of file diff --git a/ios/tooling/Component Extension.xctemplate/TemplateIcon.png b/tooling/Component Extension.xctemplate/TemplateIcon.png similarity index 100% rename from ios/tooling/Component Extension.xctemplate/TemplateIcon.png rename to tooling/Component Extension.xctemplate/TemplateIcon.png diff --git a/ios/tooling/Component Extension.xctemplate/TemplateIcon@2x.png b/tooling/Component Extension.xctemplate/TemplateIcon@2x.png similarity index 100% rename from ios/tooling/Component Extension.xctemplate/TemplateIcon@2x.png rename to tooling/Component Extension.xctemplate/TemplateIcon@2x.png diff --git a/ios/tooling/Component Extension.xctemplate/TemplateInfo.plist b/tooling/Component Extension.xctemplate/TemplateInfo.plist similarity index 100% rename from ios/tooling/Component Extension.xctemplate/TemplateInfo.plist rename to tooling/Component Extension.xctemplate/TemplateInfo.plist diff --git a/ios/tooling/Component Extension.xctemplate/___FILEBASENAME___Component+___VARIABLE_childName___.swift b/tooling/Component Extension.xctemplate/___FILEBASENAME___Component+___VARIABLE_childName___.swift similarity index 100% rename from ios/tooling/Component Extension.xctemplate/___FILEBASENAME___Component+___VARIABLE_childName___.swift rename to tooling/Component Extension.xctemplate/___FILEBASENAME___Component+___VARIABLE_childName___.swift diff --git a/ios/tooling/README.md b/tooling/README.md similarity index 100% rename from ios/tooling/README.md rename to tooling/README.md diff --git a/ios/tooling/RIB Unit Tests.xctemplate/TemplateIcon.png b/tooling/RIB Unit Tests.xctemplate/TemplateIcon.png similarity index 100% rename from ios/tooling/RIB Unit Tests.xctemplate/TemplateIcon.png rename to tooling/RIB Unit Tests.xctemplate/TemplateIcon.png diff --git a/ios/tooling/RIB Unit Tests.xctemplate/TemplateIcon@2x.png b/tooling/RIB Unit Tests.xctemplate/TemplateIcon@2x.png similarity index 100% rename from ios/tooling/RIB Unit Tests.xctemplate/TemplateIcon@2x.png rename to tooling/RIB Unit Tests.xctemplate/TemplateIcon@2x.png diff --git a/ios/tooling/RIB Unit Tests.xctemplate/TemplateInfo.plist b/tooling/RIB Unit Tests.xctemplate/TemplateInfo.plist similarity index 100% rename from ios/tooling/RIB Unit Tests.xctemplate/TemplateInfo.plist rename to tooling/RIB Unit Tests.xctemplate/TemplateInfo.plist diff --git a/ios/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___InteractorTests.swift b/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___InteractorTests.swift similarity index 100% rename from ios/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___InteractorTests.swift rename to tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___InteractorTests.swift diff --git a/ios/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___RouterTests.swift b/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___RouterTests.swift similarity index 100% rename from ios/tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___RouterTests.swift rename to tooling/RIB Unit Tests.xctemplate/___FILEBASENAME___RouterTests.swift diff --git a/ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Builder.swift b/tooling/RIB.xctemplate/Default/___FILEBASENAME___Builder.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Builder.swift rename to tooling/RIB.xctemplate/Default/___FILEBASENAME___Builder.swift diff --git a/ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Interactor.swift b/tooling/RIB.xctemplate/Default/___FILEBASENAME___Interactor.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Interactor.swift rename to tooling/RIB.xctemplate/Default/___FILEBASENAME___Interactor.swift diff --git a/ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Router.swift b/tooling/RIB.xctemplate/Default/___FILEBASENAME___Router.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/Default/___FILEBASENAME___Router.swift rename to tooling/RIB.xctemplate/Default/___FILEBASENAME___Router.swift diff --git a/ios/tooling/RIB.xctemplate/TemplateIcon.png b/tooling/RIB.xctemplate/TemplateIcon.png similarity index 100% rename from ios/tooling/RIB.xctemplate/TemplateIcon.png rename to tooling/RIB.xctemplate/TemplateIcon.png diff --git a/ios/tooling/RIB.xctemplate/TemplateIcon@2x.png b/tooling/RIB.xctemplate/TemplateIcon@2x.png similarity index 100% rename from ios/tooling/RIB.xctemplate/TemplateIcon@2x.png rename to tooling/RIB.xctemplate/TemplateIcon@2x.png diff --git a/ios/tooling/RIB.xctemplate/TemplateInfo.plist b/tooling/RIB.xctemplate/TemplateInfo.plist similarity index 100% rename from ios/tooling/RIB.xctemplate/TemplateInfo.plist rename to tooling/RIB.xctemplate/TemplateInfo.plist diff --git a/ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Builder.swift b/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Builder.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Builder.swift rename to tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Builder.swift diff --git a/ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Interactor.swift b/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Interactor.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Interactor.swift rename to tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Interactor.swift diff --git a/ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Router.swift b/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Router.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Router.swift rename to tooling/RIB.xctemplate/ownsView/___FILEBASENAME___Router.swift diff --git a/ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___ViewController.swift b/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___ViewController.swift similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsView/___FILEBASENAME___ViewController.swift rename to tooling/RIB.xctemplate/ownsView/___FILEBASENAME___ViewController.swift diff --git a/ios/tooling/RIB.xctemplate/ownsViewwithStoryboard/___FILEBASENAME___ViewController.storyboard b/tooling/RIB.xctemplate/ownsViewwithStoryboard/___FILEBASENAME___ViewController.storyboard similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsViewwithStoryboard/___FILEBASENAME___ViewController.storyboard rename to tooling/RIB.xctemplate/ownsViewwithStoryboard/___FILEBASENAME___ViewController.storyboard diff --git a/ios/tooling/RIB.xctemplate/ownsViewwithXIB/___FILEBASENAME___ViewController.xib b/tooling/RIB.xctemplate/ownsViewwithXIB/___FILEBASENAME___ViewController.xib similarity index 100% rename from ios/tooling/RIB.xctemplate/ownsViewwithXIB/___FILEBASENAME___ViewController.xib rename to tooling/RIB.xctemplate/ownsViewwithXIB/___FILEBASENAME___ViewController.xib diff --git a/ios/tooling/install-xcode-template.sh b/tooling/install-xcode-template.sh similarity index 100% rename from ios/tooling/install-xcode-template.sh rename to tooling/install-xcode-template.sh diff --git a/tutorials/tutorial1/Podfile b/tutorials/tutorial1/Podfile new file mode 100644 index 0000000..772c37d --- /dev/null +++ b/tutorials/tutorial1/Podfile @@ -0,0 +1,14 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'TicTacToe' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + inhibit_all_warnings! + + # Pods for TicTacToe + pod 'RIBs', :path => '../../' + pod 'SnapKit', '~> 4.0.0' + pod 'RxCocoa', '~> 6.5' + +end diff --git a/ios/tutorials/tutorial1/README.md b/tutorials/tutorial1/README.md similarity index 62% rename from ios/tutorials/tutorial1/README.md rename to tutorials/tutorial1/README.md index d10ee2e..f08f55b 100644 --- a/ios/tutorials/tutorial1/README.md +++ b/tutorials/tutorial1/README.md @@ -19,3 +19,10 @@ pod install ``` Then, open the TicTacToe.xcworkspace that was generated by `pod install` and follow the steps described in [tutorial 1](https://github.com/uber/RIBs/wiki/iOS-Tutorial-1) on the RIBs wiki. + +**Warning**: If you encounter the following error during build execution: + +`SnapKit Pod SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a'; try increasing the minimum deployment target` + +-> Please change the Minimum Deployment Target for SnapKit in the Pods project to **9.0** under TARGETS. + diff --git a/ios/tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj index 0c8b1ff..4de8c28 100644 --- a/ios/tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial1/TicTacToe.xcodeproj/project.pbxproj @@ -384,6 +384,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -398,6 +399,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial1/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial1/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial1/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial1/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial1/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Info.plist b/tutorials/tutorial1/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Info.plist rename to tutorials/tutorial1/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial1/TicTacToe/LoggedOut/DELETE_ME.swift b/tutorials/tutorial1/TicTacToe/LoggedOut/DELETE_ME.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/LoggedOut/DELETE_ME.swift rename to tutorials/tutorial1/TicTacToe/LoggedOut/DELETE_ME.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial1/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial1/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial1/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial1/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial1/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial1/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial1/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial1/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial1/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial1/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial1/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial1/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial1/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial1/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial1/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial2/Podfile b/tutorials/tutorial2/Podfile similarity index 60% rename from ios/tutorials/tutorial2/Podfile rename to tutorials/tutorial2/Podfile index d8c8d77..9f2f653 100644 --- a/ios/tutorials/tutorial2/Podfile +++ b/tutorials/tutorial2/Podfile @@ -4,11 +4,11 @@ use_frameworks! inhibit_all_warnings! target 'TicTacToe' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' + pod 'RxCocoa', '~> 6.5' end target 'TicTacToeTests' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' end diff --git a/ios/tutorials/tutorial2/README.md b/tutorials/tutorial2/README.md similarity index 59% rename from ios/tutorials/tutorial2/README.md rename to tutorials/tutorial2/README.md index 7214602..2c8dc0a 100644 --- a/ios/tutorials/tutorial2/README.md +++ b/tutorials/tutorial2/README.md @@ -18,3 +18,10 @@ pod install ``` Then, open the TicTacToe.xcworkspace that was generated by `pod install` and follow the steps described in [tutorial 2](https://github.com/uber/RIBs/wiki/iOS-Tutorial-2) on the RIBs wiki. + +**Warning**: If you encounter the following error during build execution: + +`SnapKit Pod SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a'; try increasing the minimum deployment target` + +-> Please change the Minimum Deployment Target for SnapKit in the Pods project to **9.0** under TARGETS. + diff --git a/ios/tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj index 0f04442..cfef53a 100644 --- a/ios/tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial2/TicTacToe.xcodeproj/project.pbxproj @@ -569,6 +569,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -583,6 +584,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial2/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial2/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial2/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial2/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial2/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Info.plist b/tutorials/tutorial2/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Info.plist rename to tutorials/tutorial2/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedIn/DELETE_ME.swift b/tutorials/tutorial2/TicTacToe/LoggedIn/DELETE_ME.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedIn/DELETE_ME.swift rename to tutorials/tutorial2/TicTacToe/LoggedIn/DELETE_ME.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift b/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift rename to tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift b/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift rename to tutorials/tutorial2/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutBuilder.swift b/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutBuilder.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutBuilder.swift rename to tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutBuilder.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutInteractor.swift b/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutInteractor.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutInteractor.swift rename to tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutInteractor.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutRouter.swift b/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutRouter.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutRouter.swift rename to tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutRouter.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutViewController.swift b/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutViewController.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutViewController.swift rename to tutorials/tutorial2/TicTacToe/LoggedOut/LoggedOutViewController.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial2/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial2/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial2/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial2/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedIn.swift b/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedIn.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedIn.swift rename to tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedIn.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial2/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial2/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial2/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial2/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial2/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial2/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial2/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeBuilder.swift b/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeBuilder.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeBuilder.swift rename to tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeBuilder.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeInteractor.swift b/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeInteractor.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeInteractor.swift rename to tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeInteractor.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeRouter.swift b/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeRouter.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeRouter.swift rename to tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeRouter.swift diff --git a/ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeViewController.swift b/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeViewController.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeViewController.swift rename to tutorials/tutorial2/TicTacToe/TicTacToe/TicTacToeViewController.swift diff --git a/ios/tutorials/tutorial2/TicTacToeTests/Info.plist b/tutorials/tutorial2/TicTacToeTests/Info.plist similarity index 100% rename from ios/tutorials/tutorial2/TicTacToeTests/Info.plist rename to tutorials/tutorial2/TicTacToeTests/Info.plist diff --git a/ios/tutorials/tutorial2/TicTacToeTests/TicTacToeMocks.swift b/tutorials/tutorial2/TicTacToeTests/TicTacToeMocks.swift similarity index 100% rename from ios/tutorials/tutorial2/TicTacToeTests/TicTacToeMocks.swift rename to tutorials/tutorial2/TicTacToeTests/TicTacToeMocks.swift diff --git a/ios/tutorials/tutorial1/Podfile b/tutorials/tutorial3-completed/Podfile similarity index 65% rename from ios/tutorials/tutorial1/Podfile rename to tutorials/tutorial3-completed/Podfile index 980817e..28e9ef0 100644 --- a/ios/tutorials/tutorial1/Podfile +++ b/tutorials/tutorial3-completed/Podfile @@ -4,7 +4,7 @@ use_frameworks! inhibit_all_warnings! target 'TicTacToe' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' + pod 'RxCocoa', '~> 6.5' end diff --git a/ios/tutorials/tutorial3-completed/README.md b/tutorials/tutorial3-completed/README.md similarity index 100% rename from ios/tutorials/tutorial3-completed/README.md rename to tutorials/tutorial3-completed/README.md diff --git a/ios/tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj index b432bd0..c0ed3d1 100644 --- a/ios/tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial3-completed/TicTacToe.xcodeproj/project.pbxproj @@ -488,6 +488,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -502,6 +503,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial3-completed/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial3-completed/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial3-completed/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial3-completed/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Info.plist b/tutorials/tutorial3-completed/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Info.plist rename to tutorials/tutorial3-completed/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInRouter.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInRouter.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInRouter.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedIn/LoggedInRouter.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift b/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift rename to tutorials/tutorial3-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Models/ScoreStream.swift b/tutorials/tutorial3-completed/TicTacToe/Models/ScoreStream.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Models/ScoreStream.swift rename to tutorials/tutorial3-completed/TicTacToe/Models/ScoreStream.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameBuilder.swift b/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameBuilder.swift rename to tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameBuilder.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameInteractor.swift b/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameInteractor.swift rename to tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameInteractor.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameRouter.swift b/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameRouter.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameRouter.swift rename to tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameRouter.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameViewController.swift b/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameViewController.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameViewController.swift rename to tutorials/tutorial3-completed/TicTacToe/OffGame/OffGameViewController.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial3-completed/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial3-completed/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedIn.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedIn.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedIn.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedIn.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial3-completed/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial3-completed/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift b/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift rename to tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift b/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift rename to tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift b/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift rename to tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift diff --git a/ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift b/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift similarity index 100% rename from ios/tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift rename to tutorials/tutorial3-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift diff --git a/ios/tutorials/tutorial4-completed/Podfile b/tutorials/tutorial3/Podfile similarity index 65% rename from ios/tutorials/tutorial4-completed/Podfile rename to tutorials/tutorial3/Podfile index 980817e..28e9ef0 100644 --- a/ios/tutorials/tutorial4-completed/Podfile +++ b/tutorials/tutorial3/Podfile @@ -4,7 +4,7 @@ use_frameworks! inhibit_all_warnings! target 'TicTacToe' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' + pod 'RxCocoa', '~> 6.5' end diff --git a/ios/tutorials/tutorial3/README.md b/tutorials/tutorial3/README.md similarity index 61% rename from ios/tutorials/tutorial3/README.md rename to tutorials/tutorial3/README.md index 48a0c8d..714d861 100644 --- a/ios/tutorials/tutorial3/README.md +++ b/tutorials/tutorial3/README.md @@ -19,3 +19,10 @@ pod install ``` Then, open the TicTacToe.xcworkspace that was generated by `pod install` and follow the steps described in [tutorial 3](https://github.com/uber/RIBs/wiki/iOS-Tutorial-3) on the RIBs wiki. + +**Warning**: If you encounter the following error during build execution: + +`SnapKit Pod SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a'; try increasing the minimum deployment target` + +-> Please change the Minimum Deployment Target for SnapKit in the Pods project to **9.0** under TARGETS. + diff --git a/ios/tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj index 6e9d0e1..110f276 100644 --- a/ios/tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial3/TicTacToe.xcodeproj/project.pbxproj @@ -476,6 +476,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -490,6 +491,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial3/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial3/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial3/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial3/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial3/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Info.plist b/tutorials/tutorial3/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Info.plist rename to tutorials/tutorial3/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInBuilder.swift b/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInBuilder.swift rename to tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInBuilder.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift b/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift rename to tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift b/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift rename to tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInInteractor.swift b/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInInteractor.swift rename to tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInInteractor.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInRouter.swift b/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInRouter.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInRouter.swift rename to tutorials/tutorial3/TicTacToe/LoggedIn/LoggedInRouter.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutBuilder.swift b/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutBuilder.swift rename to tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutBuilder.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutInteractor.swift b/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutInteractor.swift rename to tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutInteractor.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutRouter.swift b/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutRouter.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutRouter.swift rename to tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutRouter.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutViewController.swift b/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutViewController.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutViewController.swift rename to tutorials/tutorial3/TicTacToe/LoggedOut/LoggedOutViewController.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameBuilder.swift b/tutorials/tutorial3/TicTacToe/OffGame/OffGameBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameBuilder.swift rename to tutorials/tutorial3/TicTacToe/OffGame/OffGameBuilder.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameInteractor.swift b/tutorials/tutorial3/TicTacToe/OffGame/OffGameInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameInteractor.swift rename to tutorials/tutorial3/TicTacToe/OffGame/OffGameInteractor.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameRouter.swift b/tutorials/tutorial3/TicTacToe/OffGame/OffGameRouter.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameRouter.swift rename to tutorials/tutorial3/TicTacToe/OffGame/OffGameRouter.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameViewController.swift b/tutorials/tutorial3/TicTacToe/OffGame/OffGameViewController.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/OffGame/OffGameViewController.swift rename to tutorials/tutorial3/TicTacToe/OffGame/OffGameViewController.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial3/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial3/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial3/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial3/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedIn.swift b/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedIn.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedIn.swift rename to tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedIn.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial3/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial3/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial3/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial3/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial3/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial3/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial3/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeBuilder.swift b/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeBuilder.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeBuilder.swift rename to tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeBuilder.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeInteractor.swift b/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeInteractor.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeInteractor.swift rename to tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeInteractor.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeRouter.swift b/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeRouter.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeRouter.swift rename to tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeRouter.swift diff --git a/ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeViewController.swift b/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeViewController.swift similarity index 100% rename from ios/tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeViewController.swift rename to tutorials/tutorial3/TicTacToe/TicTacToe/TicTacToeViewController.swift diff --git a/ios/tutorials/tutorial3-completed/Podfile b/tutorials/tutorial4-completed/Podfile similarity index 65% rename from ios/tutorials/tutorial3-completed/Podfile rename to tutorials/tutorial4-completed/Podfile index 980817e..28e9ef0 100644 --- a/ios/tutorials/tutorial3-completed/Podfile +++ b/tutorials/tutorial4-completed/Podfile @@ -4,7 +4,7 @@ use_frameworks! inhibit_all_warnings! target 'TicTacToe' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' + pod 'RxCocoa', '~> 6.5' end diff --git a/ios/tutorials/tutorial4-completed/README.md b/tutorials/tutorial4-completed/README.md similarity index 100% rename from ios/tutorials/tutorial4-completed/README.md rename to tutorials/tutorial4-completed/README.md diff --git a/ios/tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj index 9c9f2d5..ab67949 100644 --- a/ios/tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial4-completed/TicTacToe.xcodeproj/project.pbxproj @@ -584,6 +584,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -598,6 +599,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ActionableItems/LoggedInActionableItem.swift b/tutorials/tutorial4-completed/TicTacToe/ActionableItems/LoggedInActionableItem.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ActionableItems/LoggedInActionableItem.swift rename to tutorials/tutorial4-completed/TicTacToe/ActionableItems/LoggedInActionableItem.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ActionableItems/RootActionableItem.swift b/tutorials/tutorial4-completed/TicTacToe/ActionableItems/RootActionableItem.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ActionableItems/RootActionableItem.swift rename to tutorials/tutorial4-completed/TicTacToe/ActionableItems/RootActionableItem.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial4-completed/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial4-completed/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial4-completed/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial4-completed/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Info.plist b/tutorials/tutorial4-completed/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Info.plist rename to tutorials/tutorial4-completed/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/Game.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/Game.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/Game.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/Game.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInRouter.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/LoggedInRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/RandomWinAdapter.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/RandomWinAdapter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/RandomWinAdapter.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/RandomWinAdapter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/TicTacToeAdapter.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedIn/TicTacToeAdapter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedIn/TicTacToeAdapter.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedIn/TicTacToeAdapter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift b/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/LoggedOut/LoggedOutViewController.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Models/PlayerType.swift b/tutorials/tutorial4-completed/TicTacToe/Models/PlayerType.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Models/PlayerType.swift rename to tutorials/tutorial4-completed/TicTacToe/Models/PlayerType.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Models/ScoreStream.swift b/tutorials/tutorial4-completed/TicTacToe/Models/ScoreStream.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Models/ScoreStream.swift rename to tutorials/tutorial4-completed/TicTacToe/Models/ScoreStream.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameRouter.swift b/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameViewController.swift b/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/OffGame/OffGameViewController.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Promo/LaunchGameWorkflow.swift b/tutorials/tutorial4-completed/TicTacToe/Promo/LaunchGameWorkflow.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Promo/LaunchGameWorkflow.swift rename to tutorials/tutorial4-completed/TicTacToe/Promo/LaunchGameWorkflow.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinRouter.swift b/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinViewController.swift b/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/RandomWin/RandomWinViewController.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial4-completed/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial4-completed/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedIn.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedIn.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedIn.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedIn.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial4-completed/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift b/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift b/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift b/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift rename to tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeBuilder.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift b/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift rename to tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeInteractor.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift b/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift rename to tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeRouter.swift diff --git a/ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift b/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift similarity index 100% rename from ios/tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift rename to tutorials/tutorial4-completed/TicTacToe/TicTacToe/TicTacToeViewController.swift diff --git a/ios/tutorials/tutorial3/Podfile b/tutorials/tutorial4/Podfile similarity index 65% rename from ios/tutorials/tutorial3/Podfile rename to tutorials/tutorial4/Podfile index 980817e..28e9ef0 100644 --- a/ios/tutorials/tutorial3/Podfile +++ b/tutorials/tutorial4/Podfile @@ -4,7 +4,7 @@ use_frameworks! inhibit_all_warnings! target 'TicTacToe' do - pod 'RIBs', :path => '../../../' + pod 'RIBs', :path => '../../' pod 'SnapKit', '~> 4.0.0' - pod 'RxCocoa', '~> 5.1' + pod 'RxCocoa', '~> 6.5' end diff --git a/ios/tutorials/tutorial4/README.md b/tutorials/tutorial4/README.md similarity index 59% rename from ios/tutorials/tutorial4/README.md rename to tutorials/tutorial4/README.md index 7303584..e08b748 100644 --- a/ios/tutorials/tutorial4/README.md +++ b/tutorials/tutorial4/README.md @@ -18,3 +18,10 @@ pod install ``` Then, open the TicTacToe.xcworkspace that was generated by `pod install` and follow the steps described in [tutorial 4](https://github.com/uber/RIBs/wiki/iOS-Tutorial-4) on the RIBs wiki. + +**Warning**: If you encounter the following error during build execution: + +`SnapKit Pod SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a'; try increasing the minimum deployment target` + +-> Please change the Minimum Deployment Target for SnapKit in the Pods project to **9.0** under TARGETS. + diff --git a/ios/tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj b/tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj similarity index 99% rename from ios/tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj rename to tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj index 5de64de..3cd8cfb 100644 --- a/ios/tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj +++ b/tutorials/tutorial4/TicTacToe.xcodeproj/project.pbxproj @@ -580,6 +580,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -594,6 +595,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = TicTacToe/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ubercab.TicTacToe; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/tutorials/tutorial4/TicTacToe/ActionableItems/RootActionableItem.swift b/tutorials/tutorial4/TicTacToe/ActionableItems/RootActionableItem.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/ActionableItems/RootActionableItem.swift rename to tutorials/tutorial4/TicTacToe/ActionableItems/RootActionableItem.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/AppStart/AppComponent.swift b/tutorials/tutorial4/TicTacToe/AppStart/AppComponent.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/AppStart/AppComponent.swift rename to tutorials/tutorial4/TicTacToe/AppStart/AppComponent.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/AppStart/AppDelegate.swift b/tutorials/tutorial4/TicTacToe/AppStart/AppDelegate.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/AppStart/AppDelegate.swift rename to tutorials/tutorial4/TicTacToe/AppStart/AppDelegate.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Info.plist b/tutorials/tutorial4/TicTacToe/Info.plist similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Info.plist rename to tutorials/tutorial4/TicTacToe/Info.plist diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/Game.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/Game.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/Game.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/Game.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInBuilder.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInBuilder.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+OffGame.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+RandomWin.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInComponent+TicTacToe.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInInteractor.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInInteractor.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInRouter.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInRouter.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/LoggedInRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/RandomWinAdapter.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/RandomWinAdapter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/RandomWinAdapter.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/RandomWinAdapter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedIn/TicTacToeAdapter.swift b/tutorials/tutorial4/TicTacToe/LoggedIn/TicTacToeAdapter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedIn/TicTacToeAdapter.swift rename to tutorials/tutorial4/TicTacToe/LoggedIn/TicTacToeAdapter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutBuilder.swift b/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutBuilder.swift rename to tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutInteractor.swift b/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutInteractor.swift rename to tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutRouter.swift b/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutRouter.swift rename to tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutViewController.swift b/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutViewController.swift rename to tutorials/tutorial4/TicTacToe/LoggedOut/LoggedOutViewController.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Models/PlayerType.swift b/tutorials/tutorial4/TicTacToe/Models/PlayerType.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Models/PlayerType.swift rename to tutorials/tutorial4/TicTacToe/Models/PlayerType.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Models/ScoreStream.swift b/tutorials/tutorial4/TicTacToe/Models/ScoreStream.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Models/ScoreStream.swift rename to tutorials/tutorial4/TicTacToe/Models/ScoreStream.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameBuilder.swift b/tutorials/tutorial4/TicTacToe/OffGame/OffGameBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameBuilder.swift rename to tutorials/tutorial4/TicTacToe/OffGame/OffGameBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameInteractor.swift b/tutorials/tutorial4/TicTacToe/OffGame/OffGameInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameInteractor.swift rename to tutorials/tutorial4/TicTacToe/OffGame/OffGameInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameRouter.swift b/tutorials/tutorial4/TicTacToe/OffGame/OffGameRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameRouter.swift rename to tutorials/tutorial4/TicTacToe/OffGame/OffGameRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameViewController.swift b/tutorials/tutorial4/TicTacToe/OffGame/OffGameViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/OffGame/OffGameViewController.swift rename to tutorials/tutorial4/TicTacToe/OffGame/OffGameViewController.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Promo/Stub.swift b/tutorials/tutorial4/TicTacToe/Promo/Stub.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Promo/Stub.swift rename to tutorials/tutorial4/TicTacToe/Promo/Stub.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinBuilder.swift b/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinBuilder.swift rename to tutorials/tutorial4/TicTacToe/RandomWin/RandomWinBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinInteractor.swift b/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinInteractor.swift rename to tutorials/tutorial4/TicTacToe/RandomWin/RandomWinInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinRouter.swift b/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinRouter.swift rename to tutorials/tutorial4/TicTacToe/RandomWin/RandomWinRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinViewController.swift b/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/RandomWin/RandomWinViewController.swift rename to tutorials/tutorial4/TicTacToe/RandomWin/RandomWinViewController.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Resources/Default-568h@2x.png b/tutorials/tutorial4/TicTacToe/Resources/Default-568h@2x.png similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Resources/Default-568h@2x.png rename to tutorials/tutorial4/TicTacToe/Resources/Default-568h@2x.png diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootBuilder.swift b/tutorials/tutorial4/TicTacToe/Root/RootBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootBuilder.swift rename to tutorials/tutorial4/TicTacToe/Root/RootBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedIn.swift b/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedIn.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedIn.swift rename to tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedIn.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedOut.swift b/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedOut.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedOut.swift rename to tutorials/tutorial4/TicTacToe/Root/RootComponent+LoggedOut.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootInteractor.swift b/tutorials/tutorial4/TicTacToe/Root/RootInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootInteractor.swift rename to tutorials/tutorial4/TicTacToe/Root/RootInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootRouter.swift b/tutorials/tutorial4/TicTacToe/Root/RootRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootRouter.swift rename to tutorials/tutorial4/TicTacToe/Root/RootRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/Root/RootViewController.swift b/tutorials/tutorial4/TicTacToe/Root/RootViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/Root/RootViewController.swift rename to tutorials/tutorial4/TicTacToe/Root/RootViewController.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift b/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift rename to tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift b/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift rename to tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift b/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift rename to tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift b/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift rename to tutorials/tutorial4/TicTacToe/ScoreBoard/BasicScoreBoardViewController.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeBuilder.swift b/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeBuilder.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeBuilder.swift rename to tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeBuilder.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeInteractor.swift b/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeInteractor.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeInteractor.swift rename to tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeInteractor.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeRouter.swift b/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeRouter.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeRouter.swift rename to tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeRouter.swift diff --git a/ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeViewController.swift b/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeViewController.swift similarity index 100% rename from ios/tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeViewController.swift rename to tutorials/tutorial4/TicTacToe/TicTacToe/TicTacToeViewController.swift