├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── publish-to-trunk-workflow.yml │ └── pull-request-workflow.yml ├── .gitignore ├── .ruby-version ├── .travis.yml ├── Example ├── GettingStarted.playground │ ├── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── Promis.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── Pods-DemoApp │ │ ├── Pods-DemoApp-Info.plist │ │ ├── Pods-DemoApp-acknowledgements.markdown │ │ ├── Pods-DemoApp-acknowledgements.plist │ │ ├── Pods-DemoApp-dummy.m │ │ ├── Pods-DemoApp-frameworks.sh │ │ ├── Pods-DemoApp-umbrella.h │ │ ├── Pods-DemoApp.debug.xcconfig │ │ ├── Pods-DemoApp.modulemap │ │ └── Pods-DemoApp.release.xcconfig │ │ └── Promis │ │ ├── Promis-Info.plist │ │ ├── Promis-Unit-UnitTests-Info.plist │ │ ├── Promis-Unit-UnitTests-frameworks.sh │ │ ├── Promis-Unit-UnitTests-prefix.pch │ │ ├── Promis-dummy.m │ │ ├── Promis-prefix.pch │ │ ├── Promis-umbrella.h │ │ ├── Promis.debug.xcconfig │ │ ├── Promis.modulemap │ │ ├── Promis.release.xcconfig │ │ ├── Promis.unit-unittests.debug.xcconfig │ │ ├── Promis.unit-unittests.release.xcconfig │ │ └── Promis.xcconfig ├── Promis.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── DemoApp.xcscheme ├── Promis.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Promis │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift └── UnitTests.xctestplan ├── Framework └── Sources │ ├── Future+Chaining.swift │ ├── Future+WhenAll.swift │ ├── Future.swift │ ├── FutureState.swift │ ├── PromisError.swift │ └── Promise.swift ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Package.swift ├── Promis.podspec ├── README.md ├── Tests └── Sources │ └── PromisTests.swift └── fastlane ├── Fastfile ├── README.md └── report.xml /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Motivation and Context 7 | 8 | 9 | 10 | ## How Has This Been Tested? 11 | 12 | 13 | 14 | 15 | ## Screenshots (if appropriate): 16 | 17 | ## Types of changes 18 | 19 | - [ ] Bug fix (non-breaking change which fixes an issue) 20 | - [ ] New feature (non-breaking change which adds functionality) 21 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 22 | 23 | ## Checklist: 24 | 25 | 26 | - [ ] My code follows the code style of this project. 27 | - [ ] My change requires a change to the documentation. 28 | - [ ] I have updated the documentation accordingly. 29 | -------------------------------------------------------------------------------- /.github/workflows/publish-to-trunk-workflow.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Trunk 2 | on: 3 | push: 4 | tags: 5 | - '*' 6 | jobs: 7 | build: 8 | runs-on: macOS-latest 9 | steps: 10 | - uses: actions/checkout@v1 11 | - name: Install Cocoapods 12 | run: gem install cocoapods 13 | - name: Deploy to Cocoapods 14 | run: | 15 | set -eo pipefail 16 | export LIB_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) 17 | pod lib lint --allow-warnings 18 | pod trunk push --allow-warnings 19 | env: 20 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 21 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-workflow.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Workflow 2 | on: [pull_request] 3 | jobs: 4 | run-tests: 5 | runs-on: macOS-latest 6 | timeout-minutes: 15 7 | steps: 8 | - name: Cancel previous jobs 9 | uses: styfle/cancel-workflow-action@0.6.0 10 | with: 11 | access_token: ${{ github.token }} 12 | - name: Git checkout 13 | uses: actions/checkout@v2.3.4 14 | with: 15 | fetch-depth: 0 16 | ref: ${{ github.ref }} 17 | - name: Setup Xcode 18 | uses: maxim-lobanov/setup-xcode@v1 19 | with: 20 | xcode-version: latest-stable 21 | - name: Setup ruby and bundler dependencies 22 | uses: ruby/setup-ruby@v1.81.0 23 | with: 24 | bundler-cache: true 25 | - name: Run pod install 26 | run: | 27 | set -eo pipefail 28 | export LIB_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) 29 | bundle exec pod install --project-directory=Example 30 | - name: Run tests (CocoaPods) 31 | run: bundle exec fastlane unit_tests_cocoapods device:'iPhone 11' 32 | - name: Validate lib 33 | run: | 34 | set -eo pipefail 35 | export LIB_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`) 36 | bundle exec pod lib lint --allow-warnings 37 | - name: Run tests (SPM) 38 | run: bundle exec fastlane unit_tests_spm device:'iPhone 11' 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | .build/ 22 | 23 | # Bundler 24 | .bundle 25 | 26 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 27 | # Carthage/Checkouts 28 | 29 | Carthage/Build 30 | 31 | # We recommend against adding the Pods directory to your .gitignore. However 32 | # you should judge for yourself, the pros and cons are mentioned at: 33 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 34 | # 35 | # Note: if you ignore the Pods directory, make sure to uncomment 36 | # `pod install` in .travis.yml 37 | # 38 | # Pods/ 39 | 40 | .swiftpm/ 41 | fastlane/test_output 42 | derived_data/ 43 | Packages/ 44 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.0.2 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | # * https://docs.travis-ci.com/user/languages/objective-c/ 5 | 6 | rvm: 7 | - 2.6.3 8 | 9 | osx_image: xcode10.2 10 | language: swift 11 | 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/Promis.xcworkspace -scheme Promis-Example ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,OS=12.2,name=iPhone X' 14 | - bundle exec pod lib lint --allow-warnings 15 | -------------------------------------------------------------------------------- /Example/GettingStarted.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Promis 3 | 4 | enum GettingStartedError: Error { 5 | case malformedData 6 | } 7 | 8 | //: This is an example of basic usage chaining functions that return futures. The method mimics a common getData-parse-map sequence of actions. 9 | 10 | func basicExample() { 11 | 12 | let request = URLRequest(url: URL(string: "http://example.com")!) 13 | 14 | // starts by hitting an API to download data 15 | getData(request: request).thenWithResult { data in 16 | // continue by parsing the retrieved data 17 | parse(data: data) 18 | }.thenWithResult { parsedData in 19 | // continue by mapping the parsed data 20 | map(data: parsedData) 21 | }.onError { error in 22 | // executed only in case an error occurred in the chain 23 | print("error: " + String(describing: error)) 24 | }.finally(queue: .main) { future in 25 | // always executed, no matter the state of the previous future or how the chain did perform 26 | switch future.state { 27 | case .result(let value): 28 | print(String(describing: value)) 29 | case .error(let err): 30 | print(String(describing: err)) 31 | case .cancelled: 32 | print("future is in a cancelled state") 33 | case .unresolved: 34 | print("this really cannot be if any chaining block is executed") 35 | } 36 | } 37 | } 38 | 39 | func explicitTypesExample() { 40 | 41 | let request = URLRequest(url: URL(string: "http://example.com")!) 42 | 43 | // starts by hitting an API to download data 44 | getData(request: request).then { future -> Future in 45 | // in the `then` continuation we receive the previous future 46 | // useful in case we want to inspect the future state 47 | // here we pass it throught by creating a new future 48 | return Future.futureWithResolution(of: future) 49 | }.thenWithResult { data -> Future<[Dictionary]> in 50 | /** 51 | If a block is not trivial, Swift cannot infer the type of the closure and gives the error 52 | 'Unable to infer complex closure return type; add explicit type to disambiguate' 53 | so you'll have to add `-> Future<<#NextFutureType#>> to the block signature 54 | 55 | You can make the closure complex just by adding any extra statement (like a print). 56 | 57 | All the more reason to structure your code as done in the first given example :) 58 | */ 59 | print("complex closure") 60 | return parse(data: data) 61 | }.thenWithResult { parsedData -> Future<[FooBar]> in 62 | // continue by mapping the parsed data 63 | print("complex closure") 64 | return map(data: parsedData) 65 | }.onError { error in 66 | // executed only in case an error occurred in the chain 67 | // in the case of `onError`, Swift has no problem of inferring the type 68 | // as the block does not return any future, chaining is done using the previous future 69 | print("complex closure") 70 | print("error: " + String(describing: error)) 71 | }.finally(queue: .main) { future in 72 | // always executed, no matter the state of the previous future or how the chain did perform 73 | switch future.state { 74 | case .result(let value): 75 | print(String(describing: value)) 76 | case .error(let err): 77 | print(String(describing: err)) 78 | case .cancelled: 79 | print("future is in a cancelled state") 80 | case .unresolved: 81 | print("this really cannot be if any chaining block is executed") 82 | } 83 | } 84 | } 85 | 86 | //: This method acts as a wrapper of a generic GET request to an API 87 | 88 | func getData(request: URLRequest) -> Future { 89 | print(#function) 90 | print("request: " + String(describing: request)) 91 | let promise = Promise() 92 | // async code retrieving the data here 93 | let data = "[{\"key\":\"value\"}]".data(using: .utf8)! 94 | promise.setResult(data) 95 | return promise.future 96 | } 97 | 98 | //: This method parses a result retrieved from an API as Data 99 | 100 | func parse(data: Data) -> Future<[Dictionary]> { 101 | print(#function) 102 | print("data: " + String(describing: data)) 103 | let promise = Promise<[Dictionary]>() 104 | // parsing code here 105 | do { 106 | let parsedData = try JSONSerialization.jsonObject(with: data, options: []) as! [Dictionary] 107 | promise.setResult(parsedData) 108 | } catch { 109 | promise.setError(error) 110 | } 111 | // could simply return promise.future, but specific error handling/logging 112 | // should be done here as part of the responsibilities of the function 113 | return promise.future.onError {error in 114 | // handle/log error 115 | } 116 | } 117 | 118 | struct FooBar { 119 | let value: String 120 | } 121 | 122 | //: This method maps the previously parsed data to domain-specific object(s) 123 | 124 | func map(data: [Dictionary]) -> Future<[FooBar]> { 125 | print(#function) 126 | print("data: " + String(describing: data)) 127 | let promise = Promise<[FooBar]>() 128 | promise.setResult(data.compactMap { obj -> FooBar? in 129 | if let value = obj["key"] as? String { 130 | return FooBar(value: value) 131 | } 132 | return nil 133 | }) 134 | return promise.future 135 | } 136 | 137 | basicExample() 138 | -------------------------------------------------------------------------------- /Example/GettingStarted.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/GettingStarted.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://cdn.cocoapods.org/' 2 | 3 | use_frameworks! 4 | 5 | target 'DemoApp' do 6 | platform :ios, 13.0 7 | 8 | pod 'Promis', :path => '../', :testspecs => ['UnitTests'] 9 | 10 | end 11 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Promis (2.2.0) 3 | - Promis/UnitTests (2.2.0) 4 | 5 | DEPENDENCIES: 6 | - Promis (from `../`) 7 | - Promis/UnitTests (from `../`) 8 | 9 | EXTERNAL SOURCES: 10 | Promis: 11 | :path: "../" 12 | 13 | SPEC CHECKSUMS: 14 | Promis: cb43375a9674d5bce6823de98d951f4d1307cbc7 15 | 16 | PODFILE CHECKSUM: 2caa75d2621c0c8241e46fbd838a1f1d846c02f8 17 | 18 | COCOAPODS: 1.11.3 19 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/Promis.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Promis", 3 | "version": "2.2.0", 4 | "summary": "The easiest Future and Promises framework in Swift. No magic. No boilerplate.", 5 | "description": "The easiest Future and Promises framework in Swift. No magic. No boilerplate.\n- Fully unit-tested and documented 💯\n- Thread-safe 🚦\n- Clean interface 👼\n- Support for chaining ⛓\n- Support for cancellation 🙅‍♂️\n- Queue-based block execution if needed 🚆\n- Result type provided via generics 🚀\n- Keeping the magic to the minimum, leaving the code in a readable state without going off of a tangent with fancy and unnecessary design decisions ಠ_ಠ", 6 | "homepage": "https://github.com/albertodebortoli/Promis", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Alberto De Bortoli": "albertodebortoli.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/albertodebortoli/Promis.git", 16 | "tag": "2.2.0" 17 | }, 18 | "social_media_url": "https://twitter.com/albertodebo", 19 | "platforms": { 20 | "ios": "13.0", 21 | "watchos": "4.0" 22 | }, 23 | "swift_versions": "5.0", 24 | "source_files": "Framework/Sources/**/*.swift", 25 | "frameworks": "Foundation", 26 | "testspecs": [ 27 | { 28 | "name": "UnitTests", 29 | "test_type": "unit", 30 | "source_files": "Tests/Sources/**/*.swift" 31 | } 32 | ], 33 | "swift_version": "5.0" 34 | } 35 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Promis (2.2.0) 3 | - Promis/UnitTests (2.2.0) 4 | 5 | DEPENDENCIES: 6 | - Promis (from `../`) 7 | - Promis/UnitTests (from `../`) 8 | 9 | EXTERNAL SOURCES: 10 | Promis: 11 | :path: "../" 12 | 13 | SPEC CHECKSUMS: 14 | Promis: cb43375a9674d5bce6823de98d951f4d1307cbc7 15 | 16 | PODFILE CHECKSUM: 2caa75d2621c0c8241e46fbd838a1f1d846c02f8 17 | 18 | COCOAPODS: 1.11.3 19 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 27599C6B9A3FFC721798167DAD647CC0 /* Future+WhenAll.swift in Sources */ = {isa = PBXBuildFile; fileRef = F16AFD34D46A48B051580058EC637562 /* Future+WhenAll.swift */; }; 11 | 44B12919AE0632A53D8243A508CDB515 /* Pods-DemoApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AA908D121ABF1F446FF239741E14A5 /* Pods-DemoApp-dummy.m */; }; 12 | 4CC8FAAD38305D89F6FC7396EB1643F3 /* FutureState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916ABDD6CC42E62EB3626CC902FE0485 /* FutureState.swift */; }; 13 | 69303F1EDD3C285E49A0C86DB3217550 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 14 | 77099C5DAF45B7E0FBEF6A3325190FF6 /* PromisError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5762BB6791C6CE8C4A3CA4F4F6B24C8 /* PromisError.swift */; }; 15 | 79095444F07EA8F096EACF06F311AEF0 /* Promis-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 721F0C8C74B335B7577B8FCE225C8347 /* Promis-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 7A84375A8C559073C8F3FBF081BC13DC /* Future.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37AB34A3B35F3D3BCC1D36410261297 /* Future.swift */; }; 17 | 7DFDBE2BC3CBA60FD4C37E654FF3611A /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A11C1F3D5D0826C25F62EA27D33A5C /* Promise.swift */; }; 18 | A1BC41906E92A2DD5D0A03A17F81455A /* Pods-DemoApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 699A7073FA37A911ADA3E1967F70BE98 /* Pods-DemoApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | A8B670F0F402B750F2CAE22599CFFB95 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 20 | CCD9136B4097D6C76EBBAFA42E70E67A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 21 | E033367AF24FCA8D304904AEA65EAEEF /* Future+Chaining.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF4F3E73CF9662470681AC3DBB1B92D8 /* Future+Chaining.swift */; }; 22 | E67125C7843846B20A1C2084E81ECE74 /* PromisTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C23DC77344B513778EF5F6869D963F06 /* PromisTests.swift */; }; 23 | F74DC5648EAF693C00E3BF99C8162E66 /* Promis-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 65A36F56F245B838A5370EE56DC4DB74 /* Promis-dummy.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 20661D99B322876A8440F24BFE7668BA /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = E1400FA1180B6A8188795D86A04FED99; 32 | remoteInfo = Promis; 33 | }; 34 | E4B458ACAA9922EC47BA52DA6CBF0AC8 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = E1400FA1180B6A8188795D86A04FED99; 39 | remoteInfo = Promis; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 075150ECA1E0623D8301A4B53DE9887A /* Promis-Unit-UnitTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Promis-Unit-UnitTests-frameworks.sh"; sourceTree = ""; }; 45 | 21B1E3429ADA9F0E77325B777FA3C9F9 /* Promis-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Promis-prefix.pch"; sourceTree = ""; }; 46 | 2201E7F9A0CF5EAA7C0EC59FE5C533DF /* Promis.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Promis.debug.xcconfig; sourceTree = ""; }; 47 | 22B064629CAE40CF72499DD6D67646C1 /* Pods-DemoApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-DemoApp-acknowledgements.markdown"; sourceTree = ""; }; 48 | 30ECF4A814EAC27404B9C457B70ED163 /* Promis-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Promis-Info.plist"; sourceTree = ""; }; 49 | 3FF9AA39240D697DFA11DB6BEB025672 /* Promis.unit-unittests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Promis.unit-unittests.debug.xcconfig"; sourceTree = ""; }; 50 | 4BB88D853188CA5EA957B099B2AE1E3D /* Promis.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Promis.modulemap; sourceTree = ""; }; 51 | 4CCC77C9855BB404DA571145F80135AB /* Promis */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Promis; path = Promis.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 4FE3A8914DCE32ADB404396D24D8F340 /* Pods-DemoApp */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-DemoApp"; path = Pods_DemoApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 54B7B3E96E1ADD7DD58C79E4C069D51E /* Promis-Unit-UnitTests */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "Promis-Unit-UnitTests"; path = "Promis-Unit-UnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 64F7736E91647FB1D500612961266F46 /* Pods-DemoApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-DemoApp.modulemap"; sourceTree = ""; }; 55 | 65A36F56F245B838A5370EE56DC4DB74 /* Promis-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Promis-dummy.m"; sourceTree = ""; }; 56 | 699A7073FA37A911ADA3E1967F70BE98 /* Pods-DemoApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DemoApp-umbrella.h"; sourceTree = ""; }; 57 | 721F0C8C74B335B7577B8FCE225C8347 /* Promis-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Promis-umbrella.h"; sourceTree = ""; }; 58 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 59 | 77AA908D121ABF1F446FF239741E14A5 /* Pods-DemoApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DemoApp-dummy.m"; sourceTree = ""; }; 60 | 916ABDD6CC42E62EB3626CC902FE0485 /* FutureState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FutureState.swift; path = Framework/Sources/FutureState.swift; sourceTree = ""; }; 61 | 946B1D3001B616EC334839A46A26A4D3 /* Pods-DemoApp-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DemoApp-frameworks.sh"; sourceTree = ""; }; 62 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 63 | 9F7A6AB650186BBFA9159A38A50E2B90 /* Promis-Unit-UnitTests-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Promis-Unit-UnitTests-prefix.pch"; sourceTree = ""; }; 64 | A37AB34A3B35F3D3BCC1D36410261297 /* Future.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Future.swift; path = Framework/Sources/Future.swift; sourceTree = ""; }; 65 | A41D60470BFE3915CC345DE5CCF8BC67 /* Pods-DemoApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DemoApp.release.xcconfig"; sourceTree = ""; }; 66 | AC2459E3AAD268B3B4BD79CDBC41F6B1 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 67 | B5F783EE6776FC44B69546B436F5B3D4 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 68 | B6A11C1F3D5D0826C25F62EA27D33A5C /* Promise.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Promise.swift; path = Framework/Sources/Promise.swift; sourceTree = ""; }; 69 | C23DC77344B513778EF5F6869D963F06 /* PromisTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PromisTests.swift; path = Tests/Sources/PromisTests.swift; sourceTree = ""; }; 70 | C3CB5CC796F6A53577ADB97FD22E398D /* Pods-DemoApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DemoApp-acknowledgements.plist"; sourceTree = ""; }; 71 | C3CDBD0667486A1EC37B94D0C03ECA1D /* Promis-Unit-UnitTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Promis-Unit-UnitTests-Info.plist"; sourceTree = ""; }; 72 | CF4F3E73CF9662470681AC3DBB1B92D8 /* Future+Chaining.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Future+Chaining.swift"; path = "Framework/Sources/Future+Chaining.swift"; sourceTree = ""; }; 73 | CFE6D53984A966705CAE68796D630C06 /* Promis.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Promis.release.xcconfig; sourceTree = ""; }; 74 | D5762BB6791C6CE8C4A3CA4F4F6B24C8 /* PromisError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PromisError.swift; path = Framework/Sources/PromisError.swift; sourceTree = ""; }; 75 | E29370E385DA63D6CAFB58EECFC6BFBB /* Pods-DemoApp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DemoApp-Info.plist"; sourceTree = ""; }; 76 | E604BEE3D7EE8204E2EA307754FDE881 /* Pods-DemoApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DemoApp.debug.xcconfig"; sourceTree = ""; }; 77 | F007A249A540F2AC6C21D690AAFB2608 /* Promis.unit-unittests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Promis.unit-unittests.release.xcconfig"; sourceTree = ""; }; 78 | F16AFD34D46A48B051580058EC637562 /* Future+WhenAll.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Future+WhenAll.swift"; path = "Framework/Sources/Future+WhenAll.swift"; sourceTree = ""; }; 79 | FAFA7801312D593B328E035E547A7F18 /* Promis.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = Promis.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 44BD09DE3CBD162CF0B2AC0423AC3823 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | A8B670F0F402B750F2CAE22599CFFB95 /* Foundation.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 68A7835268140BC72DA89835327E38C3 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | 69303F1EDD3C285E49A0C86DB3217550 /* Foundation.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | B8D1E4684696307DAABA90944E9772C1 /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | CCD9136B4097D6C76EBBAFA42E70E67A /* Foundation.framework in Frameworks */, 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | 384622BB8BCE6DCEC6A6183ABBD2DD57 /* Promis */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | A37AB34A3B35F3D3BCC1D36410261297 /* Future.swift */, 114 | CF4F3E73CF9662470681AC3DBB1B92D8 /* Future+Chaining.swift */, 115 | F16AFD34D46A48B051580058EC637562 /* Future+WhenAll.swift */, 116 | 916ABDD6CC42E62EB3626CC902FE0485 /* FutureState.swift */, 117 | B6A11C1F3D5D0826C25F62EA27D33A5C /* Promise.swift */, 118 | D5762BB6791C6CE8C4A3CA4F4F6B24C8 /* PromisError.swift */, 119 | 6062EC235575E31369CF2EC1CBAC54DB /* Pod */, 120 | AF4B2B4EF4F2704DCE11EBC8298641C7 /* Support Files */, 121 | C88C570EA33FC475677365DCFA343EA3 /* UnitTests */, 122 | ); 123 | name = Promis; 124 | path = ../..; 125 | sourceTree = ""; 126 | }; 127 | 4DF636EA3CB042B100D265CBAEE9CA83 /* Pods-DemoApp */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 64F7736E91647FB1D500612961266F46 /* Pods-DemoApp.modulemap */, 131 | 22B064629CAE40CF72499DD6D67646C1 /* Pods-DemoApp-acknowledgements.markdown */, 132 | C3CB5CC796F6A53577ADB97FD22E398D /* Pods-DemoApp-acknowledgements.plist */, 133 | 77AA908D121ABF1F446FF239741E14A5 /* Pods-DemoApp-dummy.m */, 134 | 946B1D3001B616EC334839A46A26A4D3 /* Pods-DemoApp-frameworks.sh */, 135 | E29370E385DA63D6CAFB58EECFC6BFBB /* Pods-DemoApp-Info.plist */, 136 | 699A7073FA37A911ADA3E1967F70BE98 /* Pods-DemoApp-umbrella.h */, 137 | E604BEE3D7EE8204E2EA307754FDE881 /* Pods-DemoApp.debug.xcconfig */, 138 | A41D60470BFE3915CC345DE5CCF8BC67 /* Pods-DemoApp.release.xcconfig */, 139 | ); 140 | name = "Pods-DemoApp"; 141 | path = "Target Support Files/Pods-DemoApp"; 142 | sourceTree = ""; 143 | }; 144 | 578452D2E740E91742655AC8F1636D1F /* iOS */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, 148 | ); 149 | name = iOS; 150 | sourceTree = ""; 151 | }; 152 | 6062EC235575E31369CF2EC1CBAC54DB /* Pod */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | B5F783EE6776FC44B69546B436F5B3D4 /* LICENSE */, 156 | FAFA7801312D593B328E035E547A7F18 /* Promis.podspec */, 157 | AC2459E3AAD268B3B4BD79CDBC41F6B1 /* README.md */, 158 | ); 159 | name = Pod; 160 | sourceTree = ""; 161 | }; 162 | AD8113861F21DEBD7BFF2B3D85673069 /* Products */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 4FE3A8914DCE32ADB404396D24D8F340 /* Pods-DemoApp */, 166 | 4CCC77C9855BB404DA571145F80135AB /* Promis */, 167 | 54B7B3E96E1ADD7DD58C79E4C069D51E /* Promis-Unit-UnitTests */, 168 | ); 169 | name = Products; 170 | sourceTree = ""; 171 | }; 172 | AF4B2B4EF4F2704DCE11EBC8298641C7 /* Support Files */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 4BB88D853188CA5EA957B099B2AE1E3D /* Promis.modulemap */, 176 | 65A36F56F245B838A5370EE56DC4DB74 /* Promis-dummy.m */, 177 | 30ECF4A814EAC27404B9C457B70ED163 /* Promis-Info.plist */, 178 | 21B1E3429ADA9F0E77325B777FA3C9F9 /* Promis-prefix.pch */, 179 | 721F0C8C74B335B7577B8FCE225C8347 /* Promis-umbrella.h */, 180 | 075150ECA1E0623D8301A4B53DE9887A /* Promis-Unit-UnitTests-frameworks.sh */, 181 | C3CDBD0667486A1EC37B94D0C03ECA1D /* Promis-Unit-UnitTests-Info.plist */, 182 | 9F7A6AB650186BBFA9159A38A50E2B90 /* Promis-Unit-UnitTests-prefix.pch */, 183 | 2201E7F9A0CF5EAA7C0EC59FE5C533DF /* Promis.debug.xcconfig */, 184 | CFE6D53984A966705CAE68796D630C06 /* Promis.release.xcconfig */, 185 | 3FF9AA39240D697DFA11DB6BEB025672 /* Promis.unit-unittests.debug.xcconfig */, 186 | F007A249A540F2AC6C21D690AAFB2608 /* Promis.unit-unittests.release.xcconfig */, 187 | ); 188 | name = "Support Files"; 189 | path = "Example/Pods/Target Support Files/Promis"; 190 | sourceTree = ""; 191 | }; 192 | C88C570EA33FC475677365DCFA343EA3 /* UnitTests */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | C23DC77344B513778EF5F6869D963F06 /* PromisTests.swift */, 196 | ); 197 | name = UnitTests; 198 | sourceTree = ""; 199 | }; 200 | C8925A89FCC6A7A7E3FC80329E7EED75 /* Targets Support Files */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 4DF636EA3CB042B100D265CBAEE9CA83 /* Pods-DemoApp */, 204 | ); 205 | name = "Targets Support Files"; 206 | sourceTree = ""; 207 | }; 208 | CF1408CF629C7361332E53B88F7BD30C = { 209 | isa = PBXGroup; 210 | children = ( 211 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, 212 | D25ECE3B0434162D44CCE3BA3E25BFAC /* Development Pods */, 213 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, 214 | AD8113861F21DEBD7BFF2B3D85673069 /* Products */, 215 | C8925A89FCC6A7A7E3FC80329E7EED75 /* Targets Support Files */, 216 | ); 217 | sourceTree = ""; 218 | }; 219 | D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | 578452D2E740E91742655AC8F1636D1F /* iOS */, 223 | ); 224 | name = Frameworks; 225 | sourceTree = ""; 226 | }; 227 | D25ECE3B0434162D44CCE3BA3E25BFAC /* Development Pods */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | 384622BB8BCE6DCEC6A6183ABBD2DD57 /* Promis */, 231 | ); 232 | name = "Development Pods"; 233 | sourceTree = ""; 234 | }; 235 | /* End PBXGroup section */ 236 | 237 | /* Begin PBXHeadersBuildPhase section */ 238 | 04F0A9B2810CF32B01F08F18C7C35186 /* Headers */ = { 239 | isa = PBXHeadersBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | A1BC41906E92A2DD5D0A03A17F81455A /* Pods-DemoApp-umbrella.h in Headers */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | 0C441CA0A4777418BDF32DC928E2F9DF /* Headers */ = { 247 | isa = PBXHeadersBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 79095444F07EA8F096EACF06F311AEF0 /* Promis-umbrella.h in Headers */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | /* End PBXHeadersBuildPhase section */ 255 | 256 | /* Begin PBXNativeTarget section */ 257 | 1BC258032FFF5C240A561B274C5D07F4 /* Pods-DemoApp */ = { 258 | isa = PBXNativeTarget; 259 | buildConfigurationList = 1EE314B90DD227C75A4B234EFAE47D25 /* Build configuration list for PBXNativeTarget "Pods-DemoApp" */; 260 | buildPhases = ( 261 | 04F0A9B2810CF32B01F08F18C7C35186 /* Headers */, 262 | 6A32D537E29D7B9ECB784E3CD5D73230 /* Sources */, 263 | 68A7835268140BC72DA89835327E38C3 /* Frameworks */, 264 | 464FB643A9527D07B34BBAB07095833A /* Resources */, 265 | ); 266 | buildRules = ( 267 | ); 268 | dependencies = ( 269 | 699098B1D57968F65B20BCF592AC19DC /* PBXTargetDependency */, 270 | ); 271 | name = "Pods-DemoApp"; 272 | productName = Pods_DemoApp; 273 | productReference = 4FE3A8914DCE32ADB404396D24D8F340 /* Pods-DemoApp */; 274 | productType = "com.apple.product-type.framework"; 275 | }; 276 | 295F351793509221CE75C7DD4981ADAA /* Promis-Unit-UnitTests */ = { 277 | isa = PBXNativeTarget; 278 | buildConfigurationList = B007BE62AC18191A8336680A24D288A5 /* Build configuration list for PBXNativeTarget "Promis-Unit-UnitTests" */; 279 | buildPhases = ( 280 | B2C38C0A3CC0BAEA6288785326B0B6E6 /* Sources */, 281 | 44BD09DE3CBD162CF0B2AC0423AC3823 /* Frameworks */, 282 | 3D0CCD80507DE04A2449B4C514E28E26 /* Resources */, 283 | 697D361A3838DCC94421122881139CDD /* [CP] Embed Pods Frameworks */, 284 | ); 285 | buildRules = ( 286 | ); 287 | dependencies = ( 288 | DD72A295D571614761558EF426E47375 /* PBXTargetDependency */, 289 | ); 290 | name = "Promis-Unit-UnitTests"; 291 | productName = "Promis-Unit-UnitTests"; 292 | productReference = 54B7B3E96E1ADD7DD58C79E4C069D51E /* Promis-Unit-UnitTests */; 293 | productType = "com.apple.product-type.bundle.unit-test"; 294 | }; 295 | E1400FA1180B6A8188795D86A04FED99 /* Promis */ = { 296 | isa = PBXNativeTarget; 297 | buildConfigurationList = 3977601545D8410F27106A6B3DD05EBA /* Build configuration list for PBXNativeTarget "Promis" */; 298 | buildPhases = ( 299 | 0C441CA0A4777418BDF32DC928E2F9DF /* Headers */, 300 | 907DC73995247A83962CFE86729F1FD8 /* Sources */, 301 | B8D1E4684696307DAABA90944E9772C1 /* Frameworks */, 302 | 3B1BF841B6EA2129D5DAADA72E4A9063 /* Resources */, 303 | ); 304 | buildRules = ( 305 | ); 306 | dependencies = ( 307 | ); 308 | name = Promis; 309 | productName = Promis; 310 | productReference = 4CCC77C9855BB404DA571145F80135AB /* Promis */; 311 | productType = "com.apple.product-type.framework"; 312 | }; 313 | /* End PBXNativeTarget section */ 314 | 315 | /* Begin PBXProject section */ 316 | BFDFE7DC352907FC980B868725387E98 /* Project object */ = { 317 | isa = PBXProject; 318 | attributes = { 319 | LastSwiftUpdateCheck = 1240; 320 | LastUpgradeCheck = 1240; 321 | }; 322 | buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; 323 | compatibilityVersion = "Xcode 3.2"; 324 | developmentRegion = en; 325 | hasScannedForEncodings = 0; 326 | knownRegions = ( 327 | Base, 328 | en, 329 | ); 330 | mainGroup = CF1408CF629C7361332E53B88F7BD30C; 331 | productRefGroup = AD8113861F21DEBD7BFF2B3D85673069 /* Products */; 332 | projectDirPath = ""; 333 | projectRoot = ""; 334 | targets = ( 335 | 1BC258032FFF5C240A561B274C5D07F4 /* Pods-DemoApp */, 336 | E1400FA1180B6A8188795D86A04FED99 /* Promis */, 337 | 295F351793509221CE75C7DD4981ADAA /* Promis-Unit-UnitTests */, 338 | ); 339 | }; 340 | /* End PBXProject section */ 341 | 342 | /* Begin PBXResourcesBuildPhase section */ 343 | 3B1BF841B6EA2129D5DAADA72E4A9063 /* Resources */ = { 344 | isa = PBXResourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | 3D0CCD80507DE04A2449B4C514E28E26 /* Resources */ = { 351 | isa = PBXResourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | }; 357 | 464FB643A9527D07B34BBAB07095833A /* Resources */ = { 358 | isa = PBXResourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | }; 364 | /* End PBXResourcesBuildPhase section */ 365 | 366 | /* Begin PBXShellScriptBuildPhase section */ 367 | 697D361A3838DCC94421122881139CDD /* [CP] Embed Pods Frameworks */ = { 368 | isa = PBXShellScriptBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | ); 372 | inputPaths = ( 373 | "${PODS_ROOT}/Target Support Files/Promis/Promis-Unit-UnitTests-frameworks.sh", 374 | "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework", 375 | ); 376 | name = "[CP] Embed Pods Frameworks"; 377 | outputPaths = ( 378 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Promis.framework", 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | shellPath = /bin/sh; 382 | shellScript = "\"${PODS_ROOT}/Target Support Files/Promis/Promis-Unit-UnitTests-frameworks.sh\"\n"; 383 | showEnvVarsInLog = 0; 384 | }; 385 | /* End PBXShellScriptBuildPhase section */ 386 | 387 | /* Begin PBXSourcesBuildPhase section */ 388 | 6A32D537E29D7B9ECB784E3CD5D73230 /* Sources */ = { 389 | isa = PBXSourcesBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | 44B12919AE0632A53D8243A508CDB515 /* Pods-DemoApp-dummy.m in Sources */, 393 | ); 394 | runOnlyForDeploymentPostprocessing = 0; 395 | }; 396 | 907DC73995247A83962CFE86729F1FD8 /* Sources */ = { 397 | isa = PBXSourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | 7A84375A8C559073C8F3FBF081BC13DC /* Future.swift in Sources */, 401 | E033367AF24FCA8D304904AEA65EAEEF /* Future+Chaining.swift in Sources */, 402 | 27599C6B9A3FFC721798167DAD647CC0 /* Future+WhenAll.swift in Sources */, 403 | 4CC8FAAD38305D89F6FC7396EB1643F3 /* FutureState.swift in Sources */, 404 | F74DC5648EAF693C00E3BF99C8162E66 /* Promis-dummy.m in Sources */, 405 | 7DFDBE2BC3CBA60FD4C37E654FF3611A /* Promise.swift in Sources */, 406 | 77099C5DAF45B7E0FBEF6A3325190FF6 /* PromisError.swift in Sources */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | B2C38C0A3CC0BAEA6288785326B0B6E6 /* Sources */ = { 411 | isa = PBXSourcesBuildPhase; 412 | buildActionMask = 2147483647; 413 | files = ( 414 | E67125C7843846B20A1C2084E81ECE74 /* PromisTests.swift in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | /* End PBXSourcesBuildPhase section */ 419 | 420 | /* Begin PBXTargetDependency section */ 421 | 699098B1D57968F65B20BCF592AC19DC /* PBXTargetDependency */ = { 422 | isa = PBXTargetDependency; 423 | name = Promis; 424 | target = E1400FA1180B6A8188795D86A04FED99 /* Promis */; 425 | targetProxy = E4B458ACAA9922EC47BA52DA6CBF0AC8 /* PBXContainerItemProxy */; 426 | }; 427 | DD72A295D571614761558EF426E47375 /* PBXTargetDependency */ = { 428 | isa = PBXTargetDependency; 429 | name = Promis; 430 | target = E1400FA1180B6A8188795D86A04FED99 /* Promis */; 431 | targetProxy = 20661D99B322876A8440F24BFE7668BA /* PBXContainerItemProxy */; 432 | }; 433 | /* End PBXTargetDependency section */ 434 | 435 | /* Begin XCBuildConfiguration section */ 436 | 1371FA0E7533345FF011C200B233108E /* Debug */ = { 437 | isa = XCBuildConfiguration; 438 | baseConfigurationReference = 3FF9AA39240D697DFA11DB6BEB025672 /* Promis.unit-unittests.debug.xcconfig */; 439 | buildSettings = { 440 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 441 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 442 | CLANG_ENABLE_OBJC_WEAK = NO; 443 | CODE_SIGNING_ALLOWED = YES; 444 | CODE_SIGNING_REQUIRED = YES; 445 | CODE_SIGN_IDENTITY = "iPhone Developer"; 446 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 447 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 448 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 449 | GCC_PREFIX_HEADER = "Target Support Files/Promis/Promis-Unit-UnitTests-prefix.pch"; 450 | INFOPLIST_FILE = "Target Support Files/Promis/Promis-Unit-UnitTests-Info.plist"; 451 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 452 | PRODUCT_NAME = "Promis-Unit-UnitTests"; 453 | SDKROOT = iphoneos; 454 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 455 | SWIFT_VERSION = 5.0; 456 | }; 457 | name = Debug; 458 | }; 459 | 234F3E18A88C6DBF7769088C2AD40F30 /* Release */ = { 460 | isa = XCBuildConfiguration; 461 | baseConfigurationReference = F007A249A540F2AC6C21D690AAFB2608 /* Promis.unit-unittests.release.xcconfig */; 462 | buildSettings = { 463 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 464 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 465 | CLANG_ENABLE_OBJC_WEAK = NO; 466 | CODE_SIGNING_ALLOWED = YES; 467 | CODE_SIGNING_REQUIRED = YES; 468 | CODE_SIGN_IDENTITY = "iPhone Developer"; 469 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 471 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 472 | GCC_PREFIX_HEADER = "Target Support Files/Promis/Promis-Unit-UnitTests-prefix.pch"; 473 | INFOPLIST_FILE = "Target Support Files/Promis/Promis-Unit-UnitTests-Info.plist"; 474 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 475 | PRODUCT_NAME = "Promis-Unit-UnitTests"; 476 | SDKROOT = iphoneos; 477 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 478 | SWIFT_VERSION = 5.0; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 3761A78A83D1607C1681C593C6058FAF /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = 2201E7F9A0CF5EAA7C0EC59FE5C533DF /* Promis.debug.xcconfig */; 486 | buildSettings = { 487 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 488 | CLANG_ENABLE_OBJC_WEAK = NO; 489 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 490 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 491 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 492 | CURRENT_PROJECT_VERSION = 1; 493 | DEFINES_MODULE = YES; 494 | DYLIB_COMPATIBILITY_VERSION = 1; 495 | DYLIB_CURRENT_VERSION = 1; 496 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 497 | GCC_PREFIX_HEADER = "Target Support Files/Promis/Promis-prefix.pch"; 498 | INFOPLIST_FILE = "Target Support Files/Promis/Promis-Info.plist"; 499 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 500 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 502 | MODULEMAP_FILE = "Target Support Files/Promis/Promis.modulemap"; 503 | PRODUCT_MODULE_NAME = Promis; 504 | PRODUCT_NAME = Promis; 505 | SDKROOT = iphoneos; 506 | SKIP_INSTALL = YES; 507 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 508 | SWIFT_VERSION = 5.0; 509 | TARGETED_DEVICE_FAMILY = "1,2"; 510 | VERSIONING_SYSTEM = "apple-generic"; 511 | VERSION_INFO_PREFIX = ""; 512 | }; 513 | name = Debug; 514 | }; 515 | 820A000B37C59B11A1ECB4EA38EDD9B3 /* Debug */ = { 516 | isa = XCBuildConfiguration; 517 | baseConfigurationReference = E604BEE3D7EE8204E2EA307754FDE881 /* Pods-DemoApp.debug.xcconfig */; 518 | buildSettings = { 519 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 520 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 521 | CLANG_ENABLE_OBJC_WEAK = NO; 522 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 523 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 524 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 525 | CURRENT_PROJECT_VERSION = 1; 526 | DEFINES_MODULE = YES; 527 | DYLIB_COMPATIBILITY_VERSION = 1; 528 | DYLIB_CURRENT_VERSION = 1; 529 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 530 | INFOPLIST_FILE = "Target Support Files/Pods-DemoApp/Pods-DemoApp-Info.plist"; 531 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 532 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 533 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 534 | MACH_O_TYPE = staticlib; 535 | MODULEMAP_FILE = "Target Support Files/Pods-DemoApp/Pods-DemoApp.modulemap"; 536 | OTHER_LDFLAGS = ""; 537 | OTHER_LIBTOOLFLAGS = ""; 538 | PODS_ROOT = "$(SRCROOT)"; 539 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 540 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 541 | SDKROOT = iphoneos; 542 | SKIP_INSTALL = YES; 543 | TARGETED_DEVICE_FAMILY = "1,2"; 544 | VERSIONING_SYSTEM = "apple-generic"; 545 | VERSION_INFO_PREFIX = ""; 546 | }; 547 | name = Debug; 548 | }; 549 | 8DE5143C03248BB6CD542DE3963D6F3A /* Debug */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | ALWAYS_SEARCH_USER_PATHS = NO; 553 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 554 | CLANG_ANALYZER_NONNULL = YES; 555 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 556 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 557 | CLANG_CXX_LIBRARY = "libc++"; 558 | CLANG_ENABLE_MODULES = YES; 559 | CLANG_ENABLE_OBJC_ARC = YES; 560 | CLANG_ENABLE_OBJC_WEAK = YES; 561 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 562 | CLANG_WARN_BOOL_CONVERSION = YES; 563 | CLANG_WARN_COMMA = YES; 564 | CLANG_WARN_CONSTANT_CONVERSION = YES; 565 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 566 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 567 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 568 | CLANG_WARN_EMPTY_BODY = YES; 569 | CLANG_WARN_ENUM_CONVERSION = YES; 570 | CLANG_WARN_INFINITE_RECURSION = YES; 571 | CLANG_WARN_INT_CONVERSION = YES; 572 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 573 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 574 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 575 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 576 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 577 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 578 | CLANG_WARN_STRICT_PROTOTYPES = YES; 579 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 580 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 581 | CLANG_WARN_UNREACHABLE_CODE = YES; 582 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 583 | COPY_PHASE_STRIP = NO; 584 | DEBUG_INFORMATION_FORMAT = dwarf; 585 | ENABLE_STRICT_OBJC_MSGSEND = YES; 586 | ENABLE_TESTABILITY = YES; 587 | GCC_C_LANGUAGE_STANDARD = gnu11; 588 | GCC_DYNAMIC_NO_PIC = NO; 589 | GCC_NO_COMMON_BLOCKS = YES; 590 | GCC_OPTIMIZATION_LEVEL = 0; 591 | GCC_PREPROCESSOR_DEFINITIONS = ( 592 | "POD_CONFIGURATION_DEBUG=1", 593 | "DEBUG=1", 594 | "$(inherited)", 595 | ); 596 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 597 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 598 | GCC_WARN_UNDECLARED_SELECTOR = YES; 599 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 600 | GCC_WARN_UNUSED_FUNCTION = YES; 601 | GCC_WARN_UNUSED_VARIABLE = YES; 602 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 603 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 604 | MTL_FAST_MATH = YES; 605 | ONLY_ACTIVE_ARCH = YES; 606 | PRODUCT_NAME = "$(TARGET_NAME)"; 607 | STRIP_INSTALLED_PRODUCT = NO; 608 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 609 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 610 | SWIFT_VERSION = 5.0; 611 | SYMROOT = "${SRCROOT}/../build"; 612 | }; 613 | name = Debug; 614 | }; 615 | 9E406C6AAF85E580207CD97B0044DEAB /* Release */ = { 616 | isa = XCBuildConfiguration; 617 | buildSettings = { 618 | ALWAYS_SEARCH_USER_PATHS = NO; 619 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 620 | CLANG_ANALYZER_NONNULL = YES; 621 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 622 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 623 | CLANG_CXX_LIBRARY = "libc++"; 624 | CLANG_ENABLE_MODULES = YES; 625 | CLANG_ENABLE_OBJC_ARC = YES; 626 | CLANG_ENABLE_OBJC_WEAK = YES; 627 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 628 | CLANG_WARN_BOOL_CONVERSION = YES; 629 | CLANG_WARN_COMMA = YES; 630 | CLANG_WARN_CONSTANT_CONVERSION = YES; 631 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 632 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 633 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 634 | CLANG_WARN_EMPTY_BODY = YES; 635 | CLANG_WARN_ENUM_CONVERSION = YES; 636 | CLANG_WARN_INFINITE_RECURSION = YES; 637 | CLANG_WARN_INT_CONVERSION = YES; 638 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 639 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 640 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 641 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 642 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 643 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 644 | CLANG_WARN_STRICT_PROTOTYPES = YES; 645 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 646 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 647 | CLANG_WARN_UNREACHABLE_CODE = YES; 648 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 649 | COPY_PHASE_STRIP = NO; 650 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 651 | ENABLE_NS_ASSERTIONS = NO; 652 | ENABLE_STRICT_OBJC_MSGSEND = YES; 653 | GCC_C_LANGUAGE_STANDARD = gnu11; 654 | GCC_NO_COMMON_BLOCKS = YES; 655 | GCC_PREPROCESSOR_DEFINITIONS = ( 656 | "POD_CONFIGURATION_RELEASE=1", 657 | "$(inherited)", 658 | ); 659 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 660 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 661 | GCC_WARN_UNDECLARED_SELECTOR = YES; 662 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 663 | GCC_WARN_UNUSED_FUNCTION = YES; 664 | GCC_WARN_UNUSED_VARIABLE = YES; 665 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 666 | MTL_ENABLE_DEBUG_INFO = NO; 667 | MTL_FAST_MATH = YES; 668 | PRODUCT_NAME = "$(TARGET_NAME)"; 669 | STRIP_INSTALLED_PRODUCT = NO; 670 | SWIFT_COMPILATION_MODE = wholemodule; 671 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 672 | SWIFT_VERSION = 5.0; 673 | SYMROOT = "${SRCROOT}/../build"; 674 | }; 675 | name = Release; 676 | }; 677 | E508B5219482FA80858F2B6438EBCB51 /* Release */ = { 678 | isa = XCBuildConfiguration; 679 | baseConfigurationReference = CFE6D53984A966705CAE68796D630C06 /* Promis.release.xcconfig */; 680 | buildSettings = { 681 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 682 | CLANG_ENABLE_OBJC_WEAK = NO; 683 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 684 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 685 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 686 | CURRENT_PROJECT_VERSION = 1; 687 | DEFINES_MODULE = YES; 688 | DYLIB_COMPATIBILITY_VERSION = 1; 689 | DYLIB_CURRENT_VERSION = 1; 690 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 691 | GCC_PREFIX_HEADER = "Target Support Files/Promis/Promis-prefix.pch"; 692 | INFOPLIST_FILE = "Target Support Files/Promis/Promis-Info.plist"; 693 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 694 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 695 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 696 | MODULEMAP_FILE = "Target Support Files/Promis/Promis.modulemap"; 697 | PRODUCT_MODULE_NAME = Promis; 698 | PRODUCT_NAME = Promis; 699 | SDKROOT = iphoneos; 700 | SKIP_INSTALL = YES; 701 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 702 | SWIFT_VERSION = 5.0; 703 | TARGETED_DEVICE_FAMILY = "1,2"; 704 | VALIDATE_PRODUCT = YES; 705 | VERSIONING_SYSTEM = "apple-generic"; 706 | VERSION_INFO_PREFIX = ""; 707 | }; 708 | name = Release; 709 | }; 710 | EBA545E23960D29B5B4455C41514817B /* Release */ = { 711 | isa = XCBuildConfiguration; 712 | baseConfigurationReference = A41D60470BFE3915CC345DE5CCF8BC67 /* Pods-DemoApp.release.xcconfig */; 713 | buildSettings = { 714 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 715 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 716 | CLANG_ENABLE_OBJC_WEAK = NO; 717 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 718 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 719 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 720 | CURRENT_PROJECT_VERSION = 1; 721 | DEFINES_MODULE = YES; 722 | DYLIB_COMPATIBILITY_VERSION = 1; 723 | DYLIB_CURRENT_VERSION = 1; 724 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 725 | INFOPLIST_FILE = "Target Support Files/Pods-DemoApp/Pods-DemoApp-Info.plist"; 726 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 727 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 728 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 729 | MACH_O_TYPE = staticlib; 730 | MODULEMAP_FILE = "Target Support Files/Pods-DemoApp/Pods-DemoApp.modulemap"; 731 | OTHER_LDFLAGS = ""; 732 | OTHER_LIBTOOLFLAGS = ""; 733 | PODS_ROOT = "$(SRCROOT)"; 734 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 735 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 736 | SDKROOT = iphoneos; 737 | SKIP_INSTALL = YES; 738 | TARGETED_DEVICE_FAMILY = "1,2"; 739 | VALIDATE_PRODUCT = YES; 740 | VERSIONING_SYSTEM = "apple-generic"; 741 | VERSION_INFO_PREFIX = ""; 742 | }; 743 | name = Release; 744 | }; 745 | /* End XCBuildConfiguration section */ 746 | 747 | /* Begin XCConfigurationList section */ 748 | 1EE314B90DD227C75A4B234EFAE47D25 /* Build configuration list for PBXNativeTarget "Pods-DemoApp" */ = { 749 | isa = XCConfigurationList; 750 | buildConfigurations = ( 751 | 820A000B37C59B11A1ECB4EA38EDD9B3 /* Debug */, 752 | EBA545E23960D29B5B4455C41514817B /* Release */, 753 | ); 754 | defaultConfigurationIsVisible = 0; 755 | defaultConfigurationName = Release; 756 | }; 757 | 3977601545D8410F27106A6B3DD05EBA /* Build configuration list for PBXNativeTarget "Promis" */ = { 758 | isa = XCConfigurationList; 759 | buildConfigurations = ( 760 | 3761A78A83D1607C1681C593C6058FAF /* Debug */, 761 | E508B5219482FA80858F2B6438EBCB51 /* Release */, 762 | ); 763 | defaultConfigurationIsVisible = 0; 764 | defaultConfigurationName = Release; 765 | }; 766 | 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { 767 | isa = XCConfigurationList; 768 | buildConfigurations = ( 769 | 8DE5143C03248BB6CD542DE3963D6F3A /* Debug */, 770 | 9E406C6AAF85E580207CD97B0044DEAB /* Release */, 771 | ); 772 | defaultConfigurationIsVisible = 0; 773 | defaultConfigurationName = Release; 774 | }; 775 | B007BE62AC18191A8336680A24D288A5 /* Build configuration list for PBXNativeTarget "Promis-Unit-UnitTests" */ = { 776 | isa = XCConfigurationList; 777 | buildConfigurations = ( 778 | 1371FA0E7533345FF011C200B233108E /* Debug */, 779 | 234F3E18A88C6DBF7769088C2AD40F30 /* Release */, 780 | ); 781 | defaultConfigurationIsVisible = 0; 782 | defaultConfigurationName = Release; 783 | }; 784 | /* End XCConfigurationList section */ 785 | }; 786 | rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; 787 | } 788 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Promis 5 | 6 | Apache License 7 | Version 2.0, January 2004 8 | http://www.apache.org/licenses/ 9 | 10 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 11 | 12 | 1. Definitions. 13 | 14 | "License" shall mean the terms and conditions for use, reproduction, 15 | and distribution as defined by Sections 1 through 9 of this document. 16 | 17 | "Licensor" shall mean the copyright owner or entity authorized by 18 | the copyright owner that is granting the License. 19 | 20 | "Legal Entity" shall mean the union of the acting entity and all 21 | other entities that control, are controlled by, or are under common 22 | control with that entity. For the purposes of this definition, 23 | "control" means (i) the power, direct or indirect, to cause the 24 | direction or management of such entity, whether by contract or 25 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 26 | outstanding shares, or (iii) beneficial ownership of such entity. 27 | 28 | "You" (or "Your") shall mean an individual or Legal Entity 29 | exercising permissions granted by this License. 30 | 31 | "Source" form shall mean the preferred form for making modifications, 32 | including but not limited to software source code, documentation 33 | source, and configuration files. 34 | 35 | "Object" form shall mean any form resulting from mechanical 36 | transformation or translation of a Source form, including but 37 | not limited to compiled object code, generated documentation, 38 | and conversions to other media types. 39 | 40 | "Work" shall mean the work of authorship, whether in Source or 41 | Object form, made available under the License, as indicated by a 42 | copyright notice that is included in or attached to the work 43 | (an example is provided in the Appendix below). 44 | 45 | "Derivative Works" shall mean any work, whether in Source or Object 46 | form, that is based on (or derived from) the Work and for which the 47 | editorial revisions, annotations, elaborations, or other modifications 48 | represent, as a whole, an original work of authorship. For the purposes 49 | of this License, Derivative Works shall not include works that remain 50 | separable from, or merely link (or bind by name) to the interfaces of, 51 | the Work and Derivative Works thereof. 52 | 53 | "Contribution" shall mean any work of authorship, including 54 | the original version of the Work and any modifications or additions 55 | to that Work or Derivative Works thereof, that is intentionally 56 | submitted to Licensor for inclusion in the Work by the copyright owner 57 | or by an individual or Legal Entity authorized to submit on behalf of 58 | the copyright owner. For the purposes of this definition, "submitted" 59 | means any form of electronic, verbal, or written communication sent 60 | to the Licensor or its representatives, including but not limited to 61 | communication on electronic mailing lists, source code control systems, 62 | and issue tracking systems that are managed by, or on behalf of, the 63 | Licensor for the purpose of discussing and improving the Work, but 64 | excluding communication that is conspicuously marked or otherwise 65 | designated in writing by the copyright owner as "Not a Contribution." 66 | 67 | "Contributor" shall mean Licensor and any individual or Legal Entity 68 | on behalf of whom a Contribution has been received by Licensor and 69 | subsequently incorporated within the Work. 70 | 71 | 2. Grant of Copyright License. Subject to the terms and conditions of 72 | this License, each Contributor hereby grants to You a perpetual, 73 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 74 | copyright license to reproduce, prepare Derivative Works of, 75 | publicly display, publicly perform, sublicense, and distribute the 76 | Work and such Derivative Works in Source or Object form. 77 | 78 | 3. Grant of Patent License. Subject to the terms and conditions of 79 | this License, each Contributor hereby grants to You a perpetual, 80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 81 | (except as stated in this section) patent license to make, have made, 82 | use, offer to sell, sell, import, and otherwise transfer the Work, 83 | where such license applies only to those patent claims licensable 84 | by such Contributor that are necessarily infringed by their 85 | Contribution(s) alone or by combination of their Contribution(s) 86 | with the Work to which such Contribution(s) was submitted. If You 87 | institute patent litigation against any entity (including a 88 | cross-claim or counterclaim in a lawsuit) alleging that the Work 89 | or a Contribution incorporated within the Work constitutes direct 90 | or contributory patent infringement, then any patent licenses 91 | granted to You under this License for that Work shall terminate 92 | as of the date such litigation is filed. 93 | 94 | 4. Redistribution. You may reproduce and distribute copies of the 95 | Work or Derivative Works thereof in any medium, with or without 96 | modifications, and in Source or Object form, provided that You 97 | meet the following conditions: 98 | 99 | (a) You must give any other recipients of the Work or 100 | Derivative Works a copy of this License; and 101 | 102 | (b) You must cause any modified files to carry prominent notices 103 | stating that You changed the files; and 104 | 105 | (c) You must retain, in the Source form of any Derivative Works 106 | that You distribute, all copyright, patent, trademark, and 107 | attribution notices from the Source form of the Work, 108 | excluding those notices that do not pertain to any part of 109 | the Derivative Works; and 110 | 111 | (d) If the Work includes a "NOTICE" text file as part of its 112 | distribution, then any Derivative Works that You distribute must 113 | include a readable copy of the attribution notices contained 114 | within such NOTICE file, excluding those notices that do not 115 | pertain to any part of the Derivative Works, in at least one 116 | of the following places: within a NOTICE text file distributed 117 | as part of the Derivative Works; within the Source form or 118 | documentation, if provided along with the Derivative Works; or, 119 | within a display generated by the Derivative Works, if and 120 | wherever such third-party notices normally appear. The contents 121 | of the NOTICE file are for informational purposes only and 122 | do not modify the License. You may add Your own attribution 123 | notices within Derivative Works that You distribute, alongside 124 | or as an addendum to the NOTICE text from the Work, provided 125 | that such additional attribution notices cannot be construed 126 | as modifying the License. 127 | 128 | You may add Your own copyright statement to Your modifications and 129 | may provide additional or different license terms and conditions 130 | for use, reproduction, or distribution of Your modifications, or 131 | for any such Derivative Works as a whole, provided Your use, 132 | reproduction, and distribution of the Work otherwise complies with 133 | the conditions stated in this License. 134 | 135 | 5. Submission of Contributions. Unless You explicitly state otherwise, 136 | any Contribution intentionally submitted for inclusion in the Work 137 | by You to the Licensor shall be under the terms and conditions of 138 | this License, without any additional terms or conditions. 139 | Notwithstanding the above, nothing herein shall supersede or modify 140 | the terms of any separate license agreement you may have executed 141 | with Licensor regarding such Contributions. 142 | 143 | 6. Trademarks. This License does not grant permission to use the trade 144 | names, trademarks, service marks, or product names of the Licensor, 145 | except as required for reasonable and customary use in describing the 146 | origin of the Work and reproducing the content of the NOTICE file. 147 | 148 | 7. Disclaimer of Warranty. Unless required by applicable law or 149 | agreed to in writing, Licensor provides the Work (and each 150 | Contributor provides its Contributions) on an "AS IS" BASIS, 151 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 152 | implied, including, without limitation, any warranties or conditions 153 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 154 | PARTICULAR PURPOSE. You are solely responsible for determining the 155 | appropriateness of using or redistributing the Work and assume any 156 | risks associated with Your exercise of permissions under this License. 157 | 158 | 8. Limitation of Liability. In no event and under no legal theory, 159 | whether in tort (including negligence), contract, or otherwise, 160 | unless required by applicable law (such as deliberate and grossly 161 | negligent acts) or agreed to in writing, shall any Contributor be 162 | liable to You for damages, including any direct, indirect, special, 163 | incidental, or consequential damages of any character arising as a 164 | result of this License or out of the use or inability to use the 165 | Work (including but not limited to damages for loss of goodwill, 166 | work stoppage, computer failure or malfunction, or any and all 167 | other commercial damages or losses), even if such Contributor 168 | has been advised of the possibility of such damages. 169 | 170 | 9. Accepting Warranty or Additional Liability. While redistributing 171 | the Work or Derivative Works thereof, You may choose to offer, 172 | and charge a fee for, acceptance of support, warranty, indemnity, 173 | or other liability obligations and/or rights consistent with this 174 | License. However, in accepting such obligations, You may act only 175 | on Your own behalf and on Your sole responsibility, not on behalf 176 | of any other Contributor, and only if You agree to indemnify, 177 | defend, and hold each Contributor harmless for any liability 178 | incurred by, or claims asserted against, such Contributor by reason 179 | of your accepting any such warranty or additional liability. 180 | 181 | END OF TERMS AND CONDITIONS 182 | 183 | APPENDIX: How to apply the Apache License to your work. 184 | 185 | To apply the Apache License to your work, attach the following 186 | boilerplate notice, with the fields enclosed by brackets "{}" 187 | replaced with your own identifying information. (Don't include 188 | the brackets!) The text should be enclosed in the appropriate 189 | comment syntax for the file format. We also recommend that a 190 | file or class name and description of purpose be included on the 191 | same "printed page" as the copyright notice for easier 192 | identification within third-party archives. 193 | 194 | Copyright 2017 Alberto De Bortoli 195 | 196 | Licensed under the Apache License, Version 2.0 (the "License"); 197 | you may not use this file except in compliance with the License. 198 | You may obtain a copy of the License at 199 | 200 | http://www.apache.org/licenses/LICENSE-2.0 201 | 202 | Unless required by applicable law or agreed to in writing, software 203 | distributed under the License is distributed on an "AS IS" BASIS, 204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 205 | See the License for the specific language governing permissions and 206 | limitations under the License. 207 | 208 | Generated by CocoaPods - https://cocoapods.org 209 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Apache License 18 | Version 2.0, January 2004 19 | http://www.apache.org/licenses/ 20 | 21 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 22 | 23 | 1. Definitions. 24 | 25 | "License" shall mean the terms and conditions for use, reproduction, 26 | and distribution as defined by Sections 1 through 9 of this document. 27 | 28 | "Licensor" shall mean the copyright owner or entity authorized by 29 | the copyright owner that is granting the License. 30 | 31 | "Legal Entity" shall mean the union of the acting entity and all 32 | other entities that control, are controlled by, or are under common 33 | control with that entity. For the purposes of this definition, 34 | "control" means (i) the power, direct or indirect, to cause the 35 | direction or management of such entity, whether by contract or 36 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 37 | outstanding shares, or (iii) beneficial ownership of such entity. 38 | 39 | "You" (or "Your") shall mean an individual or Legal Entity 40 | exercising permissions granted by this License. 41 | 42 | "Source" form shall mean the preferred form for making modifications, 43 | including but not limited to software source code, documentation 44 | source, and configuration files. 45 | 46 | "Object" form shall mean any form resulting from mechanical 47 | transformation or translation of a Source form, including but 48 | not limited to compiled object code, generated documentation, 49 | and conversions to other media types. 50 | 51 | "Work" shall mean the work of authorship, whether in Source or 52 | Object form, made available under the License, as indicated by a 53 | copyright notice that is included in or attached to the work 54 | (an example is provided in the Appendix below). 55 | 56 | "Derivative Works" shall mean any work, whether in Source or Object 57 | form, that is based on (or derived from) the Work and for which the 58 | editorial revisions, annotations, elaborations, or other modifications 59 | represent, as a whole, an original work of authorship. For the purposes 60 | of this License, Derivative Works shall not include works that remain 61 | separable from, or merely link (or bind by name) to the interfaces of, 62 | the Work and Derivative Works thereof. 63 | 64 | "Contribution" shall mean any work of authorship, including 65 | the original version of the Work and any modifications or additions 66 | to that Work or Derivative Works thereof, that is intentionally 67 | submitted to Licensor for inclusion in the Work by the copyright owner 68 | or by an individual or Legal Entity authorized to submit on behalf of 69 | the copyright owner. For the purposes of this definition, "submitted" 70 | means any form of electronic, verbal, or written communication sent 71 | to the Licensor or its representatives, including but not limited to 72 | communication on electronic mailing lists, source code control systems, 73 | and issue tracking systems that are managed by, or on behalf of, the 74 | Licensor for the purpose of discussing and improving the Work, but 75 | excluding communication that is conspicuously marked or otherwise 76 | designated in writing by the copyright owner as "Not a Contribution." 77 | 78 | "Contributor" shall mean Licensor and any individual or Legal Entity 79 | on behalf of whom a Contribution has been received by Licensor and 80 | subsequently incorporated within the Work. 81 | 82 | 2. Grant of Copyright License. Subject to the terms and conditions of 83 | this License, each Contributor hereby grants to You a perpetual, 84 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 85 | copyright license to reproduce, prepare Derivative Works of, 86 | publicly display, publicly perform, sublicense, and distribute the 87 | Work and such Derivative Works in Source or Object form. 88 | 89 | 3. Grant of Patent License. Subject to the terms and conditions of 90 | this License, each Contributor hereby grants to You a perpetual, 91 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 92 | (except as stated in this section) patent license to make, have made, 93 | use, offer to sell, sell, import, and otherwise transfer the Work, 94 | where such license applies only to those patent claims licensable 95 | by such Contributor that are necessarily infringed by their 96 | Contribution(s) alone or by combination of their Contribution(s) 97 | with the Work to which such Contribution(s) was submitted. If You 98 | institute patent litigation against any entity (including a 99 | cross-claim or counterclaim in a lawsuit) alleging that the Work 100 | or a Contribution incorporated within the Work constitutes direct 101 | or contributory patent infringement, then any patent licenses 102 | granted to You under this License for that Work shall terminate 103 | as of the date such litigation is filed. 104 | 105 | 4. Redistribution. You may reproduce and distribute copies of the 106 | Work or Derivative Works thereof in any medium, with or without 107 | modifications, and in Source or Object form, provided that You 108 | meet the following conditions: 109 | 110 | (a) You must give any other recipients of the Work or 111 | Derivative Works a copy of this License; and 112 | 113 | (b) You must cause any modified files to carry prominent notices 114 | stating that You changed the files; and 115 | 116 | (c) You must retain, in the Source form of any Derivative Works 117 | that You distribute, all copyright, patent, trademark, and 118 | attribution notices from the Source form of the Work, 119 | excluding those notices that do not pertain to any part of 120 | the Derivative Works; and 121 | 122 | (d) If the Work includes a "NOTICE" text file as part of its 123 | distribution, then any Derivative Works that You distribute must 124 | include a readable copy of the attribution notices contained 125 | within such NOTICE file, excluding those notices that do not 126 | pertain to any part of the Derivative Works, in at least one 127 | of the following places: within a NOTICE text file distributed 128 | as part of the Derivative Works; within the Source form or 129 | documentation, if provided along with the Derivative Works; or, 130 | within a display generated by the Derivative Works, if and 131 | wherever such third-party notices normally appear. The contents 132 | of the NOTICE file are for informational purposes only and 133 | do not modify the License. You may add Your own attribution 134 | notices within Derivative Works that You distribute, alongside 135 | or as an addendum to the NOTICE text from the Work, provided 136 | that such additional attribution notices cannot be construed 137 | as modifying the License. 138 | 139 | You may add Your own copyright statement to Your modifications and 140 | may provide additional or different license terms and conditions 141 | for use, reproduction, or distribution of Your modifications, or 142 | for any such Derivative Works as a whole, provided Your use, 143 | reproduction, and distribution of the Work otherwise complies with 144 | the conditions stated in this License. 145 | 146 | 5. Submission of Contributions. Unless You explicitly state otherwise, 147 | any Contribution intentionally submitted for inclusion in the Work 148 | by You to the Licensor shall be under the terms and conditions of 149 | this License, without any additional terms or conditions. 150 | Notwithstanding the above, nothing herein shall supersede or modify 151 | the terms of any separate license agreement you may have executed 152 | with Licensor regarding such Contributions. 153 | 154 | 6. Trademarks. This License does not grant permission to use the trade 155 | names, trademarks, service marks, or product names of the Licensor, 156 | except as required for reasonable and customary use in describing the 157 | origin of the Work and reproducing the content of the NOTICE file. 158 | 159 | 7. Disclaimer of Warranty. Unless required by applicable law or 160 | agreed to in writing, Licensor provides the Work (and each 161 | Contributor provides its Contributions) on an "AS IS" BASIS, 162 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 163 | implied, including, without limitation, any warranties or conditions 164 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 165 | PARTICULAR PURPOSE. You are solely responsible for determining the 166 | appropriateness of using or redistributing the Work and assume any 167 | risks associated with Your exercise of permissions under this License. 168 | 169 | 8. Limitation of Liability. In no event and under no legal theory, 170 | whether in tort (including negligence), contract, or otherwise, 171 | unless required by applicable law (such as deliberate and grossly 172 | negligent acts) or agreed to in writing, shall any Contributor be 173 | liable to You for damages, including any direct, indirect, special, 174 | incidental, or consequential damages of any character arising as a 175 | result of this License or out of the use or inability to use the 176 | Work (including but not limited to damages for loss of goodwill, 177 | work stoppage, computer failure or malfunction, or any and all 178 | other commercial damages or losses), even if such Contributor 179 | has been advised of the possibility of such damages. 180 | 181 | 9. Accepting Warranty or Additional Liability. While redistributing 182 | the Work or Derivative Works thereof, You may choose to offer, 183 | and charge a fee for, acceptance of support, warranty, indemnity, 184 | or other liability obligations and/or rights consistent with this 185 | License. However, in accepting such obligations, You may act only 186 | on Your own behalf and on Your sole responsibility, not on behalf 187 | of any other Contributor, and only if You agree to indemnify, 188 | defend, and hold each Contributor harmless for any liability 189 | incurred by, or claims asserted against, such Contributor by reason 190 | of your accepting any such warranty or additional liability. 191 | 192 | END OF TERMS AND CONDITIONS 193 | 194 | APPENDIX: How to apply the Apache License to your work. 195 | 196 | To apply the Apache License to your work, attach the following 197 | boilerplate notice, with the fields enclosed by brackets "{}" 198 | replaced with your own identifying information. (Don't include 199 | the brackets!) The text should be enclosed in the appropriate 200 | comment syntax for the file format. We also recommend that a 201 | file or class name and description of purpose be included on the 202 | same "printed page" as the copyright notice for easier 203 | identification within third-party archives. 204 | 205 | Copyright 2017 Alberto De Bortoli 206 | 207 | Licensed under the Apache License, Version 2.0 (the "License"); 208 | you may not use this file except in compliance with the License. 209 | You may obtain a copy of the License at 210 | 211 | http://www.apache.org/licenses/LICENSE-2.0 212 | 213 | Unless required by applicable law or agreed to in writing, software 214 | distributed under the License is distributed on an "AS IS" BASIS, 215 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 216 | See the License for the specific language governing permissions and 217 | limitations under the License. 218 | 219 | License 220 | MIT 221 | Title 222 | Promis 223 | Type 224 | PSGroupSpecifier 225 | 226 | 227 | FooterText 228 | Generated by CocoaPods - https://cocoapods.org 229 | Title 230 | 231 | Type 232 | PSGroupSpecifier 233 | 234 | 235 | StringsTable 236 | Acknowledgements 237 | Title 238 | Acknowledgements 239 | 240 | 241 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_DemoApp : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_DemoApp 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}" 117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 118 | fi 119 | fi 120 | } 121 | 122 | # Used as a return value for each invocation of `strip_invalid_archs` function. 123 | STRIP_BINARY_RETVAL=0 124 | 125 | # Strip invalid architectures 126 | strip_invalid_archs() { 127 | binary="$1" 128 | warn_missing_arch=${2:-true} 129 | # Get architectures for current target binary 130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 131 | # Intersect them with the architectures we are building for 132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 133 | # If there are no archs supported by this binary then warn the user 134 | if [[ -z "$intersected_archs" ]]; then 135 | if [[ "$warn_missing_arch" == "true" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | fi 138 | STRIP_BINARY_RETVAL=1 139 | return 140 | fi 141 | stripped="" 142 | for arch in $binary_archs; do 143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 144 | # Strip non-valid architectures in-place 145 | lipo -remove "$arch" -output "$binary" "$binary" 146 | stripped="$stripped $arch" 147 | fi 148 | done 149 | if [[ "$stripped" ]]; then 150 | echo "Stripped $binary of architectures:$stripped" 151 | fi 152 | STRIP_BINARY_RETVAL=0 153 | } 154 | 155 | # Copies the bcsymbolmap files of a vendored framework 156 | install_bcsymbolmap() { 157 | local bcsymbolmap_path="$1" 158 | local destination="${BUILT_PRODUCTS_DIR}" 159 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 161 | } 162 | 163 | # Signs a framework with the provided identity 164 | code_sign_if_enabled() { 165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 166 | # Use the current code_sign_identity 167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 169 | 170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 171 | code_sign_cmd="$code_sign_cmd &" 172 | fi 173 | echo "$code_sign_cmd" 174 | eval "$code_sign_cmd" 175 | fi 176 | } 177 | 178 | if [[ "$CONFIGURATION" == "Debug" ]]; then 179 | install_framework "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework" 183 | fi 184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 185 | wait 186 | fi 187 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_DemoAppVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_DemoAppVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis/Promis.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "Promis" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_DemoApp { 2 | umbrella header "Pods-DemoApp-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis/Promis.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "Promis" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.2.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-Unit-UnitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleIdentifier 8 | ${PRODUCT_BUNDLE_IDENTIFIER} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-Unit-UnitTests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}" 117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 118 | fi 119 | fi 120 | } 121 | 122 | # Used as a return value for each invocation of `strip_invalid_archs` function. 123 | STRIP_BINARY_RETVAL=0 124 | 125 | # Strip invalid architectures 126 | strip_invalid_archs() { 127 | binary="$1" 128 | warn_missing_arch=${2:-true} 129 | # Get architectures for current target binary 130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 131 | # Intersect them with the architectures we are building for 132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 133 | # If there are no archs supported by this binary then warn the user 134 | if [[ -z "$intersected_archs" ]]; then 135 | if [[ "$warn_missing_arch" == "true" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | fi 138 | STRIP_BINARY_RETVAL=1 139 | return 140 | fi 141 | stripped="" 142 | for arch in $binary_archs; do 143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 144 | # Strip non-valid architectures in-place 145 | lipo -remove "$arch" -output "$binary" "$binary" 146 | stripped="$stripped $arch" 147 | fi 148 | done 149 | if [[ "$stripped" ]]; then 150 | echo "Stripped $binary of architectures:$stripped" 151 | fi 152 | STRIP_BINARY_RETVAL=0 153 | } 154 | 155 | # Copies the bcsymbolmap files of a vendored framework 156 | install_bcsymbolmap() { 157 | local bcsymbolmap_path="$1" 158 | local destination="${BUILT_PRODUCTS_DIR}" 159 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 161 | } 162 | 163 | # Signs a framework with the provided identity 164 | code_sign_if_enabled() { 165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 166 | # Use the current code_sign_identity 167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 169 | 170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 171 | code_sign_cmd="$code_sign_cmd &" 172 | fi 173 | echo "$code_sign_cmd" 174 | eval "$code_sign_cmd" 175 | fi 176 | } 177 | 178 | if [[ "$CONFIGURATION" == "Debug" ]]; then 179 | install_framework "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework" 180 | fi 181 | if [[ "$CONFIGURATION" == "Release" ]]; then 182 | install_framework "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework" 183 | fi 184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 185 | wait 186 | fi 187 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-Unit-UnitTests-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Promis : NSObject 3 | @end 4 | @implementation PodsDummy_Promis 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double PromisVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char PromisVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Promis 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.modulemap: -------------------------------------------------------------------------------- 1 | framework module Promis { 2 | umbrella header "Promis-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Promis 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.unit-unittests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 6 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "Promis" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | SKIP_INSTALL = YES 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.unit-unittests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Promis" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 6 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "Promis" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | SKIP_INSTALL = YES 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Promis/Promis.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Promis 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Promis.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 36DE527E756609633C700234 /* Pods_DemoApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD9F3FE6A9E8F169784987D /* Pods_DemoApp.framework */; }; 11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 0D4857AE50459ECA931D1A65 /* Pods-DemoApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DemoApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp.debug.xcconfig"; sourceTree = ""; }; 20 | 493DB3F2DFCAD32E3147490B /* Pods-DemoApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DemoApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-DemoApp/Pods-DemoApp.release.xcconfig"; sourceTree = ""; }; 21 | 4F08EA95284EB6CB00390978 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = file; path = UnitTests.xctestplan; sourceTree = SOURCE_ROOT; }; 22 | 4F39FD8B1F93E77D0034F4C3 /* GettingStarted.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = GettingStarted.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 23 | 4FA5AAE5E15C6C42C8A57CA5 /* Promis.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Promis.podspec; path = ../Promis.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 24 | 607FACD01AFB9204008FA782 /* DemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 27 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 28 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 30 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 31 | 7BD9F3FE6A9E8F169784987D /* Pods_DemoApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DemoApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | A13AAEF3239B132DBFA3A98D /* Pods-Promis_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Promis_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Promis_Example/Pods-Promis_Example.debug.xcconfig"; sourceTree = ""; }; 33 | AEE4CAD109538A5449BB6805 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 34 | C042DF351FEF387544C98FC6 /* Pods-Promis_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Promis_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Promis_Example/Pods-Promis_Example.release.xcconfig"; sourceTree = ""; }; 35 | DC4D4563AED7A5ED91315705 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | 36DE527E756609633C700234 /* Pods_DemoApp.framework in Frameworks */, 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 607FACC71AFB9204008FA782 = { 51 | isa = PBXGroup; 52 | children = ( 53 | 4F39FD8B1F93E77D0034F4C3 /* GettingStarted.playground */, 54 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 55 | 607FACD21AFB9204008FA782 /* Example for Promis */, 56 | 607FACD11AFB9204008FA782 /* Products */, 57 | 948C7B0BA1E4F3996EE5D2D9 /* Pods */, 58 | D7CEEB090109A167A981FCE6 /* Frameworks */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | 607FACD11AFB9204008FA782 /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 607FACD01AFB9204008FA782 /* DemoApp.app */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | 607FACD21AFB9204008FA782 /* Example for Promis */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 4F08EA95284EB6CB00390978 /* UnitTests.xctestplan */, 74 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 75 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 76 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 77 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 78 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 79 | 607FACD31AFB9204008FA782 /* Supporting Files */, 80 | ); 81 | name = "Example for Promis"; 82 | path = Promis; 83 | sourceTree = ""; 84 | }; 85 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 607FACD41AFB9204008FA782 /* Info.plist */, 89 | ); 90 | name = "Supporting Files"; 91 | sourceTree = ""; 92 | }; 93 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 4FA5AAE5E15C6C42C8A57CA5 /* Promis.podspec */, 97 | DC4D4563AED7A5ED91315705 /* README.md */, 98 | AEE4CAD109538A5449BB6805 /* LICENSE */, 99 | ); 100 | name = "Podspec Metadata"; 101 | sourceTree = ""; 102 | }; 103 | 948C7B0BA1E4F3996EE5D2D9 /* Pods */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | A13AAEF3239B132DBFA3A98D /* Pods-Promis_Example.debug.xcconfig */, 107 | C042DF351FEF387544C98FC6 /* Pods-Promis_Example.release.xcconfig */, 108 | 0D4857AE50459ECA931D1A65 /* Pods-DemoApp.debug.xcconfig */, 109 | 493DB3F2DFCAD32E3147490B /* Pods-DemoApp.release.xcconfig */, 110 | ); 111 | name = Pods; 112 | sourceTree = ""; 113 | }; 114 | D7CEEB090109A167A981FCE6 /* Frameworks */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 7BD9F3FE6A9E8F169784987D /* Pods_DemoApp.framework */, 118 | ); 119 | name = Frameworks; 120 | sourceTree = ""; 121 | }; 122 | /* End PBXGroup section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | 607FACCF1AFB9204008FA782 /* DemoApp */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DemoApp" */; 128 | buildPhases = ( 129 | BAE3240962E758C3353EDBCA /* [CP] Check Pods Manifest.lock */, 130 | 607FACCC1AFB9204008FA782 /* Sources */, 131 | 607FACCD1AFB9204008FA782 /* Frameworks */, 132 | 607FACCE1AFB9204008FA782 /* Resources */, 133 | F54764E59B79A96E27C40222 /* [CP] Embed Pods Frameworks */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = DemoApp; 140 | productName = Promis; 141 | productReference = 607FACD01AFB9204008FA782 /* DemoApp.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 607FACC81AFB9204008FA782 /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | LastSwiftUpdateCheck = 0830; 151 | LastUpgradeCheck = 1010; 152 | ORGANIZATIONNAME = CocoaPods; 153 | TargetAttributes = { 154 | 607FACCF1AFB9204008FA782 = { 155 | CreatedOnToolsVersion = 6.3.1; 156 | LastSwiftMigration = 1010; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Promis" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | English, 166 | en, 167 | Base, 168 | ); 169 | mainGroup = 607FACC71AFB9204008FA782; 170 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 171 | projectDirPath = ""; 172 | projectRoot = ""; 173 | targets = ( 174 | 607FACCF1AFB9204008FA782 /* DemoApp */, 175 | ); 176 | }; 177 | /* End PBXProject section */ 178 | 179 | /* Begin PBXResourcesBuildPhase section */ 180 | 607FACCE1AFB9204008FA782 /* Resources */ = { 181 | isa = PBXResourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 185 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 186 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | }; 190 | /* End PBXResourcesBuildPhase section */ 191 | 192 | /* Begin PBXShellScriptBuildPhase section */ 193 | BAE3240962E758C3353EDBCA /* [CP] Check Pods Manifest.lock */ = { 194 | isa = PBXShellScriptBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | inputPaths = ( 199 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 200 | "${PODS_ROOT}/Manifest.lock", 201 | ); 202 | name = "[CP] Check Pods Manifest.lock"; 203 | outputPaths = ( 204 | "$(DERIVED_FILE_DIR)/Pods-DemoApp-checkManifestLockResult.txt", 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | shellPath = /bin/sh; 208 | 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"; 209 | showEnvVarsInLog = 0; 210 | }; 211 | F54764E59B79A96E27C40222 /* [CP] Embed Pods Frameworks */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputPaths = ( 217 | "${PODS_ROOT}/Target Support Files/Pods-DemoApp/Pods-DemoApp-frameworks.sh", 218 | "${BUILT_PRODUCTS_DIR}/Promis/Promis.framework", 219 | ); 220 | name = "[CP] Embed Pods Frameworks"; 221 | outputPaths = ( 222 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Promis.framework", 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | shellPath = /bin/sh; 226 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DemoApp/Pods-DemoApp-frameworks.sh\"\n"; 227 | showEnvVarsInLog = 0; 228 | }; 229 | /* End PBXShellScriptBuildPhase section */ 230 | 231 | /* Begin PBXSourcesBuildPhase section */ 232 | 607FACCC1AFB9204008FA782 /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 237 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXSourcesBuildPhase section */ 242 | 243 | /* Begin PBXVariantGroup section */ 244 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 245 | isa = PBXVariantGroup; 246 | children = ( 247 | 607FACDA1AFB9204008FA782 /* Base */, 248 | ); 249 | name = Main.storyboard; 250 | sourceTree = ""; 251 | }; 252 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | 607FACDF1AFB9204008FA782 /* Base */, 256 | ); 257 | name = LaunchScreen.xib; 258 | sourceTree = ""; 259 | }; 260 | /* End PBXVariantGroup section */ 261 | 262 | /* Begin XCBuildConfiguration section */ 263 | 607FACED1AFB9204008FA782 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_MODULES = YES; 270 | CLANG_ENABLE_OBJC_ARC = YES; 271 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 272 | CLANG_WARN_BOOL_CONVERSION = YES; 273 | CLANG_WARN_COMMA = YES; 274 | CLANG_WARN_CONSTANT_CONVERSION = YES; 275 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 276 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 277 | CLANG_WARN_EMPTY_BODY = YES; 278 | CLANG_WARN_ENUM_CONVERSION = YES; 279 | CLANG_WARN_INFINITE_RECURSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 282 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 283 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 285 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 286 | CLANG_WARN_STRICT_PROTOTYPES = YES; 287 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 288 | CLANG_WARN_UNREACHABLE_CODE = YES; 289 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 290 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 291 | COPY_PHASE_STRIP = NO; 292 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 293 | ENABLE_STRICT_OBJC_MSGSEND = YES; 294 | ENABLE_TESTABILITY = YES; 295 | GCC_C_LANGUAGE_STANDARD = gnu99; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_NO_COMMON_BLOCKS = YES; 298 | GCC_OPTIMIZATION_LEVEL = 0; 299 | GCC_PREPROCESSOR_DEFINITIONS = ( 300 | "DEBUG=1", 301 | "$(inherited)", 302 | ); 303 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 304 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 307 | GCC_WARN_UNDECLARED_SELECTOR = YES; 308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 309 | GCC_WARN_UNUSED_FUNCTION = YES; 310 | GCC_WARN_UNUSED_VARIABLE = YES; 311 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | ONLY_ACTIVE_ARCH = YES; 314 | SDKROOT = iphoneos; 315 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 316 | SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; 317 | SWIFT_VERSION = 5.0; 318 | }; 319 | name = Debug; 320 | }; 321 | 607FACEE1AFB9204008FA782 /* Release */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 326 | CLANG_CXX_LIBRARY = "libc++"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 330 | CLANG_WARN_BOOL_CONVERSION = YES; 331 | CLANG_WARN_COMMA = YES; 332 | CLANG_WARN_CONSTANT_CONVERSION = YES; 333 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_EMPTY_BODY = YES; 336 | CLANG_WARN_ENUM_CONVERSION = YES; 337 | CLANG_WARN_INFINITE_RECURSION = YES; 338 | CLANG_WARN_INT_CONVERSION = YES; 339 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 340 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 341 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 344 | CLANG_WARN_STRICT_PROTOTYPES = YES; 345 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 346 | CLANG_WARN_UNREACHABLE_CODE = YES; 347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 349 | COPY_PHASE_STRIP = NO; 350 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 351 | ENABLE_NS_ASSERTIONS = NO; 352 | ENABLE_STRICT_OBJC_MSGSEND = YES; 353 | GCC_C_LANGUAGE_STANDARD = gnu99; 354 | GCC_NO_COMMON_BLOCKS = YES; 355 | GCC_TREAT_WARNINGS_AS_ERRORS = YES; 356 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 357 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 358 | GCC_WARN_UNDECLARED_SELECTOR = YES; 359 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 360 | GCC_WARN_UNUSED_FUNCTION = YES; 361 | GCC_WARN_UNUSED_VARIABLE = YES; 362 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 363 | MTL_ENABLE_DEBUG_INFO = NO; 364 | SDKROOT = iphoneos; 365 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 366 | SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; 367 | SWIFT_VERSION = 5.0; 368 | VALIDATE_PRODUCT = YES; 369 | }; 370 | name = Release; 371 | }; 372 | 607FACF01AFB9204008FA782 /* Debug */ = { 373 | isa = XCBuildConfiguration; 374 | baseConfigurationReference = 0D4857AE50459ECA931D1A65 /* Pods-DemoApp.debug.xcconfig */; 375 | buildSettings = { 376 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 377 | INFOPLIST_FILE = Promis/Info.plist; 378 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 379 | MODULE_NAME = ExampleApp; 380 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | }; 383 | name = Debug; 384 | }; 385 | 607FACF11AFB9204008FA782 /* Release */ = { 386 | isa = XCBuildConfiguration; 387 | baseConfigurationReference = 493DB3F2DFCAD32E3147490B /* Pods-DemoApp.release.xcconfig */; 388 | buildSettings = { 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | INFOPLIST_FILE = Promis/Info.plist; 391 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 392 | MODULE_NAME = ExampleApp; 393 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | }; 396 | name = Release; 397 | }; 398 | /* End XCBuildConfiguration section */ 399 | 400 | /* Begin XCConfigurationList section */ 401 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Promis" */ = { 402 | isa = XCConfigurationList; 403 | buildConfigurations = ( 404 | 607FACED1AFB9204008FA782 /* Debug */, 405 | 607FACEE1AFB9204008FA782 /* Release */, 406 | ); 407 | defaultConfigurationIsVisible = 0; 408 | defaultConfigurationName = Release; 409 | }; 410 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DemoApp" */ = { 411 | isa = XCConfigurationList; 412 | buildConfigurations = ( 413 | 607FACF01AFB9204008FA782 /* Debug */, 414 | 607FACF11AFB9204008FA782 /* Release */, 415 | ); 416 | defaultConfigurationIsVisible = 0; 417 | defaultConfigurationName = Release; 418 | }; 419 | /* End XCConfigurationList section */ 420 | }; 421 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 422 | } 423 | -------------------------------------------------------------------------------- /Example/Promis.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Promis.xcodeproj/xcshareddata/xcschemes/DemoApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 34 | 35 | 36 | 37 | 47 | 49 | 55 | 56 | 57 | 58 | 64 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Example/Promis.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Promis.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Promis/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 10/14/2017. 6 | // Copyright (c) 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // 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. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Promis/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/Promis/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/Promis/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Promis/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Promis/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 10/14/2017. 6 | // Copyright (c) 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | public override func viewDidLoad() { 14 | super.viewDidLoad() 15 | } 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Example/UnitTests.xctestplan: -------------------------------------------------------------------------------- 1 | { 2 | "configurations" : [ 3 | { 4 | "id" : "62F6AB81-518E-4925-B31C-0C7F6B9C6EB7", 5 | "name" : "Configuration 1", 6 | "options" : { 7 | 8 | } 9 | } 10 | ], 11 | "defaultOptions" : { 12 | "codeCoverage" : { 13 | "targets" : [ 14 | { 15 | "containerPath" : "container:Pods\/Pods.xcodeproj", 16 | "identifier" : "E1400FA1180B6A8188795D86A04FED99", 17 | "name" : "Promis" 18 | } 19 | ] 20 | }, 21 | "targetForVariableExpansion" : { 22 | "containerPath" : "container:Promis.xcodeproj", 23 | "identifier" : "607FACCF1AFB9204008FA782", 24 | "name" : "DemoApp" 25 | } 26 | }, 27 | "testTargets" : [ 28 | { 29 | "target" : { 30 | "containerPath" : "container:Pods\/Pods.xcodeproj", 31 | "identifier" : "295F351793509221CE75C7DD4981ADAA", 32 | "name" : "Promis-Unit-UnitTests" 33 | } 34 | } 35 | ], 36 | "version" : 1 37 | } 38 | -------------------------------------------------------------------------------- /Framework/Sources/Future+Chaining.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Future+Chaining.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Future { 12 | 13 | // MARK: Chaining 14 | 15 | /** 16 | Continues the execution of the receiver with a finally block. 17 | 18 | - parameter queue: An optional queue used to execute the block on 19 | - parameter block: The block to execute as continuation of the future receiving the receiver as a parameter 20 | */ 21 | public func finally(queue: DispatchQueue? = nil, block: @escaping (Future) -> Void) { 22 | // rather than making all the chaining APIs throwable 23 | // if a continuation has already been set, a crash is desired 24 | try! setContinuation { future in 25 | if let queue = queue { 26 | queue.async { 27 | block(future) 28 | } 29 | } else { 30 | block(future) 31 | } 32 | } 33 | } 34 | 35 | /** 36 | Continues the execution of the receiver allowing chaining. 37 | 38 | - parameter queue: An optional queue used to execute the block on 39 | - parameter block: The block to execute as continuation of the future receiving the receiver as a parameter and returning a new future (possibly with a different type) 40 | 41 | - returns: A new future resolved with the resolution of the future returned by the block parameter. 42 | */ 43 | @discardableResult 44 | public func then(queue: DispatchQueue? = nil, task: @escaping (Future) -> Future) -> Future { 45 | let promise = Promise() 46 | finally(queue: queue) { future in 47 | let f2 = task(future) 48 | f2.finally(queue: queue) { fut2 in 49 | promise.setResolution(of: fut2) 50 | } 51 | } 52 | return promise.future 53 | } 54 | 55 | /** 56 | Continues the execution of the receiver allowing chaining. 57 | 58 | - parameter queue: An optional queue used to execute the block on 59 | - parameter block: The block to execute as continuation of the future receiving the result of the receiver as a parameter and returning a new future (possibly with a different type). The block is not execute if the receiver is not resolved with a result. 60 | 61 | - returns: A new future resolved with the resolution of the future returned by the block parameter. 62 | */ 63 | @discardableResult 64 | public func thenWithResult(queue: DispatchQueue? = nil, continuation: @escaping (ResultType) -> Future) -> Future { 65 | let promise = Promise() 66 | finally(queue: queue) { future in 67 | guard case .result(let value) = self.state else { 68 | promise.setResolutionOfFutureNotResolvedWithResult(future) 69 | return 70 | } 71 | let f2 = continuation(value) 72 | f2.finally(queue: queue) { fut2 in 73 | promise.setResolution(of: fut2) 74 | } 75 | } 76 | return promise.future 77 | } 78 | 79 | /** 80 | Continues the execution of the receiver allowing chaining. 81 | 82 | - parameter queue: An optional queue used to execute the block on 83 | - parameter block: The block to execute as continuation of the future receiving the error of the receiver as a parameter. The block is not execute if the receiver is not resolved with error. 84 | 85 | - returns: A new future resolved with the resolution of the receiver. 86 | */ 87 | @discardableResult 88 | public func onError(queue: DispatchQueue? = nil, continuation: @escaping (Error) -> Void) -> Future { 89 | let promise = Promise() 90 | finally(queue: queue) { future in 91 | guard case .error(let err) = self.state else { 92 | promise.setResolution(of: future) 93 | return 94 | } 95 | continuation(err) 96 | promise.setResolution(of: future) 97 | } 98 | return promise.future 99 | } 100 | 101 | // MARK: Chaining (Private) 102 | 103 | /** 104 | Continues the execution of the receiver with a finally block. 105 | 106 | - parameter block: The block to execute as continuation of the future receiving the receiver as a parameter. 107 | */ 108 | func setContinuation(_ block: @escaping (Future) -> Void) throws { 109 | cv.lock() 110 | guard continuation == nil else { 111 | cv.unlock() 112 | throw PromisError.futureContinuationAlreadySet 113 | } 114 | continuation = block 115 | let resolved = state != .unresolved 116 | 117 | cv.unlock() 118 | if (resolved) { 119 | continuation!(self) 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Framework/Sources/Future+WhenAll.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Future+WhenAll.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Future { 12 | 13 | /** 14 | Creates and returns a future that is resolved with a result when all the futures passed as parametes are resolved. 15 | 16 | - parameter futures: An array of futures 17 | 18 | - returns: A future of type [FutureState] with the resolved states of all the futures passed as parameters. 19 | */ 20 | @discardableResult 21 | public class func whenAll(_ futures: [Future]) -> Future<[FutureState]> { 22 | let future = Future<[FutureState]>() 23 | var counter = Int32(futures.count) 24 | var states = Array>(repeating: .unresolved, count: Int(counter)) 25 | for (index, element) in futures.enumerated() { 26 | element.finally { [unowned future] fut in 27 | states[index] = fut.state 28 | if (OSAtomicDecrement32(&counter) == 0) { 29 | future.setResult(states) 30 | } 31 | } 32 | } 33 | return future 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Framework/Sources/Future.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Future.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class Future { 12 | 13 | let cv: NSCondition 14 | var continuation: ((Future) -> Void)? 15 | private(set) public var state: FutureState = .unresolved 16 | 17 | public init() { 18 | self.cv = NSCondition() 19 | } 20 | 21 | public var description: String { 22 | return "" 23 | } 24 | 25 | // MARK: Creation 26 | 27 | /** 28 | Initializes a new resolved future with a result. 29 | 30 | - parameter result: The result to use to resolve the future 31 | 32 | - returns: A newly created future, resolved with result. 33 | */ 34 | public class func future(withResult result: ResultType) -> Future { 35 | let promise = Promise() 36 | promise.setResult(result) 37 | return promise.future 38 | } 39 | 40 | /** 41 | Initializes a new resolved future with an error. 42 | 43 | - parameter error: The error to use to resolve the future 44 | 45 | - returns: A newly created future, resolved with error. 46 | */ 47 | public class func future(withError error: Error) -> Future { 48 | let promise = Promise() 49 | promise.setError(error) 50 | return promise.future 51 | } 52 | 53 | /** 54 | Initializes a new resolved future in cancelled state. 55 | 56 | - returns: A newly created future, resolved with cancellation. 57 | */ 58 | public class func cancelledFuture() -> Future { 59 | let promise = Promise() 60 | promise.cancel() 61 | return promise.future 62 | } 63 | 64 | /** 65 | Initializes a new resolved future. 66 | 67 | - parameter future: The future with the state to use to resolve the returning future 68 | 69 | - returns: A newly created and resolved future. 70 | */ 71 | public class func futureWithResolution(of future: Future) -> Future { 72 | switch future.state { 73 | case .result(let value): 74 | return self.future(withResult: value) 75 | case .error(let err): 76 | return self.future(withError: err) 77 | default: 78 | return cancelledFuture() 79 | } 80 | } 81 | 82 | // MARK: Resolution 83 | 84 | /** 85 | If the receiver is not resolved, the function waits for resolution before returning the result. 86 | */ 87 | public var result: ResultType? { 88 | get { 89 | wait() 90 | return state.getResult() 91 | } 92 | } 93 | 94 | /** 95 | If the receiver is not resolved, the function waits for resolution before returning the error. 96 | */ 97 | public var error: Error? { 98 | get { 99 | wait() 100 | return state.getError() 101 | } 102 | } 103 | 104 | /** 105 | If the receiver is not resolved, the function waits for resolution before returning if it was cancelled. 106 | */ 107 | public var isCancelled: Bool { 108 | get { 109 | return state.isCancelled() 110 | } 111 | } 112 | 113 | // MARK: State checks 114 | 115 | /** 116 | True if the future is in a resolved state, false otherwise. 117 | */ 118 | public func isResolved() -> Bool { 119 | cv.lock() 120 | let retVal = state != FutureState.unresolved 121 | cv.unlock() 122 | return retVal 123 | } 124 | /** 125 | True if the future has a result, false otherwise. 126 | */ 127 | public func hasResult() -> Bool { 128 | cv.lock() 129 | let retVal = (state.getResult() != nil) 130 | cv.unlock() 131 | return retVal 132 | } 133 | 134 | /** 135 | True if the future has an error, false otherwise. 136 | */ 137 | public func hasError() -> Bool { 138 | cv.lock() 139 | let retVal = (state.getError() != nil) 140 | cv.unlock() 141 | return retVal 142 | } 143 | 144 | // MARK: Waiting for resolution 145 | 146 | /** 147 | Blocks the current thread waiting for the receiver to be resolved. 148 | */ 149 | public func wait() { 150 | cv.lock() 151 | while (state == .unresolved) { 152 | cv.wait() 153 | } 154 | cv.unlock() 155 | } 156 | 157 | /** 158 | Blocks the current thread waiting for the receiver to be resolved before a given date. 159 | */ 160 | public func waitUntilDate(_ date: Date) -> Bool { 161 | cv.lock() 162 | var timeoutExpired = false 163 | while (state == .unresolved && !timeoutExpired) { 164 | timeoutExpired = !cv.wait(until: date) 165 | } 166 | cv.unlock() 167 | return !timeoutExpired 168 | } 169 | 170 | // MARK: State setting 171 | 172 | /** 173 | Resolves the receiver by setting a result. 174 | 175 | - parameter result: The result to use for the resolution. 176 | */ 177 | public func setResult(_ result: ResultType) { 178 | cv.lock() 179 | assert(state == .unresolved, "Cannot set result. Future already resolved") 180 | 181 | state = .result(result) 182 | let continuation = self.continuation 183 | self.continuation = nil 184 | 185 | cv.signal() 186 | cv.unlock() 187 | 188 | if let cont = continuation { 189 | cont(self) 190 | } 191 | } 192 | 193 | /** 194 | Resolves the receiver by setting an error. 195 | 196 | - parameter error: The error to use for the resolution. 197 | */ 198 | public func setError(_ error: Error) { 199 | cv.lock() 200 | assert(state == .unresolved, "Cannot set error. Future already resolved") 201 | 202 | state = .error(error) 203 | let continuation = self.continuation 204 | self.continuation = nil 205 | 206 | cv.signal() 207 | cv.unlock() 208 | 209 | if let cont = continuation { 210 | cont(self) 211 | } 212 | } 213 | 214 | /** 215 | Resolves the receiver by cancelling it. 216 | */ 217 | public func cancel() { 218 | cv.lock() 219 | assert(state == .unresolved, "Cannot cancel. Future already resolved") 220 | 221 | state = .cancelled 222 | let continuation = self.continuation 223 | self.continuation = nil 224 | 225 | cv.signal() 226 | cv.unlock() 227 | 228 | if let cont = continuation { 229 | cont(self) 230 | } 231 | } 232 | 233 | /** 234 | The string representation of the state of the receiver. 235 | 236 | - returns: A string describing the state. 237 | */ 238 | func stateString() -> String { 239 | var retVal: String = "Unresolved" 240 | switch state { 241 | case .result(let value): 242 | retVal = "Resolved with result: \(value)" 243 | case .error (let error): 244 | retVal = "Resolved with error: \(error)" 245 | case .cancelled: 246 | retVal = "Resolved with cancellation" 247 | case .unresolved: 248 | retVal = "Unresolved" 249 | } 250 | return retVal 251 | } 252 | 253 | } 254 | -------------------------------------------------------------------------------- /Framework/Sources/FutureState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Future+WhenAll.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum FutureState { 12 | case unresolved 13 | case result(ResultType) 14 | case error(Error) 15 | case cancelled 16 | 17 | func getResult() -> ResultType? { 18 | guard case .result(let value) = self else { return nil } 19 | return value 20 | } 21 | 22 | func getError() -> Error? { 23 | guard case .error(let err) = self else { return nil } 24 | return err 25 | } 26 | 27 | func isCancelled() -> Bool { 28 | return self == .cancelled 29 | } 30 | } 31 | 32 | func ==(lhs: FutureState, rhs: FutureState) -> Bool { 33 | var equal: Bool = false 34 | switch (lhs, rhs) { 35 | case (.unresolved, .unresolved): 36 | equal = true 37 | case (.error, .error): 38 | equal = true 39 | case (.result, .result): 40 | equal = true 41 | case (.cancelled, .cancelled): 42 | equal = true 43 | default: 44 | break 45 | } 46 | return equal 47 | } 48 | 49 | func !=(lhs: FutureState, rhs: FutureState) -> Bool { 50 | return !(lhs == rhs) 51 | } 52 | -------------------------------------------------------------------------------- /Framework/Sources/PromisError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PromisError.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum PromisError: Error { 12 | case futureContinuationAlreadySet 13 | case promiseDeallocatedBeforeBeingResolved 14 | } 15 | -------------------------------------------------------------------------------- /Framework/Sources/Promise.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Promise.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 14/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class Promise { 12 | 13 | public let future: Future 14 | 15 | public init() { 16 | self.future = Future() 17 | } 18 | 19 | deinit { 20 | if (!future.isResolved()) { 21 | let error = PromisError.promiseDeallocatedBeforeBeingResolved 22 | setError(error) 23 | } 24 | } 25 | 26 | public var description: String { 27 | return "" 28 | } 29 | 30 | // MARK: Future state setting 31 | 32 | /** 33 | Resolves the receiver by setting a result. 34 | 35 | - parameter result: The result to use for the resolution. 36 | */ 37 | public func setResult(_ result: ResultType) { 38 | future.setResult(result) 39 | } 40 | 41 | /** 42 | Resolves the receiver by setting an error. 43 | 44 | - parameter error: The error to use for the resolution. 45 | */ 46 | public func setError(_ error: Error) { 47 | future.setError(error) 48 | } 49 | 50 | /** 51 | Resolves the receiver by cancelling it. 52 | */ 53 | public func cancel() { 54 | future.cancel() 55 | } 56 | 57 | /** 58 | Resolve the receiver with the state of the given future. 59 | 60 | - parameter future: The future to use for the resolution. 61 | */ 62 | public func setResolution(of future: Future) { 63 | switch future.state { 64 | case .result(let value): 65 | setResult(value) 66 | case .error(let err): 67 | setError(err) 68 | default: 69 | cancel() 70 | } 71 | } 72 | 73 | // MARK: Generics (templating) supports 74 | 75 | /** 76 | Resolve the receiver with the state of the given future, ignoring the result state. This method allows chaining in `thenWithResult` to match the requirements forced by generics. 77 | 78 | - parameter future: The future to use for the resolution. 79 | */ 80 | func setResolutionOfFutureNotResolvedWithResult(_ future: Future) { 81 | switch future.state { 82 | case .error(let err): 83 | setError(err) 84 | default: 85 | cancel() 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | ruby '3.0.2' 2 | 3 | source 'https://rubygems.org' 4 | 5 | gem 'cocoapods', '~> 1.11.2' 6 | gem 'fastlane', '~> 2.206.2' 7 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.5) 5 | rexml 6 | activesupport (6.1.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.0) 13 | public_suffix (>= 2.0.2, < 5.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | artifactory (3.0.15) 18 | atomos (0.1.3) 19 | aws-eventstream (1.2.0) 20 | aws-partitions (1.595.0) 21 | aws-sdk-core (3.131.1) 22 | aws-eventstream (~> 1, >= 1.0.2) 23 | aws-partitions (~> 1, >= 1.525.0) 24 | aws-sigv4 (~> 1.1) 25 | jmespath (~> 1, >= 1.6.1) 26 | aws-sdk-kms (1.57.0) 27 | aws-sdk-core (~> 3, >= 3.127.0) 28 | aws-sigv4 (~> 1.1) 29 | aws-sdk-s3 (1.114.0) 30 | aws-sdk-core (~> 3, >= 3.127.0) 31 | aws-sdk-kms (~> 1) 32 | aws-sigv4 (~> 1.4) 33 | aws-sigv4 (1.5.0) 34 | aws-eventstream (~> 1, >= 1.0.2) 35 | babosa (1.0.4) 36 | claide (1.1.0) 37 | cocoapods (1.11.3) 38 | addressable (~> 2.8) 39 | claide (>= 1.0.2, < 2.0) 40 | cocoapods-core (= 1.11.3) 41 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 42 | cocoapods-downloader (>= 1.4.0, < 2.0) 43 | cocoapods-plugins (>= 1.0.0, < 2.0) 44 | cocoapods-search (>= 1.0.0, < 2.0) 45 | cocoapods-trunk (>= 1.4.0, < 2.0) 46 | cocoapods-try (>= 1.1.0, < 2.0) 47 | colored2 (~> 3.1) 48 | escape (~> 0.0.4) 49 | fourflusher (>= 2.3.0, < 3.0) 50 | gh_inspector (~> 1.0) 51 | molinillo (~> 0.8.0) 52 | nap (~> 1.0) 53 | ruby-macho (>= 1.0, < 3.0) 54 | xcodeproj (>= 1.21.0, < 2.0) 55 | cocoapods-core (1.11.3) 56 | activesupport (>= 5.0, < 7) 57 | addressable (~> 2.8) 58 | algoliasearch (~> 1.0) 59 | concurrent-ruby (~> 1.1) 60 | fuzzy_match (~> 2.0.4) 61 | nap (~> 1.0) 62 | netrc (~> 0.11) 63 | public_suffix (~> 4.0) 64 | typhoeus (~> 1.0) 65 | cocoapods-deintegrate (1.0.5) 66 | cocoapods-downloader (1.6.3) 67 | cocoapods-plugins (1.0.0) 68 | nap 69 | cocoapods-search (1.0.1) 70 | cocoapods-trunk (1.6.0) 71 | nap (>= 0.8, < 2.0) 72 | netrc (~> 0.11) 73 | cocoapods-try (1.2.0) 74 | colored (1.2) 75 | colored2 (3.1.2) 76 | commander (4.6.0) 77 | highline (~> 2.0.0) 78 | concurrent-ruby (1.1.10) 79 | declarative (0.0.20) 80 | digest-crc (0.6.4) 81 | rake (>= 12.0.0, < 14.0.0) 82 | domain_name (0.5.20190701) 83 | unf (>= 0.0.5, < 1.0.0) 84 | dotenv (2.7.6) 85 | emoji_regex (3.2.3) 86 | escape (0.0.4) 87 | ethon (0.15.0) 88 | ffi (>= 1.15.0) 89 | excon (0.92.3) 90 | faraday (1.10.0) 91 | faraday-em_http (~> 1.0) 92 | faraday-em_synchrony (~> 1.0) 93 | faraday-excon (~> 1.1) 94 | faraday-httpclient (~> 1.0) 95 | faraday-multipart (~> 1.0) 96 | faraday-net_http (~> 1.0) 97 | faraday-net_http_persistent (~> 1.0) 98 | faraday-patron (~> 1.0) 99 | faraday-rack (~> 1.0) 100 | faraday-retry (~> 1.0) 101 | ruby2_keywords (>= 0.0.4) 102 | faraday-cookie_jar (0.0.7) 103 | faraday (>= 0.8.0) 104 | http-cookie (~> 1.0.0) 105 | faraday-em_http (1.0.0) 106 | faraday-em_synchrony (1.0.0) 107 | faraday-excon (1.1.0) 108 | faraday-httpclient (1.0.1) 109 | faraday-multipart (1.0.3) 110 | multipart-post (>= 1.2, < 3) 111 | faraday-net_http (1.0.1) 112 | faraday-net_http_persistent (1.2.0) 113 | faraday-patron (1.0.0) 114 | faraday-rack (1.0.0) 115 | faraday-retry (1.0.3) 116 | faraday_middleware (1.2.0) 117 | faraday (~> 1.0) 118 | fastimage (2.2.6) 119 | fastlane (2.206.2) 120 | CFPropertyList (>= 2.3, < 4.0.0) 121 | addressable (>= 2.8, < 3.0.0) 122 | artifactory (~> 3.0) 123 | aws-sdk-s3 (~> 1.0) 124 | babosa (>= 1.0.3, < 2.0.0) 125 | bundler (>= 1.12.0, < 3.0.0) 126 | colored 127 | commander (~> 4.6) 128 | dotenv (>= 2.1.1, < 3.0.0) 129 | emoji_regex (>= 0.1, < 4.0) 130 | excon (>= 0.71.0, < 1.0.0) 131 | faraday (~> 1.0) 132 | faraday-cookie_jar (~> 0.0.6) 133 | faraday_middleware (~> 1.0) 134 | fastimage (>= 2.1.0, < 3.0.0) 135 | gh_inspector (>= 1.1.2, < 2.0.0) 136 | google-apis-androidpublisher_v3 (~> 0.3) 137 | google-apis-playcustomapp_v1 (~> 0.1) 138 | google-cloud-storage (~> 1.31) 139 | highline (~> 2.0) 140 | json (< 3.0.0) 141 | jwt (>= 2.1.0, < 3) 142 | mini_magick (>= 4.9.4, < 5.0.0) 143 | multipart-post (~> 2.0.0) 144 | naturally (~> 2.2) 145 | optparse (~> 0.1.1) 146 | plist (>= 3.1.0, < 4.0.0) 147 | rubyzip (>= 2.0.0, < 3.0.0) 148 | security (= 0.1.3) 149 | simctl (~> 1.6.3) 150 | terminal-notifier (>= 2.0.0, < 3.0.0) 151 | terminal-table (>= 1.4.5, < 2.0.0) 152 | tty-screen (>= 0.6.3, < 1.0.0) 153 | tty-spinner (>= 0.8.0, < 1.0.0) 154 | word_wrap (~> 1.0.0) 155 | xcodeproj (>= 1.13.0, < 2.0.0) 156 | xcpretty (~> 0.3.0) 157 | xcpretty-travis-formatter (>= 0.0.3) 158 | ffi (1.15.5) 159 | fourflusher (2.3.1) 160 | fuzzy_match (2.0.4) 161 | gh_inspector (1.1.3) 162 | google-apis-androidpublisher_v3 (0.21.0) 163 | google-apis-core (>= 0.4, < 2.a) 164 | google-apis-core (0.5.0) 165 | addressable (~> 2.5, >= 2.5.1) 166 | googleauth (>= 0.16.2, < 2.a) 167 | httpclient (>= 2.8.1, < 3.a) 168 | mini_mime (~> 1.0) 169 | representable (~> 3.0) 170 | retriable (>= 2.0, < 4.a) 171 | rexml 172 | webrick 173 | google-apis-iamcredentials_v1 (0.10.0) 174 | google-apis-core (>= 0.4, < 2.a) 175 | google-apis-playcustomapp_v1 (0.7.0) 176 | google-apis-core (>= 0.4, < 2.a) 177 | google-apis-storage_v1 (0.14.0) 178 | google-apis-core (>= 0.4, < 2.a) 179 | google-cloud-core (1.6.0) 180 | google-cloud-env (~> 1.0) 181 | google-cloud-errors (~> 1.0) 182 | google-cloud-env (1.6.0) 183 | faraday (>= 0.17.3, < 3.0) 184 | google-cloud-errors (1.2.0) 185 | google-cloud-storage (1.36.2) 186 | addressable (~> 2.8) 187 | digest-crc (~> 0.4) 188 | google-apis-iamcredentials_v1 (~> 0.1) 189 | google-apis-storage_v1 (~> 0.1) 190 | google-cloud-core (~> 1.6) 191 | googleauth (>= 0.16.2, < 2.a) 192 | mini_mime (~> 1.0) 193 | googleauth (1.1.3) 194 | faraday (>= 0.17.3, < 3.a) 195 | jwt (>= 1.4, < 3.0) 196 | memoist (~> 0.16) 197 | multi_json (~> 1.11) 198 | os (>= 0.9, < 2.0) 199 | signet (>= 0.16, < 2.a) 200 | highline (2.0.3) 201 | http-cookie (1.0.5) 202 | domain_name (~> 0.5) 203 | httpclient (2.8.3) 204 | i18n (1.10.0) 205 | concurrent-ruby (~> 1.0) 206 | jmespath (1.6.1) 207 | json (2.6.2) 208 | jwt (2.3.0) 209 | memoist (0.16.2) 210 | mini_magick (4.11.0) 211 | mini_mime (1.1.2) 212 | minitest (5.15.0) 213 | molinillo (0.8.0) 214 | multi_json (1.15.0) 215 | multipart-post (2.0.0) 216 | nanaimo (0.3.0) 217 | nap (1.1.0) 218 | naturally (2.2.1) 219 | netrc (0.11.0) 220 | optparse (0.1.1) 221 | os (1.1.4) 222 | plist (3.6.0) 223 | public_suffix (4.0.7) 224 | rake (13.0.6) 225 | representable (3.2.0) 226 | declarative (< 0.1.0) 227 | trailblazer-option (>= 0.1.1, < 0.2.0) 228 | uber (< 0.2.0) 229 | retriable (3.1.2) 230 | rexml (3.2.5) 231 | rouge (2.0.7) 232 | ruby-macho (2.5.1) 233 | ruby2_keywords (0.0.5) 234 | rubyzip (2.3.2) 235 | security (0.1.3) 236 | signet (0.16.1) 237 | addressable (~> 2.8) 238 | faraday (>= 0.17.5, < 3.0) 239 | jwt (>= 1.5, < 3.0) 240 | multi_json (~> 1.10) 241 | simctl (1.6.8) 242 | CFPropertyList 243 | naturally 244 | terminal-notifier (2.0.0) 245 | terminal-table (1.8.0) 246 | unicode-display_width (~> 1.1, >= 1.1.1) 247 | trailblazer-option (0.1.2) 248 | tty-cursor (0.7.1) 249 | tty-screen (0.8.1) 250 | tty-spinner (0.9.3) 251 | tty-cursor (~> 0.7) 252 | typhoeus (1.4.0) 253 | ethon (>= 0.9.0) 254 | tzinfo (2.0.4) 255 | concurrent-ruby (~> 1.0) 256 | uber (0.1.0) 257 | unf (0.1.4) 258 | unf_ext 259 | unf_ext (0.0.8.2) 260 | unicode-display_width (1.8.0) 261 | webrick (1.7.0) 262 | word_wrap (1.0.0) 263 | xcodeproj (1.21.0) 264 | CFPropertyList (>= 2.3.3, < 4.0) 265 | atomos (~> 0.1.3) 266 | claide (>= 1.0.2, < 2.0) 267 | colored2 (~> 3.1) 268 | nanaimo (~> 0.3.0) 269 | rexml (~> 3.2.4) 270 | xcpretty (0.3.0) 271 | rouge (~> 2.0.7) 272 | xcpretty-travis-formatter (1.0.1) 273 | xcpretty (~> 0.2, >= 0.0.7) 274 | zeitwerk (2.5.4) 275 | 276 | PLATFORMS 277 | arm64-darwin-21 278 | x86_64-darwin-19 279 | 280 | DEPENDENCIES 281 | cocoapods (~> 1.11.2) 282 | fastlane (~> 2.206.2) 283 | 284 | RUBY VERSION 285 | ruby 3.0.2p107 286 | 287 | BUNDLED WITH 288 | 2.2.22 289 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Alberto De Bortoli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.5 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "Promis", 7 | platforms: [.iOS(.v13)], 8 | products: [ 9 | .library( 10 | name: "Promis", 11 | targets: ["Promis"]) 12 | ], 13 | targets: [ 14 | .target( 15 | name: "Promis", 16 | path: "Framework/Sources"), 17 | .testTarget( 18 | name: "PromisTests", 19 | dependencies: ["Promis"], 20 | path: "Tests/Sources") 21 | ] 22 | ) 23 | -------------------------------------------------------------------------------- /Promis.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint Promis.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'Promis' 11 | s.version = ENV['LIB_VERSION'] 12 | s.summary = 'The easiest Future and Promises framework in Swift. No magic. No boilerplate.' 13 | s.description = <<-DESC 14 | The easiest Future and Promises framework in Swift. No magic. No boilerplate. 15 | - Fully unit-tested and documented 💯 16 | - Thread-safe 🚦 17 | - Clean interface 👼 18 | - Support for chaining ⛓ 19 | - Support for cancellation 🙅‍♂️ 20 | - Queue-based block execution if needed 🚆 21 | - Result type provided via generics 🚀 22 | - Keeping the magic to the minimum, leaving the code in a readable state without going off of a tangent with fancy and unnecessary design decisions ಠ_ಠ 23 | DESC 24 | 25 | s.homepage = 'https://github.com/albertodebortoli/Promis' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'Alberto De Bortoli' => 'albertodebortoli.com' } 28 | s.source = { :git => 'https://github.com/albertodebortoli/Promis.git', :tag => s.version.to_s } 29 | s.social_media_url = 'https://twitter.com/albertodebo' 30 | 31 | s.ios.deployment_target = '13.0' 32 | s.swift_version = '5.0' 33 | 34 | s.source_files = 'Framework/Sources/**/*.swift' 35 | s.frameworks = 'Foundation' 36 | 37 | s.test_spec 'UnitTests' do |test_spec| 38 | test_spec.source_files = 'Tests/Sources/**/*.swift' 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Promis 2 | 3 | [![Build Status](https://travis-ci.org/albertodebortoli/Promis.svg?branch=master)](https://travis-ci.org/albertodebortoli/Promis) 4 | [![Version](https://img.shields.io/cocoapods/v/Promis.svg?style=flat)](http://cocoapods.org/pods/Promis) 5 | [![License](https://img.shields.io/cocoapods/l/Promis.svg?style=flat)](http://cocoapods.org/pods/Promis) 6 | [![Platform](https://img.shields.io/cocoapods/p/Promis.svg?style=flat)](http://cocoapods.org/pods/Promis) 7 | 8 | The easiest Future and Promises framework in Swift. No magic. No boilerplate. 9 | 10 | ## Overview 11 | 12 | While starting from the Objective-C implementation of [JustPromises](https://github.com/justeat/JustPromises) and keeping the code minimalistic, this library adds the following: 13 | 14 | - conversion to Swift 4 15 | - usage of generics to allow great type inference that wasn't possible in Objective-C 16 | - overall refactoring for fresh and modern code 17 | - remove the unnecessary and misleading concept of Progress causing bad patterns to emerge 18 | 19 | You can read about the theory behind Future and Promises on [Wikipedia](https://en.wikipedia.org/wiki/Futures_and_promises), here are the main things you should know to get started. 20 | 21 | - Promises represent the promise that a task will be fulfilled in the future while the future holds the state of such resolution. 22 | - Futures, when created are in the unresolved state and can be resolved with one of 3 states: with a result, an error, or being cancelled. 23 | - Futures can be chained, allowing to avoid the [pyramid of doom](https://twitter.com/piscis168/status/641237956070666240) problem, clean up asynchronous code paths and simplify error handling. 24 | 25 | Promis brags about being/having: 26 | 27 | - Fully unit-tested and documented 💯 28 | - Thread-safe 🚦 29 | - Clean interface 👼 30 | - Support for chaining ⛓ 31 | - Support for cancellation 🙅‍♂️ 32 | - Queue-based block execution if needed 🚆 33 | - Result type provided via generics 🚀 34 | - Keeping the magic to the minimum, leaving the code in a readable state without going off of a tangent with fancy and unnecessary design decisions ಠ_ಠ 35 | 36 | ## Alternatives 37 | 38 | Other open-source solutions exist such as: 39 | - [FutureKit](https://github.com/FutureKit/FutureKit) 40 | - [PromiseKit](https://github.com/mxcl/PromiseKit) 41 | - [JustPromises](https://github.com/justeat/JustPromises) 42 | - [Promises](https://github.com/google/promises) 43 | 44 | Promis takes inspiration from the Objective-C version of JustPromises developed by the iOS Team of [Just Eat](https://www.just-eat.com/) which is really concise and minimalistic, while other libraries are more weighty. 45 | 46 | ## Usage 47 | 48 | The following example should outline the main benefits of using futures via chaining. 49 | 50 | ```swift 51 | let request = URLRequest(url: URL(string: "http://example.com")!) 52 | 53 | // starts by hitting an API to download data 54 | getData(request: request).thenWithResult { data in 55 | // continue by parsing the retrieved data 56 | parse(data: data) 57 | }.thenWithResult { parsedData in 58 | // continue by mapping the parsed data 59 | map(data: parsedData) 60 | }.onError { error in 61 | // executed only in case an error occurred in the chain 62 | print("error: " + String(describing: error)) 63 | }.finally(queue: .main) { future in 64 | // always executed, no matter the state of the previous future or how the chain did perform 65 | switch future.state { 66 | case .result(let value): 67 | print(String(describing: value)) 68 | case .error(let err): 69 | print(String(describing: err)) 70 | case .cancelled: 71 | print("future is in a cancelled state") 72 | case .unresolved: 73 | print("this really cannot be if any chaining block is executed") 74 | } 75 | } 76 | ``` 77 | 78 | The functions used in the example have the following signatures: 79 | 80 | ```swift 81 | func getData(request: URLRequest) -> Future 82 | func parse(data: Data) -> Future<[Dictionary]> 83 | func map(data: [Dictionary]) -> Future<[FooBar]> 84 | ``` 85 | 86 | Promises and Futures are parametrized leveraging the power of the generics, meaning that Swift can infer the type of the result compile type. This was a considerable limitation in the Objective-C world and we can now prevent lots of issues at build time thanks to the static typing nature of the language. The state of the future is an enum defined as follows: 87 | 88 | ```swift 89 | enum FutureState { 90 | case unresolved 91 | case result(ResultType) 92 | case error(Error) 93 | case cancelled 94 | } 95 | ``` 96 | 97 | Promises are created and resolved like so: 98 | 99 | ```swift 100 | let promise = Promise() 101 | promise.setResult(value) 102 | // or 103 | promise.setError(error) 104 | // or 105 | promise.cancel() 106 | ``` 107 | 108 | Continuation methods used for chaining are the following: 109 | 110 | ```swift 111 | func then(queue: DispatchQueue? = nil, task: @escaping (Future) -> Future) -> Future 112 | func thenWithResult(queue: DispatchQueue? = nil, continuation: @escaping (ResultType) -> Future) -> Future { 113 | func onError(queue: DispatchQueue? = nil, continuation: @escaping (Error) -> Void) -> Future { 114 | func finally(queue: DispatchQueue? = nil, block: @escaping (Future) -> Void) 115 | ``` 116 | 117 | All the functions can accept an optional `DispatchQueue` used to perform the continuation blocks. 118 | 119 | 120 | ### Best practices 121 | 122 | Functions wrapping async tasks should follow the below pattern: 123 | 124 | ```swift 125 | func wrappedAsyncTask() -> Future { 126 | 127 | let promise = Promise() 128 | someAsyncOperation() { data, error in 129 | // resolve the promise according to how the async operations did go 130 | switch (data, error) { 131 | case (let data?, _): 132 | promise.setResult(data) 133 | case (nil, let error?): 134 | promise.setError(error) 135 | // etc. 136 | } 137 | } 138 | return promise.future 139 | } 140 | ``` 141 | 142 | You could chain an `onError` continuation before returning the future to allow in-line error handling, which I find to be a very handy pattern. 143 | 144 | ```swift 145 | // ... 146 | return promise.future.onError {error in 147 | // handle/log error 148 | } 149 | ``` 150 | 151 | ### Pitfalls 152 | 153 | When using `then` or `thenWithResult`, the following should be taken in consideration. 154 | 155 | ```swift 156 | ...}.thenWithResult { data -> Future in 157 | /** 158 | If a block is not trivial, Swift cannot infer the type of the closure and gives the error 159 | 'Unable to infer complex closure return type; add explicit type to disambiguate' 160 | so you'll have to add `-> Future to the block signature 161 | 162 | You can make the closure complex just by adding any extra statement (like a print). 163 | 164 | All the more reason to structure your code as done in the first given example :) 165 | */ 166 | print("complex closure") 167 | return parse(data: data) 168 | } 169 | ``` 170 | 171 | Please check the GettingStarted playground in the demo app to see the complete implementation of the above examples. 172 | 173 | ## Installation 174 | 175 | ### CocoaPods 176 | 177 | Add `Promis` to your Podfile 178 | 179 | ```ruby 180 | use_frameworks! 181 | target 'MyTarget' do 182 | pod 'Promis', '~> x.y.z' 183 | end 184 | ``` 185 | 186 | ```bash 187 | $ pod install 188 | ``` 189 | 190 | ### Carthage 191 | 192 | ```ruby 193 | github "albertodebortoli/Promis" ~> "x.y.z" 194 | ``` 195 | 196 | Then on your application target *Build Phases* settings tab, add a "New Run Script Phase". Create a Run Script with the following content: 197 | 198 | ```ruby 199 | /usr/local/bin/carthage copy-frameworks 200 | ``` 201 | 202 | and add the following paths under "Input Files": 203 | 204 | ```ruby 205 | $(SRCROOT)/Carthage/Build/iOS/Promis.framework 206 | ``` 207 | 208 | ## Author 209 | 210 | Alberto De Bortoli 211 | Twitter: [@albertodebo](https://twitter.com/albertodebo) 212 | GitHub: [albertodebortoli](https://github.com/albertodebortoli) 213 | website: [albertodebortoli.com](http://albertodebortoli.com) 214 | 215 | ## License 216 | 217 | Promis is available under the Apache 2 license in respect of JustPromises which this library takes inspiration from. See the [LICENSE](LICENSE) file for more info. 218 | -------------------------------------------------------------------------------- /Tests/Sources/PromisTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PromisTests.swift 3 | // Promis 4 | // 5 | // Created by Alberto De Bortoli on 11/10/2017. 6 | // Copyright © 2017 Alberto De Bortoli. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Promis 11 | 12 | class PromisTests: XCTestCase { 13 | 14 | let TestErrorDomain = "com.albertodebortoli.promis.tests" 15 | 16 | func test_GivenUnresolvedPromise_WhenCheckingFutureState_ThenStateIsUnresolved() { 17 | let p = Promise() 18 | let f = p.future 19 | XCTAssert(f.state == .unresolved) 20 | } 21 | 22 | func test_GivenUnresolvedPromise_WhenAskingFutureState_ThenStateChecksReturnFalse() { 23 | let p = Promise() 24 | let f = p.future 25 | XCTAssertFalse(f.isResolved()) 26 | XCTAssertFalse(f.hasResult()) 27 | XCTAssertFalse(f.hasError()) 28 | XCTAssertFalse(f.isCancelled) 29 | } 30 | 31 | func test_GivenFutureWithResult_ThenFutureHasResult() { 32 | let f = Future.future(withResult: true) 33 | XCTAssertTrue(f.isResolved()) 34 | XCTAssertTrue(f.hasResult()) 35 | XCTAssertFalse(f.hasError()) 36 | XCTAssertFalse(f.isCancelled) 37 | } 38 | 39 | func test_GivenFutureWithError_ThenFutureHasError() { 40 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 41 | let f = Future.future(withError: error) 42 | XCTAssertTrue(f.isResolved()) 43 | XCTAssertFalse(f.hasResult()) 44 | XCTAssertTrue(f.hasError()) 45 | XCTAssertFalse(f.isCancelled) 46 | } 47 | 48 | func test_GivenCancelledFuture_ThenFutureIsCancelled() { 49 | let f = Future.cancelledFuture() 50 | XCTAssertTrue(f.isResolved()) 51 | XCTAssertFalse(f.hasResult()) 52 | XCTAssertFalse(f.hasError()) 53 | XCTAssertTrue(f.isCancelled) 54 | } 55 | 56 | func test_GivenFutureWithResult_WhenCreatingFutureWithResolutionOfFuture_ThenFutureHasResult() { 57 | let f = Future.future(withResult: true) 58 | let f2 = Future.futureWithResolution(of: f) 59 | XCTAssertTrue(f2.isResolved()) 60 | XCTAssertTrue(f2.hasResult()) 61 | XCTAssertFalse(f2.hasError()) 62 | XCTAssertFalse(f2.isCancelled) 63 | } 64 | 65 | func test_GivenFutureWithError_WhenCreatingFutureWithResolutionOfFuture_ThenFutureHasError() { 66 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 67 | let f = Future.future(withError: error) 68 | let f2 = Future.futureWithResolution(of: f) 69 | XCTAssertTrue(f2.isResolved()) 70 | XCTAssertFalse(f2.hasResult()) 71 | XCTAssertTrue(f2.hasError()) 72 | XCTAssertFalse(f2.isCancelled) 73 | } 74 | 75 | func test_GivenCancelledFuture_WhenCreatingFutureWithResolutionOfFuture_ThenFutureIsCancelled() { 76 | let f = Future.cancelledFuture() 77 | let f2 = Future.futureWithResolution(of: f) 78 | XCTAssertTrue(f2.isResolved()) 79 | XCTAssertFalse(f2.hasResult()) 80 | XCTAssertFalse(f2.hasError()) 81 | XCTAssertTrue(f2.isCancelled) 82 | } 83 | 84 | func test_GivenPromise_WhenSetResult_ThenFutureHasResult() { 85 | let p = Promise() 86 | let f = p.future 87 | 88 | p.setResult("1") 89 | XCTAssertTrue(f.isResolved()) 90 | XCTAssertTrue(f.hasResult()) 91 | XCTAssertFalse(f.hasError()) 92 | XCTAssertFalse(f.isCancelled) 93 | 94 | XCTAssertEqual(f.result!, "1") 95 | XCTAssertNil(f.error) 96 | } 97 | 98 | func test_GivenPromise_WhenSetResult_ThenFutureHasStateResolvedWithResult() { 99 | let p = Promise() 100 | let f = p.future 101 | 102 | p.setResult("1") 103 | XCTAssert(f.state == .result("1")) 104 | } 105 | 106 | func test_GivenPromise_WhenSetError_ThenFutureHasError() { 107 | let p = Promise() 108 | let f = p.future 109 | 110 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 111 | p.setError(error) 112 | XCTAssertTrue(f.isResolved()) 113 | XCTAssertFalse(f.hasResult()) 114 | XCTAssertTrue(f.hasError()) 115 | XCTAssertFalse(f.isCancelled) 116 | 117 | XCTAssertNil(f.result) 118 | XCTAssertEqual(f.error! as NSError, error) 119 | } 120 | 121 | func test_GivenPromise_WhenSetError_ThenFutureHasStateResolvedWithError() { 122 | let p = Promise() 123 | let f = p.future 124 | 125 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 126 | p.setError(error) 127 | XCTAssert(f.state == .error(error)) 128 | } 129 | 130 | func test_GivenPromise_WhenCancelled_ThenFutureIsCancelled() { 131 | let p = Promise() 132 | let f = p.future 133 | 134 | p.cancel() 135 | XCTAssertTrue(f.isResolved()) 136 | XCTAssertFalse(f.hasResult()) 137 | XCTAssertFalse(f.hasError()) 138 | XCTAssertTrue(f.isCancelled) 139 | 140 | XCTAssertNil(f.result) 141 | XCTAssertNil(f.error) 142 | } 143 | 144 | func test_GivenPromise_WhenCancelled_ThenFutureHasStateResolvedWithCancellation() { 145 | let p = Promise() 146 | let f = p.future 147 | 148 | p.cancel() 149 | XCTAssert(f.state == .cancelled) 150 | } 151 | 152 | func test_GivenPromise_WhenFutureSetResultWhileWaiting_ThenResultIsSet() { 153 | let p = Promise() 154 | let f = p.future 155 | 156 | DispatchQueue.global().asyncAfter(deadline: .now() + 1) { 157 | p.setResult("1") 158 | } 159 | 160 | XCTAssertEqual(f.result, "1") 161 | } 162 | 163 | func test_GivenPromise_WhenFutureSetResultWhileExplicitlyWaiting_ThenResultIsSet() { 164 | let p = Promise() 165 | let f = p.future 166 | 167 | DispatchQueue.global().asyncAfter(deadline: .now() + 1) { 168 | p.setResult("1") 169 | } 170 | 171 | f.wait() 172 | XCTAssertTrue(f.hasResult()) 173 | XCTAssertEqual(f.result!, "1") 174 | } 175 | 176 | func test_GivenPromise_WhenNotSatisfiedAndDealloced_ThenFutureHasError() { 177 | var f: Future! 178 | autoreleasepool { 179 | let p = Promise() 180 | f = p.future 181 | } 182 | 183 | XCTAssertTrue(f.hasError()) 184 | XCTAssert((f.error as! PromisError) == .promiseDeallocatedBeforeBeingResolved) 185 | } 186 | 187 | func test_GivenPromise_WhenFutureIsAskedToWaitUntilDateAndSetResult_ThenFutureHasResult() { 188 | let p = Promise() 189 | let f = p.future 190 | 191 | XCTAssertFalse(f.waitUntilDate(Date(timeIntervalSinceNow: 1))) 192 | 193 | p.setResult("1") 194 | XCTAssertTrue(f.waitUntilDate(Date(timeIntervalSinceNow: 1))) 195 | 196 | XCTAssertTrue(f.hasResult()) 197 | XCTAssertEqual(f.result, "1") 198 | } 199 | 200 | func test_GivenPromise_WhenSetContinuationAndResultIsSet_ThenContinuationIsExecuted() { 201 | let p = Promise() 202 | let f = p.future 203 | 204 | let exp: XCTestExpectation = expectation(description: "test expectation") 205 | f.finally { future in 206 | XCTAssertEqual(future.result, "1") 207 | exp.fulfill() 208 | } 209 | 210 | p.setResult("1") 211 | waitForExpectations(timeout: 10, handler: nil) 212 | } 213 | 214 | func test_GivenPromise_WhenSetContinuationOnGlobalQueueAndResultIsSet_ThenContinuationIsExecuted() { 215 | let p = Promise() 216 | let f = p.future 217 | 218 | let exp: XCTestExpectation = expectation(description: "test expectation") 219 | let queue = DispatchQueue.global() 220 | 221 | f.finally(queue: queue) { future in 222 | XCTAssertEqual(future.result, "1") 223 | exp.fulfill() 224 | } 225 | 226 | p.setResult("1") 227 | waitForExpectations(timeout: 10, handler: nil) 228 | } 229 | 230 | func test_GivenPromise_WhenFutureContinuesWithSynchronousTaskAndResultIsSet_ThenNewFutureHasResult() { 231 | let p = Promise() 232 | let f = p.future 233 | 234 | let f2 = f.then { future -> Future in 235 | let p = Promise() 236 | p.setResult(future.result! + "2") 237 | return p.future 238 | } 239 | 240 | p.setResult("1") 241 | XCTAssertTrue(f2.hasResult()) 242 | XCTAssertEqual(f2.result!, "12") 243 | } 244 | 245 | func test_GivenPromise_WhenFutureContinuesWithNotSatisfyingSynchronousTaskAndResultIsSet_ThenNewFutureHasError() { 246 | let p = Promise() 247 | let f = p.future 248 | 249 | let f2 = f.then { future -> Future in 250 | let p = Promise() 251 | return p.future 252 | } 253 | 254 | p.setResult("1") 255 | XCTAssertTrue(f2.hasError()) 256 | XCTAssertNotNil(f2.error) 257 | } 258 | 259 | func test_GivenPromise_WhenFutureContinuesWithAsynchronousTaskAndResultIsSet_ThenNewFutureHasResult() { 260 | let p = Promise() 261 | let f = p.future 262 | 263 | let f2 = f.then { future -> Future in 264 | let p = Promise() 265 | 266 | let queue = DispatchQueue.global() 267 | queue.asyncAfter(deadline: .now() + 1, execute: { 268 | p.setResult(future.result! + "2") 269 | }) 270 | 271 | return p.future 272 | } 273 | 274 | p.setResult("1") 275 | f2.wait() 276 | XCTAssertTrue(f2.hasResult()) 277 | XCTAssertEqual(f2.result!, "12") 278 | } 279 | 280 | func test_GivenPromise_WhenContinuesWithTaskAndSetResult_ThenFutureHasResult() { 281 | let p = Promise() 282 | let f = p.future 283 | 284 | let f2 = f.then { future -> Future in 285 | XCTAssertTrue(future.hasResult()) 286 | return Future.futureWithResolution(of: future) 287 | } 288 | 289 | p.setResult("42") 290 | XCTAssertTrue(f2.hasResult()) 291 | XCTAssertEqual(f2.result!, "42") 292 | } 293 | 294 | func test_GivenPromise_WhenContinuesWithTaskAndSetError_ThenFutureHasError() { 295 | let p = Promise() 296 | let f = p.future 297 | 298 | let f2 = f.then { future -> Future in 299 | XCTAssertTrue(future.hasError()) 300 | return Future.futureWithResolution(of: future) 301 | } 302 | 303 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 304 | p.setError(error) 305 | XCTAssertTrue(f2.hasError()) 306 | XCTAssertEqual(f2.error! as NSError, error) 307 | } 308 | 309 | func test_GivenPromise_WhenContinuesWithTaskAndCancelled_ThenFutureIsCancelled() { 310 | let p = Promise() 311 | let f = p.future 312 | 313 | let f2 = f.then { future -> Future in 314 | XCTAssertTrue(future.isCancelled) 315 | return Future.futureWithResolution(of: future) 316 | } 317 | 318 | p.cancel() 319 | XCTAssertTrue(f2.isCancelled) 320 | } 321 | 322 | func test_GivenPromise_WhenContinuesWithTaskOnGlobalQueueAndResultIsSet_ThenFutureHasResult() { 323 | let p = Promise() 324 | let f = p.future 325 | 326 | let queue = DispatchQueue.global() 327 | 328 | let f2 = f.then(queue: queue) { future -> Future in 329 | let p = Promise() 330 | p.setResult(future.result! + "2") 331 | return p.future 332 | } 333 | 334 | p.setResult("1") 335 | 336 | f2.wait() 337 | XCTAssertTrue(f2.hasResult()) 338 | XCTAssertEqual(f2.result!, "12") 339 | } 340 | 341 | func test_GivenPromise_WhenFutureContinuesWithResultAndResultIsSet_ThenResultIsSetOnSubsequentFuture() { 342 | let p = Promise() 343 | let f = p.future 344 | 345 | let f2 = f.thenWithResult { val -> Future in 346 | let p = Promise() 347 | p.setResult(val + "2") 348 | return p.future 349 | } 350 | 351 | p.setResult("1") 352 | XCTAssertTrue(f2.hasResult()) 353 | XCTAssertEqual(f2.result!, "12") 354 | } 355 | 356 | func test_GivenPromise_WhenFutureContinuesWithResultAndErrorIsSet_ThenSubsequentFutureHasError() { 357 | let p = Promise() 358 | let f = p.future 359 | 360 | let f2 = f.thenWithResult { val -> Future in 361 | let p = Promise() 362 | p.setResult(val + "2") 363 | return p.future 364 | } 365 | 366 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 367 | p.setError(error) 368 | 369 | XCTAssertTrue(f2.hasError()) 370 | XCTAssertEqual(f2.error! as NSError, error) 371 | } 372 | 373 | func test_GivenPromise_WhenFutureContinuesWithResultAndIsCancelled_ThenSubsequentFutureIsCancelled() { 374 | let p = Promise() 375 | let f = p.future 376 | 377 | let f2 = f.thenWithResult { val -> Future in 378 | XCTAssert(false, "This block should not be called") 379 | let p = Promise() 380 | p.setResult(val + "2") 381 | return p.future 382 | } 383 | 384 | p.cancel() 385 | XCTAssertTrue(f2.isCancelled) 386 | XCTAssertNil(f2.result) 387 | } 388 | 389 | func test_GivenPromise_WhenContinuesWithResultAndCancelledFuture_ThenFutureIsCancelled() { 390 | let p = Promise() 391 | let f = p.future 392 | 393 | let f2 = f.thenWithResult { val in 394 | return Future.cancelledFuture() 395 | } 396 | 397 | p.setResult("1") 398 | 399 | XCTAssertTrue(f2.isCancelled) 400 | XCTAssertNil(f2.result) 401 | } 402 | 403 | func test_GivenPromise_WhenContinuesWithResultAndSetResult_ThenFutureHasResult() { 404 | let p = Promise() 405 | let f = p.future 406 | 407 | let queue = DispatchQueue.global() 408 | 409 | let f2 = f.thenWithResult(queue: queue) { val -> Future in 410 | let p = Promise() 411 | p.setResult(val + "2") 412 | return p.future 413 | } 414 | 415 | p.setResult("1") 416 | 417 | f2.wait() 418 | XCTAssertTrue(f2.hasResult()) 419 | XCTAssertEqual(f2.result!, "12") 420 | } 421 | 422 | func test_GivenPromise_WhenContinuesWithResultOnGlobalQueueAndCancelled_ThenFutureIsCancelled() { 423 | let p = Promise() 424 | let f = p.future 425 | 426 | let queue = DispatchQueue.global() 427 | 428 | let f2 = f.thenWithResult(queue: queue) { val in 429 | return Future.cancelledFuture() 430 | } 431 | 432 | p.setResult("1") 433 | 434 | f2.wait() 435 | XCTAssertTrue(f2.isCancelled) 436 | XCTAssertNil(f2.result) 437 | } 438 | 439 | func test_GivenPromise_WhenFutureContinuesWithErrorAndResultIsSet_ThenSubsequentFutureHasError() { 440 | let p = Promise() 441 | let f = p.future 442 | 443 | let exp: XCTestExpectation = expectation(description: "test expectation") 444 | 445 | let f2 = f.onError { err in 446 | XCTAssert(false, "This block should not be called") 447 | }.then { future -> Future in 448 | XCTAssert(true, "This block should be called") 449 | exp.fulfill() 450 | return Future.futureWithResolution(of: future) 451 | } 452 | 453 | p.setResult("1") 454 | 455 | waitForExpectations(timeout: 10, handler: nil) 456 | XCTAssertTrue(f2.hasResult()) 457 | XCTAssertEqual(f2.result!, "1") 458 | } 459 | 460 | func test_GivenPromise_WhenFutureContinuesWithErrorAndErrorIsSet_ThenSubsequentFutureHasError() { 461 | let p = Promise() 462 | let f = p.future 463 | 464 | let exp: XCTestExpectation = expectation(description: "test expectation") 465 | 466 | let f2 = f.onError { err in 467 | XCTAssert(true, "This block should be called") 468 | }.then { future -> Future in 469 | XCTAssert(true, "This block should be called") 470 | exp.fulfill() 471 | return Future.futureWithResolution(of: future) 472 | } 473 | 474 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 475 | p.setError(error) 476 | 477 | waitForExpectations(timeout: 10, handler: nil) 478 | XCTAssertTrue(f2.hasError()) 479 | XCTAssertEqual(f2.error! as NSError, error) 480 | } 481 | 482 | func test_GivenPromise_WhenFutureContinuesWithErrorAndIsCancelled_ThenSubsequentFutureIsCancelled() { 483 | let p = Promise() 484 | let f = p.future 485 | 486 | let f2 = f.onError { err in 487 | XCTAssert(false, "This block should not be called") 488 | } 489 | 490 | p.cancel() 491 | 492 | XCTAssertTrue(f2.isCancelled) 493 | XCTAssertNil(f2.result) 494 | } 495 | 496 | func test_GivenPromise_WhenContinuesWithErrorAndSetResult_ThenFutureHasResult() { 497 | let p = Promise() 498 | let f = p.future 499 | 500 | let queue = DispatchQueue.global() 501 | 502 | let f2 = f.onError(queue: queue) { err in 503 | XCTAssert(false, "This block should not be called") 504 | } 505 | 506 | p.setResult("1") 507 | 508 | f2.wait() 509 | XCTAssertTrue(f2.hasResult()) 510 | XCTAssertEqual(f2.result!, "1") 511 | } 512 | 513 | func test_GivenPromise_WhenContinuesWithErrorOnGlobalQueueAndSetError_ThenFutureHasError() { 514 | let p = Promise() 515 | let f = p.future 516 | 517 | let exp: XCTestExpectation = expectation(description: "test expectation") 518 | 519 | let queue = DispatchQueue.global() 520 | 521 | let f2 = f.onError(queue: queue) { err in 522 | exp.fulfill() 523 | } 524 | 525 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 526 | p.setError(error) 527 | 528 | f2.wait() 529 | 530 | waitForExpectations(timeout: 10, handler: nil) 531 | XCTAssertTrue(f2.hasError()) 532 | XCTAssertNotNil(f2.error) 533 | } 534 | 535 | func test_GivenPromise_WhenSetContinuationTwice_ThemExceptionIsRaised() { 536 | let p = Promise() 537 | let f = p.future 538 | 539 | try! f.setContinuation { future in } 540 | 541 | XCTAssertThrowsError(try f.setContinuation { future in }) 542 | } 543 | 544 | func test_GivenPromises_WhenAllPromisesSucceeded_ThenWhenAllFutureHasResult() { 545 | let p1 = Promise() 546 | let p2 = Promise() 547 | let p3 = Promise() 548 | 549 | let futures = [p1.future, p2.future, p3.future] 550 | let allFuture = Future.whenAll(futures) 551 | 552 | XCTAssertFalse(allFuture.hasResult()) 553 | p3.setResult("3") 554 | XCTAssertFalse(allFuture.hasResult()) 555 | p1.setResult("1") 556 | XCTAssertFalse(allFuture.hasResult()) 557 | p2.setResult("2") 558 | 559 | XCTAssertTrue(allFuture.hasResult()) 560 | 561 | let results = allFuture.result! 562 | XCTAssertEqual(results[0].getResult(), "1") 563 | XCTAssertEqual(results[1].getResult(), "2") 564 | XCTAssertEqual(results[2].getResult(), "3") 565 | } 566 | 567 | func test_GivenPromises_WhenAllPromisesAreSatisfied_ThenWhenAllFutureHasResult() { 568 | let p1 = Promise() 569 | let p2 = Promise() 570 | let p3 = Promise() 571 | 572 | let futures = [p1.future, p2.future, p3.future] 573 | let allFuture = Future.whenAll(futures) 574 | 575 | XCTAssertFalse(allFuture.hasResult()) 576 | p3.cancel() 577 | XCTAssertFalse(allFuture.hasResult()) 578 | p1.setResult("1") 579 | XCTAssertFalse(allFuture.hasResult()) 580 | let error = NSError(domain: TestErrorDomain, code:0, userInfo:nil) 581 | p2.setError(error) 582 | 583 | XCTAssertTrue(allFuture.hasResult()) 584 | 585 | let results = allFuture.result! 586 | XCTAssertEqual(results[0].getResult(), "1") 587 | XCTAssertNotNil(results[1].getError()) 588 | XCTAssertTrue(results[2].isCancelled()) 589 | } 590 | 591 | func test_GivenUnresolvedPromise_WhenPrintedDescription_ThenProperDescriptionIsPrinted() { 592 | let p = Promise() 593 | let testValue: String = "Unresolved".lowercased() 594 | let targetValue: String = p.description.lowercased() 595 | XCTAssertNotNil(targetValue.range(of: testValue)) 596 | } 597 | 598 | func test_GivenPromiseResolvedWithResult_WhenPrintedDescription_ThenProperDescriptionIsPrinted() { 599 | let p = Promise() 600 | p.setResult("42") 601 | let testValue = "Resolved with result".lowercased() 602 | let targetValue = p.description.lowercased() 603 | XCTAssertNotNil(targetValue.range(of: testValue)) 604 | } 605 | 606 | func test_GivenPromiseResolvedWithError_WhenPrintedDescription_ThenProperDescriptionIsPrinted() { 607 | let p = Promise() 608 | p.setError(NSError(domain: TestErrorDomain, code:0, userInfo:nil)) 609 | let testValue = "Resolved with error".lowercased() 610 | let targetValue = p.description.lowercased() 611 | XCTAssertNotNil(targetValue.range(of: testValue)) 612 | } 613 | 614 | func test_GivenCancelledPromise_WhenPrintedDescription_ThenProperDescriptionIsPrinted() { 615 | let p = Promise() 616 | p.cancel() 617 | let testValue = "Resolved with cancellation".lowercased() 618 | let targetValue = p.description.lowercased() 619 | XCTAssertNotNil(targetValue.range(of: testValue)) 620 | } 621 | 622 | } 623 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform :ios 2 | 3 | platform :ios do 4 | 5 | before_all do 6 | ensure_bundle_exec 7 | $test_output_folder = "fastlane/test_output" 8 | $derived_data_folder = "./derived_data" 9 | $workspace_filename = "Example/Promis.xcworkspace" 10 | $common_test_xcargs = "COMPILER_INDEX_STORE_ENABLE=NO" 11 | end 12 | 13 | lane :unit_tests_cocoapods do |parameters| 14 | UI.user_error! "Missing parameter 'device'" unless parameters.has_key?(:device) 15 | device = parameters[:device] 16 | run_tests( 17 | workspace: $workspace_filename, 18 | scheme: "DemoApp", 19 | testplan: "UnitTests", 20 | device: device, 21 | code_coverage: true, 22 | result_bundle: true, 23 | concurrent_workers: 1, 24 | xcargs: $common_test_xcargs, 25 | derived_data_path: $derived_data_folder 26 | ) 27 | end 28 | 29 | lane :unit_tests_spm do |parameters| 30 | UI.user_error! "Missing parameter 'device'" unless parameters.has_key?(:device) 31 | device = parameters[:device] 32 | run_tests( 33 | package_path: "./", 34 | scheme: "Promis", 35 | device: device, 36 | code_coverage: true, 37 | result_bundle: true, 38 | concurrent_workers: 1, 39 | xcargs: $common_test_xcargs, 40 | derived_data_path: $derived_data_folder, 41 | output_directory: $test_output_folder 42 | ) 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## iOS 17 | 18 | ### ios unit_tests_cocoapods 19 | 20 | ```sh 21 | [bundle exec] fastlane ios unit_tests_cocoapods 22 | ``` 23 | 24 | 25 | 26 | ### ios unit_tests_spm 27 | 28 | ```sh 29 | [bundle exec] fastlane ios unit_tests_spm 30 | ``` 31 | 32 | 33 | 34 | ---- 35 | 36 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 37 | 38 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 39 | 40 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 41 | -------------------------------------------------------------------------------- /fastlane/report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------