Skip to content

Commit

Permalink
MacOS support for RxSwift subspec. Swift 4 migration.
Browse files Browse the repository at this point in the history
  • Loading branch information
sinarionn committed Nov 30, 2017
1 parent 7d2d164 commit 4761643
Show file tree
Hide file tree
Showing 15 changed files with 501 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2
4.0
6 changes: 3 additions & 3 deletions AppRouter.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Pod::Spec.new do |s|
s.name = "AppRouter"
s.version = "4.0.2"
s.version = "4.1.0"
s.summary = "UIViewController creation, navigation, utility methods for easy routing"

s.homepage = "https://github.com/MLSDev/AppRouter"
Expand All @@ -21,8 +21,8 @@ Pod::Spec.new do |s|
end

s.subspec 'RxSwift' do |rxswift|
rxswift.dependency 'AppRouter/Core'
rxswift.dependency 'RxSwift', '~> 3.0'
s.osx.deployment_target = "10.10"
rxswift.dependency 'RxSwift', '~> 4.0'
rxswift.source_files = 'Sources/RxSwift/*.swift'
end
end
199 changes: 169 additions & 30 deletions AppRouter.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

82 changes: 82 additions & 0 deletions AppRouter.xcodeproj/xcshareddata/xcschemes/AppRouterRx.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0D64FC11FB44E25003B6B89"
BuildableName = "AppRouterRx.framework"
BlueprintName = "AppRouterRx"
ReferencedContainer = "container:AppRouter.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0D64FC11FB44E25003B6B89"
BuildableName = "AppRouterRx.framework"
BlueprintName = "AppRouterRx"
ReferencedContainer = "container:AppRouter.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0D64FC11FB44E25003B6B89"
BuildableName = "AppRouterRx.framework"
BlueprintName = "AppRouterRx"
ReferencedContainer = "container:AppRouter.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file.

## [4.1.0](https://github.com/MLSDev/AppRouter/releases/tag/4.1.0)

Swift 4 migration.
MacOS support for RxSwift subspec
RxSwift subspec does not include Core automatically to allow usage in Cocoa applications.


## [4.0.2](https://github.com/MLSDev/AppRouter/releases/tag/4.0.2)

Swift 3.2 migration.
Expand Down
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "ReactiveX/RxSwift" "rxswift4.0-swift4.0"
github "ReactiveX/RxSwift"
2 changes: 1 addition & 1 deletion Plists/AppRouter.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.0.2</string>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
26 changes: 26 additions & 0 deletions Plists/AppRouterRx.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ Extremely easy way to handle controller creation / presentation / navigation and
## Requirements

- iOS 8.0+
- macOS 10.10+ (RxSwift subspec only)
- Xcode 9+
- Swift 3.2
- Swift 4

## Installation

