モバイルメソッド大阪第一回 RxSwift入門資料です。
͍·͞Βฉ͚ͳ͍RxSwiftೖגࣜձࣾ tech veinழມ ॆԝ
View Slide
ࣗݾհגࣜձࣾ tech vein දழມ ॆԝ (͍ͷ·ͨ ΈͭͻΖ)ձࣾHP: https://www.tech-vein.com/private twitter: @ino2222
ެ։தͷAndroid/iOSΞϓϦιϧΞϯϦʔγϡࣗͷΦϦΩϟϥΛ࡞ΔεϚϗ31(IUUQTPVOUFDIWFJODPN IUUQTCJUMZ);BV3$IJJ2ҬͰॿ͚߹͑Δಗ໊૬ஊΞϓϦIUUQTBQQMFDP,[IYDϙέοτΞϒετϥΫτҩྍैࣄऀ͚ͷ࠷৽δϟʔφϧӾཡΞϓϦ
ࠓ͓͢Δ͜ͱ• RxSwiftͱ• RxSwiftͷجຊ• ͜Ε͚֮ͩ͑ͨΒ͑ΔΑ͏ʹͳΔ͔ʁ
ࠓ͓͠ͳ͍͜ͱ(ͬͯΔਓ͚)• Cold -> Hot ม• Reactive Streams(backPressure ͳͲ)
RxSwiftͱ• ֤ݴޠͰ࣮͞Ε͍ͯΔʮRx(Reactive Extension)ʯ ͷSwift͚ϥΠϒϥϦ• Reactive Extension … ͱͱ C#.NET ͰΘΕͩͨ͠ Rx.NET ͕ΦϦδφϧ• Java(RxJava), JavaScript(RxJS), C++(RxCpp),Ruby(Rx.rb), PHP(RxPHP) ͳͲͳͲଟ
ReactiveXͱԿ͔ʁReactiveX = Reactive ExtensionReactive Programming ʹԠతϓϩάϥϛϯάΛ͢ΔͨΊͷExtension = ֦ுReactiveX- σβΠϯύλʔϯͷ Observable ύλʔϯ- σβΠϯύλʔϯͷ Iterator ύλʔϯ- ؔܕϓϩάϥϛϯάΛΈ߹Θͤͯ࡞ΒΕͨϥΠϒϥϦͷ͜ͱ
ObserverύλʔϯσʔλΛࢹ͢Δਓͱ͑ΔΈΛநԽͨ͠σβΠϯύλʔϯ͕͜͜େࣄʂ
Iterator ύλʔϯhttps://ja.wikipedia.org/wiki/Iterator_ύλʔϯҰ࿈ͷσʔλΛॱ൪ʹॲཧ͢ΔσβΠϯύλʔϯ͕͜͜େࣄʂ
ؔܕϓϩάϥϛϯάˠͦΕͧΕͷؔ*/065ʹ͔͠Өڹ͠ͳ͍ ʹ෭࡞༻͕ͳ͍
ͦͯ͠Rx…
͕͜͜خ͍͠RxSwift࣌ܥྻσʔλΛؚΉɺ͋ΒΏΔσʔλΛετϦʔϜͱͯ͠εϚʔτʹॲཧͰ͖ΔɻετϦʔϜͱͯ͠ॱ൪ʹॲཧͰ͖Δ͜ͱͰɺ͍͜͠ඇಉظ੍ޚ͕γϯϓϧʹͳΔɻ→ίʔϧόοΫࠈ͔Βͷղ์நԽʹΑΓૹΓखɾड͚औΓखΛΒͳ͍··ॲཧ͕ग़དྷΔͷͰૄ݁߹ʹͳΔɻ→վมͷӨڹൣғ͕খ͘͞ͳΔ→෦Խɾڞ௨Խ͕ਐΉ֤छετϦʔϜΛѻ͏ศརͳಓ۩͕ἧ͍ͬͯΔɻ→ετϦʔϜͷੜɾมɾ߹Λߦ͏ΦϖϨʔλ܈→ετϦʔϜͷεϨουΓସ͑ػೳ
RxSwiftͷجຊ
RxSwiftͷجຊ͜Ε͚ͩͬͯͨΒRxŧŔŕŪɹɹ ũƄŝſͬͯݴ͑Δ
RxSwiftͷجຊ͜Ε͚ͩͬͯͨΒRxŧŔŕŪ(ŦƄş)ũƄŝſͬͯݴ͑Δ͔ʁ
Observable, Subject,DisposableΩϞʹͳΔͷɺ͜ͷ̏ܥ౷ͷΫϥε(ϓϩτίϧ)ɻΫϥε৭ʑ͋Γ·͕͢ɺ͍͍ͩͨ͜ΕΒͷؒͰ͢ɻ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓObservable, Subject,Disposable
Observable༁͢Δͱɺࢹ͢Δ͜ͱ͕Ͱ͖Δରɻҙͷܕ T ʹ͍ͭͯɺࢹͯ͠σʔλʢΠϕϯτ)Λड͚औΔࣄ͕Ͱ͖ΔΫϥεɾΠϯελϯεͰ͢ɻ࣌ܥྻͰσʔλ͕ObservableʹྲྀΕΔ͜ͱ͔ΒɺObservableετϦʔϜ(Stream)ͱݺͼ·͢ɻ+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓ
“Hello” “Rx” “World”Observablecompleted࣌ؒͷྲྀΕ࣮ߦ݁ՌɿԼͷॱʹग़ྗ͞ΕΔɻOFYU )FMMP OFYU 3Y OFYU 8PSME DPNQMFUFE
Subject؆୯ʹݴ͏ͱɺҙͷσʔλΛྲྀ͢ػೳ(Observerͱͯ͠ͷػೳ)Λ࣋ͬͨObservable࣮ɻRxSwift ͷSubjectPublishSubject, BehaviorSubject, ReplaySubjectͷ̏छྨɻ+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓ
SubjectObserverΛܧঝ͍ͯ͠ΔͷͰObservableͱͯ͠ѻ͑ΔɻSubjectonNext(), onComplete(), onError()ͳͲͷσʔλɾΠϕϯτൃ৴ϝιουΛ࣋ͭɻ
ετϦʔϜͷΠϕϯτ• next σʔλ͕ਖ਼͘͠ྲྀΕ͖ͯͨͱ͍͏ΠϕϯτɻҙͷܕͷσʔλΛҾʹ࣋ͭɻ• error ετϦʔϜத͕Τϥʔ(ྫ֎)Ͱҟৗఀࢭͨ࣌͠ʹྲྀΕΔΠϕϯτɻൃੜͨ͠ΤϥʔΛҾʹ࣋ͭɻ• completed ετϦʔϜ͕ਖ਼ྃͨ࣌͘͠͠ʹൃੜ͢ΔΠϕϯτɻετϦʔϜͷ࠷ޙʹҰ͚ͩൃੜ͢Δɻ ʢೖྗΛͪଓ͚͍ͨͱ͖completedΛྲྀ͞ͳ͍ʣ
ετϦʔϜͷΠϕϯτnext completednext next next nextnext completednext nextετϦʔϜ next ͰσʔλΛྲྀ͠ɺDPNQMFUFEͰऴྃ͢ΔDPNQMFUFE͕དྷͨΒɺͦͷઌOFYUFSSPSྲྀͤͳ͍next next nextFSSPS ྫ֎͕དྷͨΒɺͦͷઌOFYUDPNQMFUFEFSSPSྲྀͤͳ͍error
RxSwift ͷ Subject͍͚ɾPublishSubjectɹաڈͷσʔλΛอ࣋͠ͳ͍Subjectɻɹར༻ྫɿϘλϯͷλοϓΠϕϯτɾBehaviorSubjectɹաڈͷσʔλͷ͏ͪۙͷ̍ͭΛอ͍࣋ͯ͠ΔSubjectɻɹར༻ྫɿεΠονON/OFFঢ়ଶɾϢʔβεςʔλεͳͲɾReplaySubject.create(bufferSize: Int)ɹաڈͷۙσʔλΛࢦఆόοϑΝʹೖΔ͚ͩอ͍࣋ͯ͠ΔSubjectɻɹόοϑΝαΠζ̌ͳΒPublishSubjectͱಉ͡ɻɹόοϑΝαΠζ̍ͳΒBehaviorSubjectͱಉ͡ɻɹར༻ྫɿࢥ͍͔ͭͳ͍…ཤྺܥͰ͑Δ͔ʁ
PublishSubjectPublishSubjectcompleted࣌ؒͷྲྀΕTVCTDSJCF TVCTDSJCF
BehaviorSubjectBehaviorSubjectcompleted࣌ؒͷྲྀΕTVCTDSJCF TVCTDSJCF TVCTDSJCF
ReplaySubjectReplaySubject.create(bufferSize: 2)completed࣌ؒͷྲྀΕTVCTDSJCF TVCTDSJCF TVCTDSJCF
Disposable༁͢ΔͱɺഇغɾॲͰ͖ΔͷɻObservableΛ subscribe(ߪಡ) ͢ΔͱΓͱͯ͠ Disposable Λฦ͠·͢ɻDisposableʹରͯ͠dispose()ΛݺͿ͜ͱͰɺඇಉظॲཧͷΩϟϯηϧͳͲɺࢹ͢Δଆͱͯ͠ॲཧΛࢭΊΔࣄ͕Ͱ͖·͢ɻྫɿը໘Λดͨ͡Β௨৴Ωϟϯηϧͨ͠ΓɺೖྗͪΛࢭΊͨΓ͢Δɻ+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓॲཧͷྲྀΕ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓsubscribe(onNext: … )ॲཧͷྲྀΕ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓsubscribe(onNext: … )ΠϕϯτΛҾͷΫϩʔδϟͰͪड͚ΔPO/FYU lIFMMPzPO/FYU l3YzPO/FYU l8PSMEzʜPO$PNQMFUFE ॲཧͷྲྀΕ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓsubscribe(onNext: … )dispose()ΠϕϯτΛҾͷΫϩʔδϟͰͪड͚ΔॲཧͷྲྀΕ
+ subscribe()Observable+ onNext()+ onError()+ onCompleted()+ subscribe()Subjectܧঝ+ dispose()Disposablesubscribe() ͷΓsubscribe(onNext: … )dispose()ΠϕϯτΛҾͷΫϩʔδϟͰͪड͚ΔॲཧΛࢭΊͨ͘ͳͬͨΒEJTQPTFΛݺͿॲཧͷྲྀΕ
(x, y) (x2, y2) (x3, y3)ྫɿλονΠϕϯτͷࢹ Observable)࣌ؒͷྲྀΕ(x4, y4)TVCTDSJCF EJTQPTF EJTQPTFE(x2, y2) (x3, y3)Disposable.dispose()
DisposeBagdisposeΛ͍͍ͪͪ͢ΔͷΊΜͲ͍͘͞ɻͦΜͳͱ͖DisposeBagɻ
DisposeBagը໘ͳͲɺࢹݩΠϯελϯε͕ࢮΜͩΒࣗಈͰͥΜͿdisposeͯ͠΄͍࣌͠ʹ͑ΔศརΫϥεɻDisposeBagΠϯελϯεʹಥͬࠐΜͰ͓͘ͱɺdisposeBag͕ղ์͞ΕΔ࣌ʹ·ͱΊͯdisposeBagͷதͷdisposableΛdisposeͯ͘͠ΕΔɻˠ3Yඪ४Ͱͳ͍Ͱ͕͢ΊͪΌͪ͘Ό͍·͢ɻɹͱΓ͋͑ͣ%JTQPTF#BH࡞ͬͯ์ΓࠐΜͰ͓͚͍͍ͱࢥ͏ɻ
(x, y) (x2, y2) (x3, y3)ྫɿλονΠϕϯτͷࢹ Observable)࣌ؒͷྲྀΕ(x4, y4)TVCTDSJCF EJTQPTF EJTQPTFE(x2, y2) (x3, y3)EJTQPTFE CZEJTQPTF#BHSubscibe ॲཧDisposeBagJOJU EFJOJU View%JTQPTBCMFΛ%JTQPTF#BHͷதʹೖΕΔɻ%JTQPTF#BHഁغ͞ΕΔͱதͷ%JTQPTBCMFΛEJTQPTF͢Δɻ
IUUQTHJUIVCDPNFDPPQOFUSYTXJGUCFHJOOFSCMPCNBTUFS3Y4XJGU4BNQMF3Y4XJGU4BNQMF6*4BNQMF7JFX$POUSPMMFSTXJGUDisposeBagͷར༻ྫˡ6*7JFX$POUSPMMFSͷϑΟʔϧυʹEJTQPTF#BHΛஔ͍͓ͯ͘ ˠը໘͕ดͨ͡Β6*7JFX$POUSPMMFS͕ࢮ͵ɻˠ6*7JFX$POUSPMMFS͕ࢮΜͩΒ%JTQPTF#BHࢮ͵ɻˠ%JTQPTF#BH͕ࢮΜͩΒඥͮ͘EJTQPTBCMF͕ɹEJTQPTF ͞ΕΔɻ
ΦϖϨʔλ(Operator)Rxʹ Observable, SubjectͰ࡞ͬͨετϦʔϜΛૢ࡞͢Δػೳ͕ఏڙ͞Ε͍ͯ·͢ɻετϦʔϜ(=Observable)Λมɾ߹ɾੜ͢Δૢ࡞ͷ͜ͱΛʮΦϖϨʔλʯͱݺͼ·͢ɻ
ετϦʔϜΛ࡞Δ̍ … Subject Ϋϥε͔Β࡞Δ̎ … from(), of(), just() ͳͲͰҙͷྻɾΛมͯ͠࡞Δ̏ … Observable.create() Ͱҙͷॲཧ͔Β࡞Δ
PublishSubjectcompleted࣌ؒͷྲྀΕTVCTDSJCF TVCTDSJCF
10Observable.just(10)completedσʔλετϦʔϜͷྲྀΕjust( )ετϦʔϜม
“a”Observable.of(“a”, ”b”, ’c”, ”d”, “e”)completedσʔλετϦʔϜͷྲྀΕof( , , , , )ετϦʔϜม“b” “c” “d” “e”
1Observable.from([1, 3, 5, 7, 9])completedσʔλετϦʔϜͷྲྀΕfrom([ , , , , ])ετϦʔϜม3 5 7 9
Observable.error(MyError())σʔλετϦʔϜͷྲྀΕerror( )ετϦʔϜมmyError
1Observable.create(ҙͷॲཧ)completedσʔλετϦʔϜͷྲྀΕcreate(ҙͷॲཧ)ετϦʔϜม3 5 7 9
map: ετϦʔϜΛม͢Δmap(_:((T) -> R)) -> ObservableҙͷܕɾͷετϦʔϜΛՃͯ͠ผͷܕɾͷετϦʔϜʹม͠·͢ɻ
filter: ετϦʔϜΛϑΟϧλ͢Δfilter(_:((T) -> Bool)) -> ObservableྲྀΕ͖ͯͨετϦʔϜΛҾͷؔͰॱ൪ʹॲཧ͠ɺ݁Ռ͕true ʹͳΔσʔλ͚ͩͷετϦʔϜʹม͠·͢ɻ
flatMap: ετϦʔϜΛม͢ΔflatMap(_:((T) -> Observable)) -> ObservableҙͷܕɾͷετϦʔϜΛՃͯ͠ผͷܕɾͷετϦʔϜʹม͠·͢ɻmapͱ΄΅ಉ͡Ͱ͕͢ɺΫϩʔδϟͷฦΓ͕Observableʹͳ͍ͬͯΔ͕ҟͳΓ·͢ɻ
1 completed2 3flatMap({x in Observable.of(x, x*10)})1 completed2 310 20 30completedcompletedcompleted1 completed2 310 20 30
filter, map, flatMap ͷྫ
map ͱ flatMap ͷ͍͚map … ಉظతʹॲཧͰ͖Δσʔλมʹ͍·͢ɻྫɿStringܕ -> URLܕɺInt ܕΛॱ൪ʹܭࢉͯ͠ม͢ΔflatMap … ඇಉظॲཧͳͲɺผͷετϦʔϜΛͬͯม͢Δ࣌ʹ͍·͢ɻྫɿtwitterͷπΠʔτIDετϦʔϜΛflatMapͯ͠ɺॱ൪ʹAPIΛୟ͍ͯ༰Λऔಘͯ͠λΠϜϥΠϯදࣔ͢Δ
map ͱ subscribe ͷ͍͚ʢ؆୯ͳઆ໌ʣͲͪΒͰonNext ʹ͍ͭͯॲཧ͕ग़དྷ·͕͢ɺsubscribe()ܨ͍ͩετϦʔϜΛಈ͔࢝͠ΊΔͱ͍͏େࣄͳׂ͕͋Γ·͢ɻ(ετϦʔϜมͷऴ)subscribe() ετϦʔϜมͰͳ͘ετϦʔϜ࣮ߦʹͳΔͨΊɺObservableͰͳ͘DisposableΛฦ͠·͢ɻ͜ͷͨΊmapͱҧ͍͏͠ΖʹετϦʔϜΛͭͳ͛Δ͜ͱ͕Ͱ͖·ͤΜɻ
1 completedσʔλετϦʔϜͷྲྀΕObservable.from([1, 2, 3, 4, 5])ετϦʔϜม2 3 4 5filter({ x in x % 2 == 1})1 completed3 5map({ x in “v\(x)”)“v1” completed“v3” “v5”TVCTDSJCF “v1” completed“v3” “v5”
ଞʹศརͳΦϖϨʔλ͕ͨ͘͞Μ͋Γ·͢ࢀߟɿhttp://reactivex.io/documentation/operators.htmlhttp://rxmarbles.com/
ศརͳΦϖϨʔλͷҰྫ• zip, merge, combineLatest … ෳͷετϦʔϜΛฒྻʹಈ͔ͯ̍ͭ͠ͷετϦʔϜʹ·ͱΊΔɻ• catchError … Τϥʔ͕ൃੜͨ͠ͱ͖ʹϦΧόϦॲཧΛͯ͠onNext ʹม͢Δɻ࠶ΤϥʔΛ͛Δ(throw)͜ͱͰɺผͷΤϥʔʹม͢Δ͜ͱͰ͖Δ• distinctUntilChanged … ॏෳআ֎ɻετϦʔϜதʹมߋ͕͋ͬͨͱ͖͚ͩ௨͢Δ• throttle, debounce … ࿈ଧࢭʹ͑ΔϑΟϧλɻσʔλΛड͚औͬͨΒҰఆ࣌ؒؒΛ։͚ͳ͍ͱ͕࣍ൃՐ͠ͳͨ͘͠Γ͢Δ• toArray … ྻʹ·ͱΊΔɻcompleted·Ͱͬͯ̍ͭͷྻʹม͢Δ• groupBy … ετϦʔϜͷσʔλΛ͖ͳ݅ͰάϧʔϓԽ͢Δ
Try Rx!
RxSwift/RxCocoa ͷΠϯετʔϧᶃ CocoaPods → Podfile:ᶄ pod installᶅ .swift ϑΝΠϧͰimport※Carthage / Swift Package Manager ʹରԠͯ͠·͢ɻhttps://github.com/ReactiveX/RxSwift3Y$PDPBʹ͍ͭͯޙड़·ͨ
Hello, Rx worldˠ
Hello, Rx world2ˠ
Hello, Rx world3ˣ
RxCocoa ʹ͍ͭͯRxSwift ͷαϒηοτతͳϥΠϒϥϦͰ͢ɻRxSwift ͕७ਮͳ Rx ࣮ͰɺRxCocoa iOS/Mac։ൃʹศརͳଐΫϥεɾ֦ுΛఏڙ͍ͯ͠·͢ɻRxCocoa Λ͏ʹ RxSwift ͱผʹϥΠϒϥϦΠϯετʔϧ͕ඞཁʹͳΓ·͢ɻ> pod ‘RxCocoa'Ͱ pod install ͯ͠ɺswiftίʔυͰ import RxCocoa Λॻ͍͓ͯ͘ͱ͑·͢ɻ
RxCocoa ͕ఏڙ͢Δػೳͷྫ
UIKit ఏڙΫϥεͷ rx ԽUIView, URLSession ͳͲUIKit,͕ఏڙ͢ΔΫϥεͷϓϩύςΟɾΠϕϯτΛrxԽͯ͠ɺObservableΠϯελϯεͱͷ૬ޓόΠϯυΛՄೳʹ͢Δɻྫɿ- ࣈΛςΩετೖྗͨ͠Βϥϕϧʹܭࢉ݁ՌΛදࣔ͢Δɻ- ϘλϯΛԡͨ͠ΒAPI௨৴ͯ͠ɺAPI࣮ߦ݁ՌΛϥϕϧʹදࣔ͢Δɻ- URLSession ͷAPI௨৴݁ՌJSONΛܗͯ͠ϓϩϑΟʔϧը໘ʹදࣔ
͓ͬͯ͘ͱྑ͍͔ɻ• RxAlamofire ͳͲ୳ͤઌਓ͕RxԽͯ͘͠ΕͯΔͷɺެ։͞ΕͯΔίʔυ͕݁ߏ͋Γ·͢ɻ
·ͱΊ
·ͱΊ• σʔλͷΓऔΓΛετϦʔϜͱͯ͠ߟ͑Α͏• ͱΓ͋͑ͣRxͷετϦʔϜ(Observable)ʹͰ͖ͨΒͬͪ͜ͷͷɻͲ͏Ճͯ͠తͷܗࣜʹ͢Δ͔Λߟ͑Α͏ɻ• RxΛۃΊͨΒϩδοΫ͕γϯϓϧʹ෭࡞༻ͳ͘ɺεϚʔτʹॻ͚ΔΑ͏ʹͳΔɻඇಉظॲཧා͘ͳ͍ʢͣʣ
͍͞͝ʹ• tech vein Ͱ͜ΜͳΞϓϦΤϯδχΞɺ ϑϦʔϥϯεɾύʔτφʔ༷Λืू͍ͯ͠·͢ɻ• RxSwift, RxJava Λ͍͍ͨ• MVVMɺ CleanArchitectureɺ DI Λ׆༻ͨ͠ઃܭʹڵຯ͕͋Δڵຯ͕͋ΔํɺͪΐͬͱΛฉ͍ͯΈ͍ͨํ ͨͩ3YͷΛͬͱฉ͖͍ͨํ ͥͻ͓͕͚Լ͍͞ʂ
ࢀߟ• ࠓճͷαϯϓϧίʔυஔ͖ɹʴ RxCocoa Λͬͨ؆୯ͳΞϓϦ• GitHub: https://github.com/ecoopnet/rxswift-beginner• ࢀߟهࣄ• Կͱͳ͘RxJavaΛͬͯΔ͚Ͳਖ਼Α͔ͬͯ͘ͳ͍ਓ͕ಡΉͱྑͦ͞͏ͳهࣄɾجૅฤ https://qiita.com/k-mats/items/4d374460a3f6284dd09f
͕࣌ؒ͋ΕαϯϓϧΞϓϦσϞ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
Driver ͷ͍ํ Observable ͱ΄΅ಉ͡
Driver ͷ͍ํ Observable ͱ΄΅ಉ͡ʁ→Τϥʔॲཧ͕ཁΒͳ͍ͷࡉ͔͍ҧ͍͋Δ
Driver (ิ)۩ମతʹ observable.asDriver(onErrorJustReturn: “”) ͱ͢Δͱ- UIεϨουͰॲཧɿ.observeOn(MainScheduler.instance)- Cold -> Hot มɿ.share(replay:1)- Τϥʔ࣌ʹࢹ͕ࢭ·ΔͷΛ͙ͨΊͷϦΧόϦॲཧɿ.catchError({ _ in “” })Λ·ͱΊͯͬͯ͘ΕΔΑ͏ʹͳΓ·͢ɻˎ