Reactivecocoa: Swift 3์—์„œ `rac_` ์ ‘๋‘์‚ฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋‚˜์š”?

์— ๋งŒ๋“  2016๋…„ 07์›” 10์ผ  ยท  15์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: ReactiveCocoa/ReactiveCocoa

Swift API ์ง€์นจ์€ ์†Œ๋ฌธ์ž ๊ทœ์•ฝ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ Swift ์ฝ”๋“œ๋ฒ ์ด์Šค์—๋Š” NotificationCenter.rac_notifications(forName:object:) ๋ฐ URLSession.rac_data(with:) ๋‘ ๊ฐ€์ง€ ์˜ˆ์™ธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ IIRC์—์„œ Rex๋ฅผ Cocoa Bindings repo์˜ ์ผ๋ถ€๋กœ ๋ณ‘ํ•ฉํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ rex_ ์ ‘๋‘์‚ฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์•ผ ํ• ๊นŒ์š”, ์•„๋‹ˆ๋ฉด ๊ทธ๋Œ€๋กœ ๋†”๋‘ฌ์•ผ ํ• ๊นŒ์š”?

์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์žˆ๋Š” ๋‘ ๊ฐœ์˜ ํ™•์žฅ์— ๋Œ€ํ•ด ๊ฐ€์žฅ ๋…์ฐฝ์ ์ด์ง€ ์•Š์€ ์ด๋ฆ„์€ ์•„๋งˆ๋„ makeProducer ์ž…๋‹ˆ๋‹ค.

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์€ "make"๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค(egxmakeIterator()).

ํŽธ์ง‘: ๋‘ ๋ฒˆ์งธ ์ƒ๊ฐ ํ›„, ์ƒ์‚ฐ์ž์˜ ๊ฒฝ์šฐ ์‹œ์ž‘๋  ๋•Œ๊นŒ์ง€ ๋ถ€์ž‘์šฉ์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ „๋‹ฌํ•  ๋‚ด์šฉ์„ ์„ค๋ช…ํ•˜๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ์ด๋ฆ„์€ ์ ์ ˆํ•œ IMO๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์˜ˆ: notifications(forName:object:) .

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

SnapKit์œผ๋กœ ์ˆ˜ํ–‰ํ•œ ์ž‘์—… ์ค‘ ํ•˜๋‚˜๋Š” ํ™•์žฅ์„ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. RAC API๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

struct UIButtonRACDSL {
    var pressed: Signal<UIButton, NoError>
    init(button: UIButton) { }
}

extension UIButton {
    var rac: UIButtonRACDSL { return UIButtonRACDSL(button: self) }
}

์ด ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ด๋™ํ•˜๋ฉด ์•ฝ๊ฐ„์˜ ์œ ์—ฐ์„ฑ์ด ์ œ๊ณต๋˜๊ณ  ํ™•์žฅ์˜ ์ถฉ๋Œ ๋ฒ”์œ„๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

๋ชจ๋“  15 ๋Œ“๊ธ€

์ ์–ด๋„ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์œ ํ˜•์ด ์ด๋ฆ„์„ ๋ชจํ˜ธํ•˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ ‘๋‘์‚ฌ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋“ค์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚œ ์šธํƒ€๋ฆฌ์—์žˆ์–ด.

์œ ์ง€ํ•œ๋‹ค๋ฉด ์—ฌ๊ธฐ์— rac_ ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ (Rex์˜ ์ฝ”๋“œ ํฌํ•จ) ReactiveSwift์— ๋Œ€ํ•œ ์ƒˆ ์ ‘๋‘์‚ฌ๋ฅผ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ”์ธ๋”ฉ์˜ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ญ์ œํ•˜๋ฉด ์ €์žฅ๋œ ์†์„ฑ๊ณผ ์ด๋ฆ„ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ด์— ๋Œ€ํ•œ ๋Œ€์•ˆ์€ ๋ชจ๋“  ์†์„ฑ์„ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ํ”„๋ก์‹œ๋ฅผ ๋„์ž…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ

view.bindables.text <~ property

// `view.bindables` is of type `Bindings<UIView>`, which conforms to `BindingsProtocol`
// that requires an associated type `Owner`.
//
// `view.bindables.text` is provided by the extension to `BindingsProtocol` for all
//`Owner` inherited from `UIView`.

(๋˜๋Š” ๊ทธ๋ƒฅ rac ? ๊ทธ๋Ÿฌ๋‚˜ ReactiveSwift์™€ ReactiveCocoa ๋ชจ๋‘ ์ผ์ข…์˜ ๋ฐ”์ธ๋”ฉ์„ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.)

... ์•„๋‹ˆ๋ฉด view.textProxy , view.reactiveText ๋˜๋Š” ๋ฌด์—‡์ด๋“  ์ด๋ฆ„์„ ์ง€์ •ํ•˜์‹ญ์‹œ์˜ค.