Expand All @@ -22,9 +23,11 @@ Extremely easy way to handle controller creation / presentation / navigation and
pod 'AppRouter'
```

RxSwift extension for AppRouter with lifeCircle observables:
RxSwift extension for AppRouter with life cycle observables:
**Warrning:** RxSwift subspec does not include `Core` anymore.

```ruby
pod 'AppRouter'
pod 'AppRouter/RxSwift'
```

Expand Down
2 changes: 1 addition & 1 deletion Sources/Core/AppRouter+accessors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ extension UIViewController : ARToppestControllerProvider {
/// ARToppestControllerProvider implementation
///
/// - returns: presentedViewController
open func toppestControllerFromCurrent() -> UIViewController? {
@objc open func toppestControllerFromCurrent() -> UIViewController? {
return self.presentedViewController
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Core/AppRouter+navigations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ extension UINavigationController {
fileprivate func _сoordinator(_ animated: Bool, completion: Func<Void, Void>?) {
if let coordinator = transitionCoordinator , animated {
coordinator.animate(alongsideTransition: nil) { _ in
completion?()
completion?(())
}
} else {
completion?()
completion?(())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,44 @@
// Copyright © 2016 Artem Antihevich. All rights reserved.
//

import Foundation
import UIKit
import RxSwift
#if os(iOS) || os(tvOS)
import UIKit
#if !RX_NO_MODULE
import RxSwift
#endif

public extension Reactive where Base: UIViewController {
/// Observe viewDidLoad calls on current instance
public func onViewDidLoad() -> Observable<Void> {
return ARViewControllerLifeCircleManager.instance.didLoad.filter{ [weak base] in $0 === base }.map{ _ in () }
return ARViewControllerLifeCycleManager.instance.didLoad.filter{ [weak base] in $0 === base }.map{ _ in () }
}

/// Observe viewWillAppear calls on current instance
public func onViewWillAppear() -> Observable<Bool> {
return ARViewControllerLifeCircleManager.instance.willAppear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
return ARViewControllerLifeCycleManager.instance.willAppear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
}

/// Observe viewDidAppear calls on current instance
public func onViewDidAppear() -> Observable<Bool> {
return ARViewControllerLifeCircleManager.instance.didAppear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
return ARViewControllerLifeCycleManager.instance.didAppear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
}

/// Observe viewWillDisappear calls on current instance
public func onViewWillDisappear() -> Observable<Bool> {
return ARViewControllerLifeCircleManager.instance.willDisappear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
return ARViewControllerLifeCycleManager.instance.willDisappear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
}

/// Observe viewDidDisappear calls on current instance
public func onViewDidDisappear() -> Observable<Bool> {
return ARViewControllerLifeCircleManager.instance.didDisappear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
return ARViewControllerLifeCycleManager.instance.didDisappear.filter{ [weak base] in $0.controller === base }.map{ $0.animated }
}
}

public extension Reactive where Base: UIViewController {
/// observe viewDidLoad calls on all instances of current type
public static func onViewDidLoad() -> Observable<Base> {
return Observable.create({ observer -> Disposable in
return ARViewControllerLifeCircleManager.instance.didLoad.subscribe(onNext: { vc in
return ARViewControllerLifeCycleManager.instance.didLoad.subscribe(onNext: { vc in
if let required = vc as? Base {
observer.onNext(required)
}
Expand All @@ -52,7 +54,7 @@ public extension Reactive where Base: UIViewController {
/// observe viewWillAppear calls on all instances of current type
public static func onViewWillAppear() -> Observable<(controller: Base, animated: Bool)> {
return Observable.create({ observer -> Disposable in
return ARViewControllerLifeCircleManager.instance.willAppear.subscribe(onNext: { (vc, animated) in
return ARViewControllerLifeCycleManager.instance.willAppear.subscribe(onNext: { (vc, animated) in
if let required = vc as? Base {
observer.onNext((required, animated))
}
Expand All @@ -63,7 +65,7 @@ public extension Reactive where Base: UIViewController {
/// observe viewDidAppear calls on all instances of current type
public static func onViewDidAppear() -> Observable<(controller: Base, animated: Bool)> {
return Observable.create({ observer -> Disposable in
return ARViewControllerLifeCircleManager.instance.didAppear.subscribe(onNext: { (vc, animated) in
return ARViewControllerLifeCycleManager.instance.didAppear.subscribe(onNext: { (vc, animated) in
if let required = vc as? Base {
observer.onNext((required, animated))
}
Expand All @@ -74,7 +76,7 @@ public extension Reactive where Base: UIViewController {
/// observe viewWillDisappear calls on all instances of current type
public static func onViewWillDisappear() -> Observable<(controller: Base, animated: Bool)> {
return Observable.create({ observer -> Disposable in
return ARViewControllerLifeCircleManager.instance.willDisappear.subscribe(onNext: { (vc, animated) in
return ARViewControllerLifeCycleManager.instance.willDisappear.subscribe(onNext: { (vc, animated) in
if let required = vc as? Base {
observer.onNext((required, animated))
}
Expand All @@ -85,7 +87,7 @@ public extension Reactive where Base: UIViewController {
/// observe viewDidDisappear calls on all instances of current type
public static func onViewDidDisappear() -> Observable<(controller: Base, animated: Bool)> {
return Observable.create({ observer -> Disposable in
return ARViewControllerLifeCircleManager.instance.didDisappear.subscribe(onNext: { (vc, animated) in
return ARViewControllerLifeCycleManager.instance.didDisappear.subscribe(onNext: { (vc, animated) in
if let required = vc as? Base {
observer.onNext((required, animated))
}
Expand All @@ -94,17 +96,17 @@ public extension Reactive where Base: UIViewController {
}
}

private class ARViewControllerLifeCircleManager {
private class ARViewControllerLifeCycleManager {
private static var __once: () = {
swapMethods(#selector(UIViewController.viewDidLoad), swizzled: #selector(UIViewController.ar_viewDidLoad))
swapMethods(#selector(UIViewController.viewWillAppear(_:)), swizzled: #selector(UIViewController.ar_viewWillAppear(_:)))
swapMethods(#selector(UIViewController.viewDidAppear(_:)), swizzled: #selector(UIViewController.ar_viewDidAppear(_:)))
swapMethods(#selector(UIViewController.viewWillDisappear(_:)), swizzled: #selector(UIViewController.ar_viewWillDisappear(_:)))
swapMethods(#selector(UIViewController.viewDidDisappear(_:)), swizzled: #selector(UIViewController.ar_viewDidDisappear(_:)))
}()
static let instance : ARViewControllerLifeCircleManager = {
static let instance : ARViewControllerLifeCycleManager = {
_ = __once
return ARViewControllerLifeCircleManager()
return ARViewControllerLifeCycleManager()
}()
fileprivate let didLoad = PublishSubject<UIViewController>()
fileprivate let willAppear = PublishSubject<(controller: UIViewController,animated: Bool)>()
Expand All @@ -113,8 +115,8 @@ private class ARViewControllerLifeCircleManager {
fileprivate let didDisappear = PublishSubject<(controller: UIViewController,animated: Bool)>()

fileprivate class func swapMethods(_ original: Selector, swizzled: Selector) {
let originalMethod = class_getInstanceMethod(UIViewController.self, original)
let swizzledMethod = class_getInstanceMethod(UIViewController.self, swizzled)
guard let originalMethod = class_getInstanceMethod(UIViewController.self, original),
let swizzledMethod = class_getInstanceMethod(UIViewController.self, swizzled) else { return }
let didAddMethod = class_addMethod(UIViewController.self, original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod { class_replaceMethod(UIViewController.self, swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) }
else { method_exchangeImplementations(originalMethod, swizzledMethod) }
Expand All @@ -124,22 +126,24 @@ private class ARViewControllerLifeCircleManager {
extension UIViewController {
@objc fileprivate func ar_viewDidLoad() -> () {
self.ar_viewDidLoad()
ARViewControllerLifeCircleManager.instance.didLoad.onNext(self)
ARViewControllerLifeCycleManager.instance.didLoad.onNext(self)
}
@objc fileprivate func ar_viewWillAppear(_ animated: Bool) -> () {
self.ar_viewWillAppear(animated)
ARViewControllerLifeCircleManager.instance.willAppear.onNext((self, animated))
ARViewControllerLifeCycleManager.instance.willAppear.onNext((self, animated))
}
@objc fileprivate func ar_viewDidAppear(_ animated: Bool) -> () {
self.ar_viewDidAppear(animated)
ARViewControllerLifeCircleManager.instance.didAppear.onNext((self, animated: animated))
ARViewControllerLifeCycleManager.instance.didAppear.onNext((self, animated: animated))
}
@objc fileprivate func ar_viewWillDisappear(_ animated: Bool) -> () {
self.ar_viewWillDisappear(animated)
ARViewControllerLifeCircleManager.instance.willDisappear.onNext((self, animated: animated))
ARViewControllerLifeCycleManager.instance.willDisappear.onNext((self, animated: animated))
}
@objc fileprivate func ar_viewDidDisappear(_ animated: Bool) -> () {
self.ar_viewDidDisappear(animated)
ARViewControllerLifeCircleManager.instance.didDisappear.onNext((self, animated: animated))
ARViewControllerLifeCycleManager.instance.didDisappear.onNext((self, animated: animated))
}
}

#endif
Loading

0 comments on commit 4761643

Please sign in to comment.