iOS/Rx

[ iOS/Rx ] 1. RxSwift๋ž€?

Forest Yun 2023. 6. 27. 19:23
728x90

 

 

๐Ÿงš๐Ÿป‍โ™€๏ธ์š”์•ฝ๐Ÿงš๐Ÿป‍โ™€๏ธ

Rx๋Š” Observable<T> ํ˜•ํƒœ๋กœ ํ‘œํ˜„๋˜๋Š” ๋น„๋™๊ธฐ์  ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์‚ฌ์šฉํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‹ค. ๊ทธ๊ฒƒ์ด ๊ธฐ๋ฐ˜์ด ๋˜์–ด Swift ์ „์šฉ์œผ๋กœ ๊ตฌํ˜„๋œ ๊ฒƒ์ด ๋ฐ”๋กœ RxSwift์ด๋‹ค. Rx๋Š” ๋น„๋™๊ธฐ์  ์ž‘์—…๊ณผ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ๊ตฌ์„ฑ์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด์ž ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๋˜์–ด์žˆ๋‹ค. ์ „๋‹ฌ๋˜๋Š” ์ด๋ฒคํŠธ์— ๋ฐ”๋กœ ๋ฐ˜์‘ํ•˜์—ฌ ์ž‘์—…์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

Reactive ๊ตฌ์„ฑ ์š”์†Œ๋กœ๋Š” Observable(๊ด€์ฐฐ๋Œ€์ƒ), Operator(์—ฐ์‚ฐ์ž), Observer(๊ด€์ฐฐ์ž)๊ฐ€ ์žˆ์œผ๋ฉฐ, ๊ด€์ฐฐ์ž๊ฐ€ ๊ด€์ฐฐ๋Œ€์ƒ์„ ๊ตฌ๋…(Subscribe)ํ•ด์•ผ๋งŒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ ํ๋ฆ„๋“ค์ด ์ด๋ฒคํŠธ์— ๋‹ด๊ฒจ Observable์—์„œ ์‹œ์ž‘ํ•ด Operator์„ ๊ฑฐ์ณ Observer์—๊ฒŒ ๋„๋‹ฌํ•œ๋‹ค.

 

 

 


 

 

 

 

๋น„๋™๊ธฐ ์ž‘์—…

Rx์— ๋Œ€ํ•ด ์•Œ๊ธฐ ์ „ ๋น„๋™๊ธฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ๊ณ  ๊ฐ€์•ผํ•œ๋‹ค. ๋น„๋™๊ธฐ๋ž€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ผ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ์˜ˆ๋ฅผ ๋“ค์–ด ์ธ์Šคํƒ€๊ทธ๋žจ ํ”„๋กœํ•„์„ ๋กœ๋“œํ•  ๋•Œ ๋ฉ”์ธ์—์„œ๋Š” UI๋ฅผ ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ์ด๋ ‡๊ฒŒ ์•ž์œผ๋กœ๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ๋’ค์—์„œ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

 

[ iOS ] ๋™๊ธฐ์™€ ๋น„๋™๊ธฐ / ์ง๋ ฌ๊ณผ ๋™์‹œ์„ฑ

๊ณต๋ถ€ ๋ฐฐ๊ฒฝ RxSwift๋ฅผ ๊ณต๋ถ€ํ•˜๋ ค ํ•˜๋Š”๋ฐ ๊ทธ์ „์— ๋จผ์ € ๋น„๋™๊ธฐ์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์•˜๋‹ค. ๋™๊ธฐ์™€ ๋น„๋™๊ธฐ๋ฅผ ๋ฐฐ์› ์ง€๋งŒ ์ œ๋Œ€๋กœ ์•„๋Š” ๊ฒƒ ๊ฐ™์ง€ ์•Š์•„ ์ด๋ฒˆ ๊ธฐํšŒ์— ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ , ํ•จ๊ป˜ ์ง๋ ฌ๊ณผ ๋™์‹œ

88yhtserof.tistory.com

 

 

 

Reactive Programming์ด๋ž€?

Reactive Programming์„ ํ•œ๊ตญ์–ด๋กœ ํ•˜๋ฉด ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ, ๋น„๋™๊ธฐ์ ์ธ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์‚ฌ์šฉํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ๋น„๋™๊ธฐ์ ์ธ ๋ฐ์ดํ„ฐ ํ๋ฆ„์œผ๋กœ ๋ณด๋ฉฐ *Observer ๋””์ž์ธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ ์ธ ์ด๋ฒคํŠธ๋“ค์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์ด๋ฒคํŠธ์— ๋ฐ”๋กœ ๋ฐ˜์‘ํ•œ๋‹ค. ํ…์ŠคํŠธ ํ•„๋“œ์— ๊ฐ’์„ ์ž…๋ ฅํ•˜๋ฉด ์ด ํ…์ŠคํŠธ ํ•„๋“œ์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ž‘์—…์œผ๋กœ ์ž…๋ ฅ๊ฐ’์ด ๋ฐ”๋กœ ์ „๋‹ฌ๋œ๋‹ค. ์ฆ‰ Reactive Programming์€ Data Binding์„ ํ†ตํ•ด View์™€ Model์ด ๋ฐ”๋กœ๋ฐ”๋กœ ์„œ๋กœ ์ƒํ™ฉ์„ ๊ณต์œ ํ•˜๋ฉฐ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

 

