Last active
September 20, 2018 14:21
-
-
Save mono0926/bee85426e199b9eef23692c5050bebae to your computer and use it in GitHub Desktop.
Protocol OrientedなRxSwift化したUIAlertController
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import RxSwift | |
private func getAllEnumValues<T: Hashable>(_: T.Type) -> [T] { | |
var i = 0 | |
let iterator = AnyIterator<T> { | |
let next = withUnsafeBytes(of: &i) { $0.load(as: T.self) } | |
if next.hashValue != i { return nil } | |
i += 1 | |
return next | |
} | |
return Array(iterator) | |
} | |
public protocol AlertActionType: Hashable { | |
var style: UIAlertActionStyle { get } | |
static var values: [Self] { get } | |
} | |
extension AlertActionType { | |
public static var values: [Self] { return getAllEnumValues(Self.self) } | |
} | |
public protocol AlertAction { | |
associatedtype AType: AlertActionType | |
func titie(for type: AType) -> String | |
} | |
public struct Alert { | |
private init() {} | |
public struct OkAction: AlertAction { | |
public let okTitle: String | |
init(okTitle: String = okString) { | |
self.okTitle = okTitle | |
} | |
public func titie(for type: ActionType) -> String { | |
switch type { | |
case .ok: return okTitle | |
} | |
} | |
public enum ActionType: String, AlertActionType { | |
case ok | |
public var style: UIAlertActionStyle { | |
switch self { | |
case .ok: return .default | |
} | |
} | |
} | |
} | |
public struct OkCancelAction: AlertAction { | |
public let okTitle: String | |
public let cancelTitle: String | |
init(okTitle: String = okString, cancelTitle: String = cancelString) { | |
self.okTitle = okTitle | |
self.cancelTitle = cancelTitle | |
} | |
public func titie(for type: ActionType) -> String { | |
switch type { | |
case .ok: return okTitle | |
case .cancel: return cancelTitle | |
} | |
} | |
public enum ActionType: String, AlertActionType { | |
case | |
ok, | |
cancel | |
public var style: UIAlertActionStyle { | |
switch self { | |
case .ok: return .default | |
case .cancel: return .cancel | |
} | |
} | |
} | |
} | |
} | |
extension UIViewController { | |
public func prompt<Action: AlertAction>(title: String?, message: String?, action: Action) -> Observable<Action.AType> { | |
return Observable.create { observer in | |
let alertView = UIAlertController(title: title, message: message, preferredStyle: .alert) | |
for type in Action.AType.values { | |
alertView.addAction(UIAlertAction(title: action.titie(for: type), style: type.style) { _ in | |
observer.on(.next(type)) | |
}) | |
} | |
self.present(alertView, animated: true, completion: nil) | |
return Disposables.create { | |
alertView.dismiss(animated:false, completion: nil) | |
} | |
} | |
} | |
public func prompt(title: String?, message: String?, okTitle: String = okString, didTap: (() -> ())? = {}) { | |
prompt(title: title, message: message, action: Alert.OkAction(okTitle: okTitle)) | |
.subscribeOnMainThread { event in | |
switch event { | |
case .completed: didTap?() | |
case .error: joinusAssert(false) | |
case .next:break | |
} | |
}.disposed(by: rx_disposeBag) | |
} | |
public func promptWithCancel(title: String?, | |
message: String?, | |
okTitle: String = okString, | |
cancelTitle: String = cancelString, | |
didTap: (() -> ())? = {}) { | |
prompt(title: title, | |
message: message, | |
action: Alert.OkCancelAction(okTitle: okTitle, cancelTitle: cancelTitle)) | |
.subscribeOnMainThread { event in | |
switch event { | |
case .completed: break | |
case .error: joinusAssert(false) | |
case .next(let action): | |
switch action { | |
case .ok: | |
didTap?() | |
case .cancel: | |
break | |
} | |
} | |
}.disposed(by: rx_disposeBag) | |
} | |
public func prompt(error message: String?, didTap: (() -> ())? = {}) { | |
prompt(title: errorOccuredString, message: message) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
色々ダメだ( ´・‿・`)