ํŽธ์ง‘: ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ž…์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค(https://github.com/RACCommunity/Rex/pull/143).

ํŽธ์ง‘ 2: ์—‰๋ง์ง„์ฐฝ์„ ์ž ์‹œ ์ •๋ฆฌํ•˜์‹ญ์‹œ์˜ค. :NS

ReactiveCocoa 5+๋Š” Rex์™€ ํ˜ธํ™˜๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. RAC๋Š” ๋ ‰์Šค๋ฅผ ์ธ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก , ๋‚˜๋Š” ๋‹จ์ง€ Rex๊ฐ€ ๊ฐ€์ ธ์˜จ ๋ฐ”์ธ๋”ฉ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ์—‰๋ง์œผ๋กœ ์ฝํ˜”๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜ธ

outlets ๋„ ๊ฒฝ์Ÿ์ž๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

"reactive"๋Š” ์‹ ์†ํ•œ ์–ธ์–ด๋กœ ๋” ๋‚˜์€ ์ œํ’ˆ๊ตฐ์ž…๋‹ˆ๋‹ค. "rac_" ๋ฐ "rex_"๋Š” ๋งค์šฐ ์ž˜๋ชป๋œ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. "๋ฐ˜์‘ํ˜•", "ํ™œ์„ฑ" ๋˜๋Š” "์‹ ํ˜ธ"๋กœ ์ด๋™ํ•˜์—ฌ view.reactiveText ๋˜๋Š” view.activeText ๋˜๋Š” view.signalText๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Swift์™€ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์ด์ƒ ๋Ÿฐํƒ€์ž„ ์ถฉ๋Œ์˜ ์œ„ํ—˜์ด ์—†์œผ๋ฏ€๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๊ทธ๋ƒฅ ๋ฒ„๋ฆฌ์ž! :NS

๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์†์„ฑ์„ ์˜ค๋ฒ„๋กœ๋“œํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์†์„ฑ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜•

bindable ํ”„๋ก์‹œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: view.bindables.something ). %view.something ์™€ ๊ฐ™์€ ๋‹จ์ถ•ํ‚ค๋ฅผ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜•

์ ์–ด๋„ Swift 3.0์—์„œ๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ฑฐ๋‚˜ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฌ๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž๋‚˜ ๋งˆ๋ฒ• ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ œ์•ˆ์€ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์„ ํ•˜๋‚˜์˜ ๊ฐœ์ฒด๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

๋” ์ข‹์€ ์†๊ธฐ ๋Œ€์‹  ์šด์˜์ž ์ถฉ๋Œ์˜ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค ...

๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ์†์„ฑ์— ๋Œ€ํ•œ ์ ‘๋‘์‚ฌ์— ๋ถ™์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

SnapKit์œผ๋กœ ์ˆ˜ํ–‰ํ•œ ์ž‘์—… ์ค‘ ํ•˜๋‚˜๋Š” ํ™•์žฅ์„ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. RAC API๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

struct UIButtonRACDSL {
    var pressed: Signal<UIButton, NoError>
    init(button: UIButton) { }
}

extension UIButton {
    var rac: UIButtonRACDSL { return UIButtonRACDSL(button: self) }
}

์ด ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ด๋™ํ•˜๋ฉด ์•ฝ๊ฐ„์˜ ์œ ์—ฐ์„ฑ์ด ์ œ๊ณต๋˜๊ณ  ํ™•์žฅ์˜ ์ถฉ๋Œ ๋ฒ”์œ„๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

์˜ˆ, ์ด์ „์— ํ”„๋กœํ† ์ฝœ ๊ธฐ๋ฐ˜ ๋ฒ„์ „์œผ๋กœ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ‘์ค„์„ ์ ์œผ๋กœ ๋ฐ”๊พธ๊ณ  ์—ฐ์‚ฐ์ž ์†๊ธฐ๋ฅผ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. rac ๋ฅผ ์†์„ฑ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” IMO๋Š” ์–ด์จŒ๋“  ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ์•ฝ์–ด๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

https://github.com/RACCommunity/Rex/pull/143

rac ์†์„ฑ์ด ํ›จ์”ฌ ๊นจ๋—ํ•ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹คโ€ฆ :heart_eyes:

RxSwift๊ฐ€ ์ทจํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ›”์ณ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

https://github.com/ReactiveX/RxSwift/blob/4952adb27c684b47792923b00015516849061eab/RxCocoa/Common/Reactive.swift
https://github.com/ReactiveX/RxSwift/blob/4952adb27c684b47792923b00015516849061eab/RxCocoa/iOS/UIControl%2BRx.swift

๊ทธ๋“ค์€ ํ™•์žฅํ•˜๋ ค๋Š” ์œ ํ˜•์— ๋Œ€ํ•ด ์ผ๋ฐ˜์ ์ธ Reactive ๊ตฌ์กฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ œํ•œ๋œ ํ™•์žฅ์— ๋Œ€ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ Reactive . ๋ถ„๋ช…ํžˆ ๊ทธ๋“ค์€ ์ด๊ฒƒ์„ Swift์˜ .lazy ๋ชจ๋ธ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ํ›”์น˜๋Š” ๊ฒƒ์ด ์•„๋‹ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

https://github.com/RACCommunity/Rex/pull/143/commits/86f03c3b2d4759c87254a9ea3b28939f23f6be56
๐Ÿ˜œ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