*Observer ๋””์ž์ธ ํŒจํ„ด:

๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜๋Š” ์˜ต์ ธ๋ฒ„๋ฅผ ๊ฐ์ฒด์— ๋“ฑ๋กํ•˜์—ฌ ์ƒํƒœ ๋ณ€ํ™” ๋ฐœ์ƒ ์‹œ ๊ฐ์ฒด๊ฐ€ ์ง์ ‘ ์˜ต์ ธ๋ฒ„์— ์•Œ๋ฆฌ๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

 

 

RxSwift

ReactiveX๋Š” Observable<Element> ์ธํ„ฐํŽ˜์ด์Šค๋กœ ํ‘œํ˜„๋˜๋Š” ๊ณ„์‚ฐ์˜ ์ผ๋ฐ˜์ ์ธ ์ถ”์ƒํ™”๋กœ, Observable ์ŠคํŠธ๋ฆผ์˜ ๊ฐ’๊ณผ ๊ธฐํƒ€ ์ด๋ฒคํŠธ๋“ค์„ ๋ฐฉ์†กํ•˜๊ณ (broadcaste)ํ•˜๊ณ  ๊ตฌ๋…(๊ด€์ฐฐ)ํ•  ์ˆ˜ ์žˆ๋‹ค. RxSwift๋Š” ์ด๋Ÿฌํ•œ Rx์˜ Extension ํ‘œ์ค€์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ Swift ์ „์šฉ ๊ตฌํ˜„์ด๋‹ค.

RxSwift์˜ ์˜๋„๋Š” Observable ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…๊ณผ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค. ๋”ฐ๋ผ์„œ  ์ด๋Ÿฐ ๋น„๋™๊ธฐ ์ž‘์—…๋“ค์„ ๋ณ€ํ™˜ํ•˜๊ณ  ๊ตฌ์„ฑํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.

Apple์—์„œ๋Š” ํ•จ์ˆ˜, Closure, Notification ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค. RxSwift๋Š” KVO ๊ด€์ฐฐ, ๋น„๋™๊ธฐ ๊ด€์ฐฐ, UI ์ด๋ฒคํŠธ, ๊ธฐํƒ€ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์‹œํ€€์Šค(Observable)์˜ ์ถ”์ƒํ™”๋กœ ํ†ตํ•ฉํ•œ๋‹ค. ์ฆ‰, ํ•œ๊ฐ€์ง€๋งŒ์œผ๋กœ๋„ ํ˜ธ์ถœ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์กŒ๋‹ค

 

 

 

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

Rx๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๊ธฐ๋„ ํ•˜๋‹ค ๋‘”๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ฌด์—‡์ธ์ง€ ์ž˜ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ฝ”๋”ฉ ์ค‘ ์˜ค๋ฅ˜์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋Š” ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ์ง€์–‘ํ•˜๊ณ  ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•ด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋˜์–ด ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜ ์ฝ”๋“œ๋Š” '์ˆซ์ž๋“ค ์ค‘ ์ง์ˆ˜๋งŒ ๊ณจ๋ผ ๋’ค์— ๋Š๋‚Œํ‘œ๋ฅผ ๋ถ™์ธ ๊ฒƒ์ด๋‹ค'๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ด์ฒ˜๋Ÿผ ์„ ์–ธํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ๋„๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‹ค. ๋ณดํ†ต ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณด๋‹ค๋Š” .filter, .map ๋“ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•œ๋‹ค.

//'์ˆซ์ž๋“ค ์ค‘ ์ง์ˆ˜๋งŒ ๊ณจ๋ผ ๋’ค์— ๋Š๋‚Œํ‘œ๋ฅผ ๋ถ™์ธ ๊ฒƒ์ด๋‹ค'

Observable<Int>.of(1, 2, 3)
    .filter { $0%2 == 0 }
    .map { number in
        number.description + "!"
    }

// 2!

 

 

 

โญ๏ธ Reactive ๊ตฌ์„ฑ

Reactive๋Š” ์„ธ ๊ฐ€์ง€ ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ์žˆ๋‹ค. Observable, Operator, Observer

