Skip to content

Commit a01ee29

Browse files
authored
Merge pull request #47 from ishkawa/swift-3
Converting to Swift 3 (take 2)
2 parents 95be402 + 57b7081 commit a01ee29

17 files changed

+155
-167
lines changed

Action.swift

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import RxCocoa
66
public typealias CocoaAction = Action<Void, Void>
77

88
/// Possible errors from invoking execute()
9-
public enum ActionError: ErrorType {
10-
case NotEnabled
11-
case UnderlyingError(ErrorType)
9+
public enum ActionError: Error {
10+
case notEnabled
11+
case underlyingError(Error)
1212
}
1313

1414
/// TODO: Add some documentation.
1515
public final class Action<Input, Element> {
16-
public typealias WorkFactory = Input -> Observable<Element>
16+
public typealias WorkFactory = (Input) -> Observable<Element>
1717

1818
public let _enabledIf: Observable<Bool>
1919
public let workFactory: WorkFactory
@@ -23,83 +23,73 @@ public final class Action<Input, Element> {
2323
/// All inputs are always appear in this subject even if the action is not enabled.
2424
/// Thus, inputs count equals elements count + errors count.
2525
public let inputs = PublishSubject<Input>()
26-
private let _completed = PublishSubject<Void>()
26+
fileprivate let _completed = PublishSubject<Void>()
2727

2828
/// Errors aggrevated from invocations of execute().
2929
/// Delivered on whatever scheduler they were sent from.
3030
public var errors: Observable<ActionError> {
3131
return self._errors.asObservable()
3232
}
33-
private let _errors = PublishSubject<ActionError>()
33+
fileprivate let _errors = PublishSubject<ActionError>()
3434

3535
/// Whether or not we're currently executing.
3636
/// Delivered on whatever scheduler they were sent from.
3737
public var elements: Observable<Element> {
3838
return self._elements.asObservable()
3939
}
40-
private let _elements = PublishSubject<Element>()
40+
fileprivate let _elements = PublishSubject<Element>()
4141

4242
/// Whether or not we're currently executing.
4343
/// Always observed on MainScheduler.
4444
public var executing: Observable<Bool> {
4545
return self._executing.asObservable().observeOn(MainScheduler.instance)
4646
}
47-
private let _executing = Variable(false)
47+
fileprivate let _executing = Variable(false)
4848

4949
/// Observables returned by the workFactory.
5050
/// Useful for sending results back from work being completed
5151
/// e.g. response from a network call.
5252
public var executionObservables: Observable<Observable<Element>> {
5353
return self._executionObservables.asObservable().observeOn(MainScheduler.instance)
5454
}
55-
private let _executionObservables = PublishSubject<Observable<Element>>()
55+
fileprivate let _executionObservables = PublishSubject<Observable<Element>>()
5656

5757
/// Whether or not we're enabled. Note that this is a *computed* sequence
5858
/// property based on enabledIf initializer and if we're currently executing.
5959
/// Always observed on MainScheduler.
6060
public var enabled: Observable<Bool> {
6161
return _enabled.asObservable().observeOn(MainScheduler.instance)
6262
}
63-
public private(set) var _enabled = BehaviorSubject(value: true)
63+
public fileprivate(set) var _enabled = BehaviorSubject(value: true)
6464

65-
private let executingQueue = dispatch_queue_create("com.ashfurrow.Action.executingQueue", DISPATCH_QUEUE_SERIAL)
66-
private let disposeBag = DisposeBag()
65+
fileprivate let executingQueue = DispatchQueue(label: "com.ashfurrow.Action.executingQueue", attributes: [])
66+
fileprivate let disposeBag = DisposeBag()
6767

68-
public init<B: BooleanType>(enabledIf: Observable<B>, workFactory: WorkFactory) {
69-
self._enabledIf = enabledIf.map { booleanType in
70-
return booleanType.boolValue
71-
}
68+
public init(enabledIf: Observable<Bool> = Observable.just(true), workFactory: @escaping WorkFactory) {
69+
self._enabledIf = enabledIf
70+
7271
self.workFactory = workFactory
7372

7473
Observable.combineLatest(self._enabledIf, self.executing) { (enabled, executing) -> Bool in
7574
return enabled && !executing
7675
}.bindTo(_enabled).addDisposableTo(disposeBag)
7776

78-
self.inputs
79-
.subscribeNext { [weak self] input in
80-
self?._execute(input)
81-
}
82-
.addDisposableTo(disposeBag)
77+
self.inputs.subscribe(onNext: { [weak self] (input) in
78+
self?._execute(input)
79+
}).addDisposableTo(disposeBag)
8380
}
8481
}
8582

86-
// MARK: Convenience initializers.
87-
public extension Action {
88-
89-
/// Always enabled.
90-
public convenience init(workFactory: WorkFactory) {
91-
self.init(enabledIf: .just(true), workFactory: workFactory)
92-
}
93-
}
9483

9584
// MARK: Execution!
9685
public extension Action {
9786

98-
public func execute(input: Input) -> Observable<Element> {
87+
@discardableResult
88+
public func execute(_ input: Input) -> Observable<Element> {
9989
let buffer = ReplaySubject<Element>.createUnbounded()
10090
let error = errors
10191
.flatMap { error -> Observable<Element> in
102-
if case .UnderlyingError(let error) = error {
92+
if case .underlyingError(let error) = error {
10393
throw error
10494
} else {
10595
return Observable.empty()
@@ -118,7 +108,8 @@ public extension Action {
118108
return buffer.asObservable()
119109
}
120110

121-
private func _execute(input: Input) -> Observable<Element> {
111+
@discardableResult
112+
fileprivate func _execute(_ input: Input) -> Observable<Element> {
122113

123114
// Buffer from the work to a replay subject.
124115
let buffer = ReplaySubject<Element>.createUnbounded()
@@ -134,7 +125,7 @@ public extension Action {
134125

135126
// Make sure we started executing and we're accidentally disabled.
136127
guard startedExecuting else {
137-
let error = ActionError.NotEnabled
128+
let error = ActionError.notEnabled
138129
self._errors.onNext(error)
139130
buffer.onError(error)
140131

@@ -153,7 +144,7 @@ public extension Action {
153144
self?._elements.onNext(element)
154145
},
155146
onError: {[weak self] error in
156-
self?._errors.onNext(ActionError.UnderlyingError(error))
147+
self?._errors.onNext(ActionError.underlyingError(error))
157148
},
158149
onCompleted: {[weak self] in
159150
self?._completed.onNext()
@@ -169,12 +160,12 @@ public extension Action {
169160
}
170161

171162
private extension Action {
172-
private func doLocked(closure: () -> Void) {
173-
dispatch_sync(executingQueue, closure)
163+
func doLocked(_ closure: () -> Void) {
164+
executingQueue.sync(execute: closure)
174165
}
175166
}
176167

177-
internal extension BehaviorSubject where Element: BooleanLiteralConvertible {
168+
internal extension BehaviorSubject where Element: ExpressibleByBooleanLiteral {
178169
var valueOrFalse: Element {
179170
guard let value = try? value() else { return false }
180171

Action.xcodeproj/project.pbxproj

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@
434434
PRODUCT_NAME = "$(TARGET_NAME)";
435435
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
436436
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
437-
SWIFT_VERSION = 2.3;
438437
};
439438
name = Debug;
440439
};
@@ -449,7 +448,6 @@
449448
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
450449
PRODUCT_BUNDLE_IDENTIFIER = "-.Tests";
451450
PRODUCT_NAME = "$(TARGET_NAME)";
452-
SWIFT_VERSION = 2.3;
453451
};
454452
name = Release;
455453
};
@@ -464,7 +462,6 @@
464462
PRODUCT_BUNDLE_IDENTIFIER = "-.Demo";
465463
PRODUCT_NAME = "$(TARGET_NAME)";
466464
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
467-
SWIFT_VERSION = 2.3;
468465
};
469466
name = Debug;
470467
};
@@ -478,7 +475,6 @@
478475
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
479476
PRODUCT_BUNDLE_IDENTIFIER = "-.Demo";
480477
PRODUCT_NAME = "$(TARGET_NAME)";
481-
SWIFT_VERSION = 2.3;
482478
};
483479
name = Release;
484480
};
@@ -527,6 +523,7 @@
527523
ONLY_ACTIVE_ARCH = YES;
528524
SDKROOT = iphoneos;
529525
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
526+
SWIFT_VERSION = 3.0;
530527
TARGETED_DEVICE_FAMILY = "1,2";
531528
VERSIONING_SYSTEM = "apple-generic";
532529
VERSION_INFO_PREFIX = "";
@@ -571,6 +568,7 @@
571568
MTL_ENABLE_DEBUG_INFO = NO;
572569
SDKROOT = iphoneos;
573570
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
571+
SWIFT_VERSION = 3.0;
574572
TARGETED_DEVICE_FAMILY = "1,2";
575573
VALIDATE_PRODUCT = YES;
576574
VERSIONING_SYSTEM = "apple-generic";
@@ -595,7 +593,6 @@
595593
PRODUCT_NAME = "$(TARGET_NAME)";
596594
SKIP_INSTALL = YES;
597595
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
598-
SWIFT_VERSION = 2.3;
599596
};
600597
name = Debug;
601598
};
@@ -615,7 +612,6 @@
615612
PRODUCT_BUNDLE_IDENTIFIER = com.ashfurrow.Action;
616613
PRODUCT_NAME = "$(TARGET_NAME)";
617614
SKIP_INSTALL = YES;
618-
SWIFT_VERSION = 2.3;
619615
};
620616
name = Release;
621617
};

AlertAction.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import RxCocoa
44

55
public extension UIAlertAction {
66

7-
public static func Action(title: String?, style: UIAlertActionStyle) -> UIAlertAction {
7+
public static func Action(_ title: String?, style: UIAlertActionStyle) -> UIAlertAction {
88
return UIAlertAction(title: title, style: style, handler: { action in
99
action.rx_action?.execute()
1010
})
@@ -48,17 +48,17 @@ extension UIAlertAction {
4848
MainScheduler.ensureExecutingOnScheduler()
4949

5050
switch event {
51-
case .Next(let value):
52-
self?.enabled = value
53-
case .Error(let error):
51+
case .next(let value):
52+
self?.isEnabled = value
53+
case .error(let error):
5454
let error = "Binding error to UI: \(error)"
5555
#if DEBUG
5656
rxFatalError(error)
5757
#else
5858
print(error)
5959
#endif
6060
break
61-
case .Completed:
61+
case .completed:
6262
break
6363
}
6464
}

Cartfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github "ReactiveX/RxSwift" ~> 2.0
1+
github "ReactiveX/RxSwift" "3.0.0-beta.1"

Cartfile.private

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
github "Quick/Quick" ~> 0.9.3
2-
github "Quick/Nimble" ~> 4.1.0
1+
github "Quick/Quick" "swift-3.0"
2+
github "Quick/Nimble" "master"

Cartfile.resolved

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
github "Quick/Nimble" "v4.1.0"
2-
github "Quick/Quick" "v0.9.3"
3-
github "ReactiveX/RxSwift" "2.6.0"
1+
github "Quick/Nimble" "db706fc1d7130f6ac96c56aaf0e635fa3217fe57"
2+
github "Quick/Quick" "1503fb019d72417d5d6e4fbebdbaa03c9e4a125f"
3+
github "ReactiveX/RxSwift" "3.0.0-beta.1"

Carthage/Checkouts/Nimble

Submodule Nimble updated 129 files

Carthage/Checkouts/Quick

Submodule Quick updated 117 files

Carthage/Checkouts/RxSwift

Submodule RxSwift updated 467 files

Demo/AppDelegate.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1414
var window: UIWindow?
1515

1616

17-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
1818
// Override point for customization after application launch.
1919
return true
2020
}
2121

22-
func applicationWillResignActive(application: UIApplication) {
22+
func applicationWillResignActive(_ application: UIApplication) {
2323
// 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.
2424
// 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.
2525
}
2626

27-
func applicationDidEnterBackground(application: UIApplication) {
27+
func applicationDidEnterBackground(_ application: UIApplication) {
2828
// 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.
2929
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
3030
}
3131

32-
func applicationWillEnterForeground(application: UIApplication) {
32+
func applicationWillEnterForeground(_ application: UIApplication) {
3333
// 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.
3434
}
3535

36-
func applicationDidBecomeActive(application: UIApplication) {
36+
func applicationDidBecomeActive(_ application: UIApplication) {
3737
// 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.
3838
}
3939

40-
func applicationWillTerminate(application: UIApplication) {
40+
func applicationWillTerminate(_ application: UIApplication) {
4141
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
4242
}
4343

0 commit comments

Comments
 (0)