Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxSwiftってどうなってるの?

gaopin
September 20, 2017

 RxSwiftってどうなってるの?

Swift愛好会 vol23

gaopin

September 20, 2017
Tweet

More Decks by gaopin

Other Decks in Technology

Transcript

  1. self.webView?.addObserver(self, forKeyPath:"title", options:.New, context:nil) self.webView?.removeObserver(self, forKeyPath: “title”) override func observeValue(forKeyPath

    keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { switch keyPath! { case "title": if let title = change![NSKeyValueChangeKey.newKey] as? String { self.navigationItem.title = title } default: break } }
  2. public protocol ReactiveCompatible { /// Extended type associatedtype CompatibleType ///

    Reactive extensions. static var rx: Reactive<CompatibleType>.Type { get set } /// Reactive extensions. var rx: Reactive<CompatibleType> { get set } } extension ReactiveCompatible { /// Reactive extensions. public static var rx: Reactive<Self>.Type { get { return Reactive<Self>.self } set { // this enables using Reactive to "mutate" base type } } /// Reactive extensions. public var rx: Reactive<Self> { get { return Reactive(self) } set { // this enables using Reactive to "mutate" base object } } }
  3. public struct Reactive<Base> { /// Base object to extend. public

    let base: Base /// Creates extensions with base object. /// /// - parameter base: Base object. public init(_ base: Base) { self.base = base } }
  4. extension Reactive where Base: WKWebView { /** Reactive wrapper for

    `title` property */ public var title: Observable<String?> { return self.observe(String.self, "title") } /** Reactive wrapper for `loading` property. */ public var loading: Observable<Bool> { return self.observe(Bool.self, "loading") .map { $0 ?? false } } ~தུ~ }
  5. public func observe<E>(_ type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions

    = [.new, .initial], retainSelf: Bool = true) -> Observable<E?> { return KVOObservable(object: base, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable() }
  6. extension ObservableType { /// Default implementation of converting `ObservableType` to

    `Observable`. public func asObservable() -> Observable<E> { // temporary workaround //return Observable.create(subscribe: self.subscribe) return Observable.create { o in return self.subscribe(o) } } }
  7. func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E

    == Element? { let observer = KVOObserver(parent: self) { (value) in if value as? NSNull != nil { observer.on(.next(nil)) return } observer.on(.next(value as? Element)) } return Disposables.create(with: observer.dispose) }
  8. fileprivate final class KVOObserver : _RXKVOObserver , Disposable { typealias

    Callback = (Any?) -> Void var retainSelf: KVOObserver? = nil init(parent: KVOObservableProtocol, callback: @escaping Callback) { #if TRACE_RESOURCES _ = Resources.incrementTotal() #endif super.init(target: parent.target, retainTarget: parent.retainTarget, keyPath: parent.keyPath, options: parent.options, callback: callback) self.retainSelf = self } override func dispose() { super.dispose() self.retainSelf = nil } deinit { #if TRACE_RESOURCES _ = Resources.decrementTotal() #endif } }
  9. -(instancetype)initWithTarget:(id)target retainTarget:(BOOL)retainTarget keyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options callback:(void (^)(id))callback { self = [super

    init]; if (!self) return nil; self.target = target; if (retainTarget) { self.retainedTarget = target; } self.keyPath = keyPath; self.callback = callback; [self.target addObserver:self forKeyPath:self.keyPath options:options context:nil]; return self; } ΍ͬͱKVOͷΦϒβʔϒ
  10. WKWebView ४ڌ ReactiveCompatible Rx: Reactive Reactive title: Observable ۩৅ KVOObservable

    func asObservable() func subscribe() KVOObserver super init() Observableத਎ ࣮ࡍͷ஋؂ࢹ _RXKVOObserver init() func observeValueForKeyPath()