Observable์˜ ์‚ฌ์ „์  ์ •์˜๋Š” '๊ด€์ฐฐ๋  ์ˆ˜ ์žˆ๋Š”'์ด๋‹ค. ์ฆ‰, ๊ด€์ฐฐ ๋Œ€์ƒ์ด๋‹ค. ์˜ต์ ธ๋ฒ„๋ธ” ์•ˆ์—๋Š” ์—ฐ์†์ ์œผ๋กœ ๋ฐœํ–‰๋˜์–ด ๋‚˜์˜ค๋Š” ๊ฐ’๋“ค์ด ์žˆ๋Š”๋ฐ, ์ด๊ฒƒ๋“ค์€ ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด๋‹ค. ์ด ํ๋ฆ„๋“ค์€ ์ˆœ์ˆ˜ํ•จ์ˆ˜์ธ Operator์„ ๊ฑฐ์ณ ์—ฐ์‚ฐ๋œ๋‹ค. ์—ฐ์‚ฐ๋œ ๋ฐ์ดํ„ฐ๋“ค์€ ์ด๋ฒคํŠธ์— ๋‹ด๊ฒจ ์ „๋‹ฌ๋œ๋‹ค.  ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ๊ณ„์† ์ง€์ผœ๋ณด๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๊ด€์ฐฐ์ž Observer์ด๋‹ค. ์˜ต์ ธ๋ฒ„๋Š” ์ง€์ผœ๋ณด๊ธฐ ์ „ ์˜ต์ ธ๋ฒ„๋ธ”์„ ๊ตฌ๋…(subscribe)ํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋ฐ›์€ ์ด๋ฒคํŠธ ์† ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด ์˜ต์ ธ๋ฒ„ ๋งˆ์Œ๋Œ€๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์ž‘์—…์ด ๋ฐ”๋กœ subscribe ๋ธ”๋ก ์•ˆ์— ์ ํ˜€ ์žˆ๋‹ค.

Observable<Int>.of(1, 2, 3)
    .filter { $0%2 == 0 }
    .map { number in
        number.description + "!"
    }
    .subscribe{ value in
        print(value)
    }

//์ถœ๋ ฅ
>> next(2!)
>> completed

+ Observable = Sequence

์‹œํ€€์Šค๋ž€ ์š”์†Œ๋“ค์„ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์œผ๋กœ, ์˜ต์ ธ๋ฒ„๋ธ”์€ ์ผ๋ จ์˜ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œํ€€์Šค๋ผ ๋ถˆ๋ฆฐ๋‹ค.

 

 

 

์ด๋ฒคํŠธ ์œ ํ˜• 3๊ฐ€์ง€

์ด๋ฒคํŠธ ์œ ํ˜•  
Next(Element) ์‹œํ€€์Šค์˜ ๋ฐ์ดํ„ฐ ์š”์†Œ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
Error(Swift.Error) ์˜ต์ ธ๋ฒ„๋ธ”์ด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ์ถ”๊ฐ€์ ์ธ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.
Completed ์ผ๋ จ์˜ ์ด๋ฒคํŠธ๋“ค์„ ๋ชจ๋‘ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฉ์ถœํ–ˆ๋‹ค.
์ฆ‰, ์˜ต์ ธ๋ฒ„๋ธ”์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ž์‹ ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•ด์„œ ๋”์ด์ƒ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

 

 

Observable์˜ ์ƒ๋ช…์ฃผ๊ธฐ

๋„คํŠธ์›Œํฌ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ์™€ ๊ฐ™์ด ์œ ํ•œํ•œ ์‹œํ€€์Šค์˜ ๊ฒฝ์šฐ๋„ ์žˆ๊ณ , ๊ฐ€๋กœ๋ชจ๋“œ-์„ธ๋กœ๋ชจ๋“œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ ธ์•ผ ํ•˜๋Š” UI์™€ ๊ฐ™์ด ๋ฌดํ•œํ•œ ์‹œํ€€์Šค๋„ ์žˆ๋‹ค. ๊ฐ€๋กœ ๋ชจ๋“œ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ํ•ด๋„ ๋˜ ๋‹ค์‹œ ์„ธ๋กœ ๋ชจ๋“œ๋กœ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ทธ์ € ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ UI์˜ ์˜ต์ ธ๋ฒ„๋ธ”์€ ์ ˆ๋Œ€ ๋๋‚˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Error ๋˜๋Š” Completed ์ด๋ฒคํŠธ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

 

 

 

Scheduler

์Šค์ผ€์ค„๋Ÿฌ๋Š” Rx์—์„œ์˜ DispatchQueue๋กœ, ๋” ๊ฐ•๋ ฅํ•˜๊ณ  ์‚ฌ์šฉ์ด ์‰ฝ๋‹ค. RxSwift์—๋Š” ๋งŽ์€ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ๋”ฐ๋กœ ์ƒ์„ฑํ•  ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค.

 

 

 


 

 

 

Reactive Programming
RxSwift Github
โญ๏ธ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๋ญ”๊ฐ€์š”?
ํŒจ์ŠคํŠธ์บ ํผ์Šค ๊ฐ•์˜ - 30๊ฐœ ํ”„๋กœ์ ํŠธ๋กœ ๋ฐฐ์šฐ๋Š” iOS ์•ฑ ๊ฐœ๋ฐœ
728x90

'iOS > Rx' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[ Rx ] ๊ฒฐํ•ฉ ์—ฐ์‚ฐ - 1. withLatestFrom  (1) 2023.10.06