├── .gitignore ├── LICENSE ├── Podfile ├── Readme.md ├── WarpDrive.podspec ├── WarpDrive.xcodeproj └── project.pbxproj ├── WarpDrive ├── Delay.swift ├── Info.plist ├── Threading.swift ├── Waiting.swift └── WarpDrive.h └── WarpDriveTests ├── DelayTests.swift ├── Info.plist ├── ThreadingTests.swift └── WaitingTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Pods 3 | Podfile.lock 4 | WarpDrive.xcworkspace 5 | WarpDrive.xcodeproj/project.xcworkspace 6 | WarpDrive.xcodeproj/xcuserdata 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Jens Ravens (http://jensravens.de) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '8.0' 3 | # Uncomment this line if you're using Swift 4 | use_frameworks! 5 | 6 | target "WarpDrive" do 7 | pod "Interstellar", "~> 1.2" 8 | end 9 | 10 | target "WarpDriveTests" do 11 | end 12 | 13 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ![WarpDrive](https://raw.githubusercontent.com/JensRavens/WarpDrive/assets/header.jpg) 2 | 3 | Timing and threading helpers for Interstellar 4 | 5 | > This library does not use the term FRP (Functional Reactive Programming) in the way it was 6 | > defined by Conal Elliot, but as a paradigm that is both functional and reactive. Read more 7 | > about the difference at [Why I cannot say FRP but I just did](https://medium.com/@andrestaltz/why-i-cannot-say-frp-but-i-just-did-d5ffaa23973b). 8 | 9 | ## Features 10 | 11 | - [x] Multithreading with GCD becomes a breeze 12 | - [x] Delay and throttle `Signal` 13 | - [x] Wait for async signals 14 | 15 | ## Requirements 16 | 17 | - iOS 7.0+ / Mac OS X 10.9+ 18 | - Xcode 7 19 | 20 | --- 21 | 22 | ## Usage 23 | 24 | > For a full guide on how Interstellar works the the series of blog posts about 25 | > [Functional Reactive Programming in Swift](http://jensravens.de/series/functional-reactive-programming-in-swift/) 26 | > or the talk at UIKonf 2015 [How to use Functional Reactive Programming without Black Magic](http://jensravens.de/uikonf-talk/). 27 | 28 | ### Ridiculously simple multithreading 29 | 30 | This example executes the greet function on a background thread, then calls next on the main thread. 31 | 32 | ```swift 33 | let text = Signal() 34 | let greet: String->String = { subject in 35 | return "Hello \(subject)" 36 | } 37 | text.ensure(Thread.background).map(greet).ensure(Thread.main).next { text in 38 | println(text) 39 | } 40 | text.update(.Success("World")) 41 | ``` 42 | 43 | --- 44 | 45 | ## Communication 46 | 47 | - If you **found a bug**, open an issue. 48 | - If you **have a feature request**, open an issue. 49 | - If you **want to contribute**, submit a pull request. 50 | 51 | ## Installation 52 | 53 | > **Dynamic frameworks on iOS require a minimum deployment target of iOS 8 or later.** 54 | > 55 | > To use Interstellar with a project targeting iOS 7, you must include all Swift files directly in your project. 56 | 57 | ### CocoaPods 58 | 59 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. 60 | 61 | CocoaPods 0.36 adds supports for Swift and embedded frameworks. You can install it with the following command: 62 | 63 | ```bash 64 | $ gem install cocoapods 65 | ``` 66 | 67 | To integrate Interstellar and WarpDrive into your Xcode project using CocoaPods, specify it in your `Podfile`: 68 | 69 | ```ruby 70 | source 'https://github.com/CocoaPods/Specs.git' 71 | platform :ios, '8.0' 72 | use_frameworks! 73 | 74 | pod 'WarpDrive' 75 | ``` 76 | 77 | Then, run the following command: 78 | 79 | ```bash 80 | $ pod install 81 | ``` 82 | 83 | --- 84 | 85 | ## Credits 86 | 87 | Interstellar and WarpDrive is owned and maintained by [Jens Ravens](http://jensravens.de). 88 | 89 | ## License 90 | 91 | WarpDrive is released under the MIT license. See LICENSE for details. 92 | -------------------------------------------------------------------------------- /WarpDrive.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'WarpDrive' 3 | s.version = '1.0.0' 4 | s.license = 'MIT' 5 | s.summary = 'Timing and threading helpers for Interstellar' 6 | s.homepage = 'https://github.com/JensRavens/WarpDrive' 7 | s.social_media_url = 'http://twitter.com/JensRavens' 8 | s.authors = { 'Jens Ravens' => 'jens@nerdgeschoss.de' } 9 | s.source = { :git => 'https://github.com/JensRavens/WarpDrive.git', :tag => s.version } 10 | 11 | s.ios.deployment_target = '8.0' 12 | s.osx.deployment_target = '10.9' 13 | s.watchos.deployment_target = '2.0' 14 | s.tvos.deployment_target = '9.0' 15 | 16 | s.source_files = 'WarpDrive/*.swift' 17 | 18 | s.dependency 'Interstellar', '~> 1.2' 19 | 20 | s.requires_arc = true 21 | end 22 | 23 | -------------------------------------------------------------------------------- /WarpDrive.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8F3A8C2A1BCCFCCF004EAFD7 /* WarpDrive.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F3A8C291BCCFCCF004EAFD7 /* WarpDrive.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 8F3A8C311BCCFCCF004EAFD7 /* WarpDrive.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F3A8C261BCCFCCF004EAFD7 /* WarpDrive.framework */; settings = {ASSET_TAGS = (); }; }; 12 | 8F3A8C361BCCFCCF004EAFD7 /* WaitingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C351BCCFCCF004EAFD7 /* WaitingTests.swift */; }; 13 | 8F3A8C411BCCFD04004EAFD7 /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C401BCCFD04004EAFD7 /* Threading.swift */; settings = {ASSET_TAGS = (); }; }; 14 | 8F3A8C431BCCFE5B004EAFD7 /* Waiting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C421BCCFE5B004EAFD7 /* Waiting.swift */; settings = {ASSET_TAGS = (); }; }; 15 | 8F3A8C451BCD0979004EAFD7 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C441BCD0979004EAFD7 /* Delay.swift */; settings = {ASSET_TAGS = (); }; }; 16 | 8F3A8C471BCD1047004EAFD7 /* DelayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C461BCD1047004EAFD7 /* DelayTests.swift */; settings = {ASSET_TAGS = (); }; }; 17 | 8F3A8C491BCD120F004EAFD7 /* ThreadingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3A8C481BCD120F004EAFD7 /* ThreadingTests.swift */; settings = {ASSET_TAGS = (); }; }; 18 | CCD9845E96CE321D6B5B9610 /* Pods_WarpDrive.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C464E9AD412F76A3A97640D /* Pods_WarpDrive.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 8F3A8C321BCCFCCF004EAFD7 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 8F3A8C1D1BCCFCCF004EAFD7 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 8F3A8C251BCCFCCF004EAFD7; 27 | remoteInfo = WarpDrive; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 0C464E9AD412F76A3A97640D /* Pods_WarpDrive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WarpDrive.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 8F3A8C261BCCFCCF004EAFD7 /* WarpDrive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WarpDrive.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 8F3A8C291BCCFCCF004EAFD7 /* WarpDrive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WarpDrive.h; sourceTree = ""; }; 35 | 8F3A8C2B1BCCFCCF004EAFD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 8F3A8C301BCCFCCF004EAFD7 /* WarpDriveTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WarpDriveTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 8F3A8C351BCCFCCF004EAFD7 /* WaitingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitingTests.swift; sourceTree = ""; }; 38 | 8F3A8C371BCCFCCF004EAFD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 8F3A8C401BCCFD04004EAFD7 /* Threading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = ""; }; 40 | 8F3A8C421BCCFE5B004EAFD7 /* Waiting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Waiting.swift; sourceTree = ""; }; 41 | 8F3A8C441BCD0979004EAFD7 /* Delay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = ""; }; 42 | 8F3A8C461BCD1047004EAFD7 /* DelayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelayTests.swift; sourceTree = ""; }; 43 | 8F3A8C481BCD120F004EAFD7 /* ThreadingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreadingTests.swift; sourceTree = ""; }; 44 | A0A3A55E38DF71F3CDAF4F9C /* Pods-WarpDrive.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WarpDrive.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WarpDrive/Pods-WarpDrive.debug.xcconfig"; sourceTree = ""; }; 45 | D66B270BC946C7EA83BC321A /* Pods-WarpDrive.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WarpDrive.release.xcconfig"; path = "Pods/Target Support Files/Pods-WarpDrive/Pods-WarpDrive.release.xcconfig"; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 8F3A8C221BCCFCCF004EAFD7 /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | CCD9845E96CE321D6B5B9610 /* Pods_WarpDrive.framework in Frameworks */, 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | 8F3A8C2D1BCCFCCF004EAFD7 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 8F3A8C311BCCFCCF004EAFD7 /* WarpDrive.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 482D47BE8265DECBE59D2755 /* Frameworks */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 0C464E9AD412F76A3A97640D /* Pods_WarpDrive.framework */, 72 | ); 73 | name = Frameworks; 74 | sourceTree = ""; 75 | }; 76 | 5BE0C8C97EC2DC1FABAF6888 /* Pods */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | A0A3A55E38DF71F3CDAF4F9C /* Pods-WarpDrive.debug.xcconfig */, 80 | D66B270BC946C7EA83BC321A /* Pods-WarpDrive.release.xcconfig */, 81 | ); 82 | name = Pods; 83 | sourceTree = ""; 84 | }; 85 | 8F3A8C1C1BCCFCCF004EAFD7 = { 86 | isa = PBXGroup; 87 | children = ( 88 | 8F3A8C281BCCFCCF004EAFD7 /* WarpDrive */, 89 | 8F3A8C341BCCFCCF004EAFD7 /* WarpDriveTests */, 90 | 8F3A8C271BCCFCCF004EAFD7 /* Products */, 91 | 5BE0C8C97EC2DC1FABAF6888 /* Pods */, 92 | 482D47BE8265DECBE59D2755 /* Frameworks */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 8F3A8C271BCCFCCF004EAFD7 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 8F3A8C261BCCFCCF004EAFD7 /* WarpDrive.framework */, 100 | 8F3A8C301BCCFCCF004EAFD7 /* WarpDriveTests.xctest */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 8F3A8C281BCCFCCF004EAFD7 /* WarpDrive */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 8F3A8C401BCCFD04004EAFD7 /* Threading.swift */, 109 | 8F3A8C421BCCFE5B004EAFD7 /* Waiting.swift */, 110 | 8F3A8C441BCD0979004EAFD7 /* Delay.swift */, 111 | 8F3A8C291BCCFCCF004EAFD7 /* WarpDrive.h */, 112 | 8F3A8C2B1BCCFCCF004EAFD7 /* Info.plist */, 113 | ); 114 | path = WarpDrive; 115 | sourceTree = ""; 116 | }; 117 | 8F3A8C341BCCFCCF004EAFD7 /* WarpDriveTests */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 8F3A8C351BCCFCCF004EAFD7 /* WaitingTests.swift */, 121 | 8F3A8C461BCD1047004EAFD7 /* DelayTests.swift */, 122 | 8F3A8C481BCD120F004EAFD7 /* ThreadingTests.swift */, 123 | 8F3A8C371BCCFCCF004EAFD7 /* Info.plist */, 124 | ); 125 | path = WarpDriveTests; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXHeadersBuildPhase section */ 131 | 8F3A8C231BCCFCCF004EAFD7 /* Headers */ = { 132 | isa = PBXHeadersBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | 8F3A8C2A1BCCFCCF004EAFD7 /* WarpDrive.h in Headers */, 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXHeadersBuildPhase section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | 8F3A8C251BCCFCCF004EAFD7 /* WarpDrive */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = 8F3A8C3A1BCCFCCF004EAFD7 /* Build configuration list for PBXNativeTarget "WarpDrive" */; 145 | buildPhases = ( 146 | F9B5CCEBC93889EC8AA0357E /* Check Pods Manifest.lock */, 147 | 8F3A8C211BCCFCCF004EAFD7 /* Sources */, 148 | 8F3A8C221BCCFCCF004EAFD7 /* Frameworks */, 149 | 8F3A8C231BCCFCCF004EAFD7 /* Headers */, 150 | 8F3A8C241BCCFCCF004EAFD7 /* Resources */, 151 | 0C6EA9A54332442CF0169194 /* Copy Pods Resources */, 152 | ); 153 | buildRules = ( 154 | ); 155 | dependencies = ( 156 | ); 157 | name = WarpDrive; 158 | productName = WarpDrive; 159 | productReference = 8F3A8C261BCCFCCF004EAFD7 /* WarpDrive.framework */; 160 | productType = "com.apple.product-type.framework"; 161 | }; 162 | 8F3A8C2F1BCCFCCF004EAFD7 /* WarpDriveTests */ = { 163 | isa = PBXNativeTarget; 164 | buildConfigurationList = 8F3A8C3D1BCCFCCF004EAFD7 /* Build configuration list for PBXNativeTarget "WarpDriveTests" */; 165 | buildPhases = ( 166 | 8F3A8C2C1BCCFCCF004EAFD7 /* Sources */, 167 | 8F3A8C2D1BCCFCCF004EAFD7 /* Frameworks */, 168 | 8F3A8C2E1BCCFCCF004EAFD7 /* Resources */, 169 | ); 170 | buildRules = ( 171 | ); 172 | dependencies = ( 173 | 8F3A8C331BCCFCCF004EAFD7 /* PBXTargetDependency */, 174 | ); 175 | name = WarpDriveTests; 176 | productName = WarpDriveTests; 177 | productReference = 8F3A8C301BCCFCCF004EAFD7 /* WarpDriveTests.xctest */; 178 | productType = "com.apple.product-type.bundle.unit-test"; 179 | }; 180 | /* End PBXNativeTarget section */ 181 | 182 | /* Begin PBXProject section */ 183 | 8F3A8C1D1BCCFCCF004EAFD7 /* Project object */ = { 184 | isa = PBXProject; 185 | attributes = { 186 | LastSwiftUpdateCheck = 0700; 187 | LastUpgradeCheck = 0700; 188 | ORGANIZATIONNAME = "nerdgeschoss GmbH"; 189 | TargetAttributes = { 190 | 8F3A8C251BCCFCCF004EAFD7 = { 191 | CreatedOnToolsVersion = 7.0; 192 | }; 193 | 8F3A8C2F1BCCFCCF004EAFD7 = { 194 | CreatedOnToolsVersion = 7.0; 195 | }; 196 | }; 197 | }; 198 | buildConfigurationList = 8F3A8C201BCCFCCF004EAFD7 /* Build configuration list for PBXProject "WarpDrive" */; 199 | compatibilityVersion = "Xcode 3.2"; 200 | developmentRegion = English; 201 | hasScannedForEncodings = 0; 202 | knownRegions = ( 203 | en, 204 | ); 205 | mainGroup = 8F3A8C1C1BCCFCCF004EAFD7; 206 | productRefGroup = 8F3A8C271BCCFCCF004EAFD7 /* Products */; 207 | projectDirPath = ""; 208 | projectRoot = ""; 209 | targets = ( 210 | 8F3A8C251BCCFCCF004EAFD7 /* WarpDrive */, 211 | 8F3A8C2F1BCCFCCF004EAFD7 /* WarpDriveTests */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | 8F3A8C241BCCFCCF004EAFD7 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | 8F3A8C2E1BCCFCCF004EAFD7 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | }; 231 | /* End PBXResourcesBuildPhase section */ 232 | 233 | /* Begin PBXShellScriptBuildPhase section */ 234 | 0C6EA9A54332442CF0169194 /* Copy Pods Resources */ = { 235 | isa = PBXShellScriptBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | inputPaths = ( 240 | ); 241 | name = "Copy Pods Resources"; 242 | outputPaths = ( 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | shellPath = /bin/sh; 246 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-WarpDrive/Pods-WarpDrive-resources.sh\"\n"; 247 | showEnvVarsInLog = 0; 248 | }; 249 | F9B5CCEBC93889EC8AA0357E /* Check Pods Manifest.lock */ = { 250 | isa = PBXShellScriptBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | ); 254 | inputPaths = ( 255 | ); 256 | name = "Check Pods Manifest.lock"; 257 | outputPaths = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | shellPath = /bin/sh; 261 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 262 | showEnvVarsInLog = 0; 263 | }; 264 | /* End PBXShellScriptBuildPhase section */ 265 | 266 | /* Begin PBXSourcesBuildPhase section */ 267 | 8F3A8C211BCCFCCF004EAFD7 /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 8F3A8C451BCD0979004EAFD7 /* Delay.swift in Sources */, 272 | 8F3A8C411BCCFD04004EAFD7 /* Threading.swift in Sources */, 273 | 8F3A8C431BCCFE5B004EAFD7 /* Waiting.swift in Sources */, 274 | ); 275 | runOnlyForDeploymentPostprocessing = 0; 276 | }; 277 | 8F3A8C2C1BCCFCCF004EAFD7 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 8F3A8C361BCCFCCF004EAFD7 /* WaitingTests.swift in Sources */, 282 | 8F3A8C491BCD120F004EAFD7 /* ThreadingTests.swift in Sources */, 283 | 8F3A8C471BCD1047004EAFD7 /* DelayTests.swift in Sources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | /* End PBXSourcesBuildPhase section */ 288 | 289 | /* Begin PBXTargetDependency section */ 290 | 8F3A8C331BCCFCCF004EAFD7 /* PBXTargetDependency */ = { 291 | isa = PBXTargetDependency; 292 | target = 8F3A8C251BCCFCCF004EAFD7 /* WarpDrive */; 293 | targetProxy = 8F3A8C321BCCFCCF004EAFD7 /* PBXContainerItemProxy */; 294 | }; 295 | /* End PBXTargetDependency section */ 296 | 297 | /* Begin XCBuildConfiguration section */ 298 | 8F3A8C381BCCFCCF004EAFD7 /* Debug */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | ALWAYS_SEARCH_USER_PATHS = NO; 302 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 303 | CLANG_CXX_LIBRARY = "libc++"; 304 | CLANG_ENABLE_MODULES = YES; 305 | CLANG_ENABLE_OBJC_ARC = YES; 306 | CLANG_WARN_BOOL_CONVERSION = YES; 307 | CLANG_WARN_CONSTANT_CONVERSION = YES; 308 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 309 | CLANG_WARN_EMPTY_BODY = YES; 310 | CLANG_WARN_ENUM_CONVERSION = YES; 311 | CLANG_WARN_INT_CONVERSION = YES; 312 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 313 | CLANG_WARN_UNREACHABLE_CODE = YES; 314 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 315 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 316 | COPY_PHASE_STRIP = NO; 317 | CURRENT_PROJECT_VERSION = 1; 318 | DEBUG_INFORMATION_FORMAT = dwarf; 319 | ENABLE_STRICT_OBJC_MSGSEND = YES; 320 | ENABLE_TESTABILITY = YES; 321 | GCC_C_LANGUAGE_STANDARD = gnu99; 322 | GCC_DYNAMIC_NO_PIC = NO; 323 | GCC_NO_COMMON_BLOCKS = YES; 324 | GCC_OPTIMIZATION_LEVEL = 0; 325 | GCC_PREPROCESSOR_DEFINITIONS = ( 326 | "DEBUG=1", 327 | "$(inherited)", 328 | ); 329 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 330 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 331 | GCC_WARN_UNDECLARED_SELECTOR = YES; 332 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 333 | GCC_WARN_UNUSED_FUNCTION = YES; 334 | GCC_WARN_UNUSED_VARIABLE = YES; 335 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 336 | MTL_ENABLE_DEBUG_INFO = YES; 337 | ONLY_ACTIVE_ARCH = YES; 338 | SDKROOT = iphoneos; 339 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 340 | TARGETED_DEVICE_FAMILY = "1,2"; 341 | VERSIONING_SYSTEM = "apple-generic"; 342 | VERSION_INFO_PREFIX = ""; 343 | }; 344 | name = Debug; 345 | }; 346 | 8F3A8C391BCCFCCF004EAFD7 /* Release */ = { 347 | isa = XCBuildConfiguration; 348 | buildSettings = { 349 | ALWAYS_SEARCH_USER_PATHS = NO; 350 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 351 | CLANG_CXX_LIBRARY = "libc++"; 352 | CLANG_ENABLE_MODULES = YES; 353 | CLANG_ENABLE_OBJC_ARC = YES; 354 | CLANG_WARN_BOOL_CONVERSION = YES; 355 | CLANG_WARN_CONSTANT_CONVERSION = YES; 356 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 357 | CLANG_WARN_EMPTY_BODY = YES; 358 | CLANG_WARN_ENUM_CONVERSION = YES; 359 | CLANG_WARN_INT_CONVERSION = YES; 360 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 361 | CLANG_WARN_UNREACHABLE_CODE = YES; 362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 364 | COPY_PHASE_STRIP = NO; 365 | CURRENT_PROJECT_VERSION = 1; 366 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 367 | ENABLE_NS_ASSERTIONS = NO; 368 | ENABLE_STRICT_OBJC_MSGSEND = YES; 369 | GCC_C_LANGUAGE_STANDARD = gnu99; 370 | GCC_NO_COMMON_BLOCKS = YES; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 378 | MTL_ENABLE_DEBUG_INFO = NO; 379 | SDKROOT = iphoneos; 380 | TARGETED_DEVICE_FAMILY = "1,2"; 381 | VALIDATE_PRODUCT = YES; 382 | VERSIONING_SYSTEM = "apple-generic"; 383 | VERSION_INFO_PREFIX = ""; 384 | }; 385 | name = Release; 386 | }; 387 | 8F3A8C3B1BCCFCCF004EAFD7 /* Debug */ = { 388 | isa = XCBuildConfiguration; 389 | baseConfigurationReference = A0A3A55E38DF71F3CDAF4F9C /* Pods-WarpDrive.debug.xcconfig */; 390 | buildSettings = { 391 | CLANG_ENABLE_MODULES = YES; 392 | DEFINES_MODULE = YES; 393 | DYLIB_COMPATIBILITY_VERSION = 1; 394 | DYLIB_CURRENT_VERSION = 1; 395 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 396 | INFOPLIST_FILE = WarpDrive/Info.plist; 397 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 398 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 399 | PRODUCT_BUNDLE_IDENTIFIER = de.nerdgeschoss.WarpDrive; 400 | PRODUCT_NAME = "$(TARGET_NAME)"; 401 | SKIP_INSTALL = YES; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 403 | }; 404 | name = Debug; 405 | }; 406 | 8F3A8C3C1BCCFCCF004EAFD7 /* Release */ = { 407 | isa = XCBuildConfiguration; 408 | baseConfigurationReference = D66B270BC946C7EA83BC321A /* Pods-WarpDrive.release.xcconfig */; 409 | buildSettings = { 410 | CLANG_ENABLE_MODULES = YES; 411 | DEFINES_MODULE = YES; 412 | DYLIB_COMPATIBILITY_VERSION = 1; 413 | DYLIB_CURRENT_VERSION = 1; 414 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 415 | INFOPLIST_FILE = WarpDrive/Info.plist; 416 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = de.nerdgeschoss.WarpDrive; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SKIP_INSTALL = YES; 421 | }; 422 | name = Release; 423 | }; 424 | 8F3A8C3E1BCCFCCF004EAFD7 /* Debug */ = { 425 | isa = XCBuildConfiguration; 426 | buildSettings = { 427 | INFOPLIST_FILE = WarpDriveTests/Info.plist; 428 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 429 | PRODUCT_BUNDLE_IDENTIFIER = de.nerdgeschoss.WarpDriveTests; 430 | PRODUCT_NAME = "$(TARGET_NAME)"; 431 | }; 432 | name = Debug; 433 | }; 434 | 8F3A8C3F1BCCFCCF004EAFD7 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | INFOPLIST_FILE = WarpDriveTests/Info.plist; 438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 439 | PRODUCT_BUNDLE_IDENTIFIER = de.nerdgeschoss.WarpDriveTests; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | }; 442 | name = Release; 443 | }; 444 | /* End XCBuildConfiguration section */ 445 | 446 | /* Begin XCConfigurationList section */ 447 | 8F3A8C201BCCFCCF004EAFD7 /* Build configuration list for PBXProject "WarpDrive" */ = { 448 | isa = XCConfigurationList; 449 | buildConfigurations = ( 450 | 8F3A8C381BCCFCCF004EAFD7 /* Debug */, 451 | 8F3A8C391BCCFCCF004EAFD7 /* Release */, 452 | ); 453 | defaultConfigurationIsVisible = 0; 454 | defaultConfigurationName = Release; 455 | }; 456 | 8F3A8C3A1BCCFCCF004EAFD7 /* Build configuration list for PBXNativeTarget "WarpDrive" */ = { 457 | isa = XCConfigurationList; 458 | buildConfigurations = ( 459 | 8F3A8C3B1BCCFCCF004EAFD7 /* Debug */, 460 | 8F3A8C3C1BCCFCCF004EAFD7 /* Release */, 461 | ); 462 | defaultConfigurationIsVisible = 0; 463 | defaultConfigurationName = Release; 464 | }; 465 | 8F3A8C3D1BCCFCCF004EAFD7 /* Build configuration list for PBXNativeTarget "WarpDriveTests" */ = { 466 | isa = XCConfigurationList; 467 | buildConfigurations = ( 468 | 8F3A8C3E1BCCFCCF004EAFD7 /* Debug */, 469 | 8F3A8C3F1BCCFCCF004EAFD7 /* Release */, 470 | ); 471 | defaultConfigurationIsVisible = 0; 472 | defaultConfigurationName = Release; 473 | }; 474 | /* End XCConfigurationList section */ 475 | }; 476 | rootObject = 8F3A8C1D1BCCFCCF004EAFD7 /* Project object */; 477 | } 478 | -------------------------------------------------------------------------------- /WarpDrive/Delay.swift: -------------------------------------------------------------------------------- 1 | // Threading.swift 2 | // 3 | // Copyright (c) 2015 Jens Ravens (http://jensravens.de) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | import Interstellar 25 | 26 | public extension Signal { 27 | /** 28 | Creates a new signal that mirrors the original signal but is delayed by x seconds. If no queue is specified, the new signal will call it's observers and transforms on the main queue. 29 | */ 30 | public func delay(seconds: NSTimeInterval, queue: dispatch_queue_t = dispatch_get_main_queue()) -> Signal { 31 | let signal = Signal() 32 | subscribe { result in 33 | let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC))) 34 | dispatch_after(delayTime, queue) { 35 | signal.update(result) 36 | } 37 | } 38 | return signal; 39 | } 40 | } -------------------------------------------------------------------------------- /WarpDrive/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 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /WarpDrive/Threading.swift: -------------------------------------------------------------------------------- 1 | // Threading.swift 2 | // 3 | // Copyright (c) 2015 Jens Ravens (http://jensravens.de) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | import Interstellar 25 | 26 | /** 27 | Several functions that should make multithreading simpler. 28 | Use this functions together with Signal.ensure: 29 | Signal.ensure(Thread.main) // will create a new Signal on the main queue 30 | */ 31 | public final class Thread { 32 | 33 | /// Transform a signal to the main queue 34 | public static func main(a: Result, completion: Result->Void) { 35 | queue(dispatch_get_main_queue())(a, completion) 36 | } 37 | 38 | /// Transform the signal to a specified queue (despite the name this could also be the main queue) 39 | public static func queue(queue: dispatch_queue_t)(_ a: Result, _ completion: Result->Void) { 40 | dispatch_async(queue){ 41 | completion(a) 42 | } 43 | } 44 | 45 | /// Transform the signal to a global background queue with priority default 46 | public static func background(a: Result, completion: Result->Void) { 47 | let q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 48 | queue(q)(a, completion) 49 | } 50 | } -------------------------------------------------------------------------------- /WarpDrive/Waiting.swift: -------------------------------------------------------------------------------- 1 | // Threading.swift 2 | // 3 | // Copyright (c) 2015 Jens Ravens (http://jensravens.de) 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 13 | // all 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 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | import Interstellar 25 | 26 | public extension Signal { 27 | /** 28 | Wait until the signal updates the next time. This will block the current thread until there 29 | is an error or a successfull value. In case of an error, the error will be thrown. 30 | */ 31 | public func wait() throws -> T { 32 | let sema = dispatch_semaphore_create(0) 33 | var result: Result? 34 | subscribe { r in 35 | result = r 36 | dispatch_semaphore_signal(sema) 37 | } 38 | dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 39 | switch result! { 40 | case let .Success(t): return t 41 | case let .Error(e): throw e 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /WarpDrive/WarpDrive.h: -------------------------------------------------------------------------------- 1 | // 2 | // WarpDrive.h 3 | // WarpDrive 4 | // 5 | // Created by Jens Ravens on 13/10/15. 6 | // Copyright © 2015 nerdgeschoss GmbH. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for WarpDrive. 12 | FOUNDATION_EXPORT double WarpDriveVersionNumber; 13 | 14 | //! Project version string for WarpDrive. 15 | FOUNDATION_EXPORT const unsigned char WarpDriveVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /WarpDriveTests/DelayTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WarpDriveTests.swift 3 | // WarpDriveTests 4 | // 5 | // Created by Jens Ravens on 13/10/15. 6 | // Copyright © 2015 nerdgeschoss GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import Interstellar 12 | @testable import WarpDrive 13 | 14 | class DelayTests: XCTestCase { 15 | func testShouldDispatchToMainQueue() { 16 | let expectation = expectationWithDescription("delay called") 17 | Signal("test").delay(0.1).subscribe { _ in 18 | XCTAssertTrue(NSThread.isMainThread()) 19 | expectation.fulfill() 20 | } 21 | waitForExpectationsWithTimeout(0.2, handler: nil) 22 | } 23 | 24 | func testDispatchToSelectedQueue() { 25 | let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 26 | let expectation = expectationWithDescription("delay called") 27 | Signal("test").delay(0.1, queue: queue).subscribe { _ in 28 | XCTAssertFalse(NSThread.isMainThread()) 29 | expectation.fulfill() 30 | } 31 | waitForExpectationsWithTimeout(0.2, handler: nil) 32 | } 33 | 34 | func testDispatchAfterGivenTime() { 35 | // wait 0.2 seconds and check if action from 0.1 seconds already happened 36 | var value: String? = nil 37 | let expectation = expectationWithDescription("delay called") 38 | Signal("test").delay(0.2).subscribe { _ in 39 | XCTAssertEqual(value, "value") 40 | expectation.fulfill() 41 | } 42 | let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 43 | dispatch_after(delayTime, dispatch_get_main_queue()) { 44 | value = "value" 45 | } 46 | waitForExpectationsWithTimeout(0.2, handler: nil) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /WarpDriveTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /WarpDriveTests/ThreadingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WarpDriveTests.swift 3 | // WarpDriveTests 4 | // 5 | // Created by Jens Ravens on 13/10/15. 6 | // Copyright © 2015 nerdgeschoss GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import Interstellar 12 | @testable import WarpDrive 13 | 14 | class ThreadingTests: XCTestCase { 15 | func mainTest(expectation: XCTestExpectation?)(r: Result, completion:(Result->Void)) { 16 | XCTAssertTrue(NSThread.isMainThread()) 17 | expectation?.fulfill() 18 | } 19 | 20 | func testShouldDispatchToMainQueue() { 21 | let expectation = expectationWithDescription("thread called") 22 | let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 23 | dispatch_async(queue) { 24 | Signal("test") 25 | .ensure(WarpDrive.Thread.main) 26 | .ensure(mainTest(expectation)) 27 | } 28 | waitForExpectationsWithTimeout(0.1, handler: nil) 29 | } 30 | 31 | func testDispatchToSelectedQueue() { 32 | let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 33 | let expectation = expectationWithDescription("thread called") 34 | Signal("test") 35 | .ensure(Thread.queue(queue)) 36 | .subscribe { _ in 37 | XCTAssertFalse(NSThread.isMainThread()) 38 | expectation.fulfill() 39 | } 40 | waitForExpectationsWithTimeout(0.2, handler: nil) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /WarpDriveTests/WaitingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WarpDriveTests.swift 3 | // WarpDriveTests 4 | // 5 | // Created by Jens Ravens on 13/10/15. 6 | // Copyright © 2015 nerdgeschoss GmbH. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import Interstellar 12 | @testable import WarpDrive 13 | 14 | class WaitingTests: XCTestCase { 15 | func asyncOperation(delay: Double)(t: T, completion: Result->Void) { 16 | let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 17 | Signal(t).delay(delay, queue: queue).subscribe(completion) 18 | } 19 | 20 | func fail(t: T) throws -> T { 21 | throw NSError(domain: "Error", code: 400, userInfo: nil) 22 | } 23 | 24 | 25 | func testWaitingForSuccess() { 26 | let greeting = try! Signal("hello") 27 | .flatMap(self.asyncOperation(0.2)) 28 | .wait() 29 | XCTAssertEqual(greeting, "hello") 30 | } 31 | 32 | func testWaitingForFail() { 33 | do { 34 | try Signal("hello") 35 | .flatMap(self.asyncOperation(0.2)) 36 | .flatMap(fail) 37 | .wait() 38 | XCTFail("This place should never be reached due to an error.") 39 | } catch { 40 | 41 | } 42 | } 43 | } 44 | --------------------------------------------------------------------------------