func fetchUser(with id: Int, completion: @escaping ((User) -> Void)) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
let user = User(name: "jewelz")
completion(user)
}
}
func fetchUser(with id: Int) -> Signal {}
fetchUser(with: "12345").subscribe({
})
enum Result {
case success(Value)
case error(Error)
}
final class Signal {
fileprivate typealias Subscriber = (Result) -> Void
fileprivate var subscribers: [Subscriber] = []
func send(_ result: Result) {
for subscriber in subscribers {
subscriber(result)
}
}
func subscribe(_ subscriber: @escaping (Result) -> Void) {
subscribers.append(subscriber)
}
}
let signal = Signal()
signal.subscribe { result in
print(result)
}
signal.send(.success(100))
signal.send(.success(200))
// Print
success(100)
success(200)
static func empty() -> ((Result) -> Void, Signal) {
let signal = Signal()
return (signal.send, signal)
}
fileprivate func send(_ result: Result) { ... }
let (sink, signal) = Signal.empty()
signal.subscribe { result in
print(result)
}
sink(.success(100))
sink(.success(200))
extension UITextField {
var signal: Signal {
let (sink, signal) = Signal.empty()
let observer = KeyValueObserver(object: self, keyPath: #keyPath(text)) { str in
sink(.success(str))
}
signal.objects.append(observer)
return signal
}
}
final class KeyValueObserver: NSObject {
private let object: NSObject
private let keyPath: String
private let callback: (T) -> Void
init(object: NSObject, keyPath: String, callback: @escaping (T) -> Void) {
self.object = object
self.keyPath = keyPath
self.callback = callback
super.init()
object.addObserver(self, forKeyPath: keyPath, options: [.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath, keyPath == self.keyPath, let value = change?[.newKey] as? T else { return }
callback(value)
}
deinit {
object.removeObserver(self, forKeyPath: keyPath)
}
}
class VC {
let textField = UITextField()
var signal: Signal?
func viewDidLoad() {
signal = textField.signal
signal?.subscribe({ result in
print(result)
})
textField.text = "1234567"
}
deinit {
print("Removing vc")
}
}
var vc: VC? = VC()
vc?.viewDidLoad()
vc = nil
// Print
success("1234567")
Removing vc
deinit {
print("Removing Signal")
}
let observer = KeyValueObserver(object: self, keyPath: #keyPath(text)) { str in
sink(.success(str))
}
static func empty() -> ((Result) -> Void, Signal) {
let signal = Signal()
return ({[weak signal] value in signal?.send(value)}, signal)
}
fileprivate typealias Token = UUID fileprivate var subscribers: [Token: Subscriber] = [:]
final class Disposable {
private let dispose: () -> Void
static func create(_ dispose: @escaping () -> Void) -> Disposable {
return Disposable(dispose)
}
init(_ dispose: @escaping () -> Void) {
self.dispose = dispose
}
deinit {
dispose()
}
}
func subscribe(_ subscriber: @escaping (Result) -> Void) -> Disposable {
let token = UUID()
subscribers[token] = subscriber
return Disposable.create {
self.subscribers[token] = nil
}
}
let images = ["1", "2", "3"].map{ UIImage(named: $0) }
func map(_ transform: @escaping (Value) -> T) -> Signal {
let (sink, signal) = Signal.empty()
let dispose = subscribe { (result) in
sink(result.map(transform))
}
signal.objects.append(dispose)
return signal
}
extension Result {
func map(_ transform: @escaping (Value) -> T) -> Result {
switch self {
case .success(let value):
return .success(transform(value))
case .error(let error):
return .error(error)
}
}
}
// Test
let (sink, intSignal) = Signal.empty()
intSignal
.map{ String($0)}
.subscribe { result in
print(result)
}
sink(.success(100))
// Print success("100")
public func map(_ transform: (Wrapped) throws -> U) rethrows -> U? public func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U?
let aString: String? = "¥99.9"
let price = aString.flatMap{ Float($0)}
// Price is nil
func flatMap(_ transform: @escaping (Value) -> Signal) -> Signal {
let (sink, signal) = Signal.empty()
var _dispose: Disposable?
let dispose = subscribe { (result) in
switch result {
case .success(let value):
let new = transform(value)
_dispose = new.subscribe({ _result in
sink(_result)
})
case .error(let error):
sink(.error(error))
}
}
if _dispose != nil {
signal.objects.append(_dispose!)
}
signal.objects.append(dispose)
return signal
}
func users() -> Signal {
let (sink, signal) = Signal.empty()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
let users = Array(1...10).map{ User(id: String(describing: $0)) }
sink(.success(users))
}
return signal
}
func userDetail(with id: String) -> Signal {
let (sink, signal) = Signal.empty()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
sink(.success(User(id: id, name: "jewelz")))
}
return signal
}
let dispose = users()
.flatMap { return self.userDetail(with: $0.first!.id) }
.subscribe { result in
print(result)
}
disposes.append(dispose)
// Print: success(ReactivePrograming.User(name: Optional("jewelz"), id: "1"))
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有