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

さようならRxSwift こんにちは*****

さようならRxSwift こんにちは*****

mobile.stmn #6 の発表資料です。AsyncSequenceを推し!
https://stmn.connpass.com/event/317394/

Tomoki Kobayashi

June 21, 2024
Tweet

More Decks by Tomoki Kobayashi

Other Decks in Programming

Transcript

  1. 5PNPLJ,PCBZBTIJ !UFNPLJ w ϞόΠϧΞϓϦΤϯδχΞ J04 "OESPJE 'MVUUFS  w J1IPOF(೔ຊ্཮

    ೥ ͱಉ࣌ʹ J1IPOFΞϓϦ։ൃΛ࢝ΊΔ w ελϝϯ0# w ηΧϯυϋ΢εͰͷੜ׆Λຬ٤தʜʁ🐒🐒🐒 bento.me/temoki
  2. 3Y4XJGU "TZODISPOPVT1SPHSBNNJOHXJUI0CTFSWBCMF4USFBNT w .JDSPTPGUىݯͷ3FBDUJWF9ͷ4XJGU࣮૷ w ࣌ؒͷܦաͱͱ΋ʹมԽ͢ΔσʔλΛ 4FRVFODFͷΑ͏ʹѻ͏͜ͱ͕Ͱ͖Δ w ඇಉظॲཧίʔϧόοΫ஍ࠈͷ ιϦϡʔγϣϯͷ̍ͭ

    w .77.ʴσʔλόΠϯσΟϯάΛ "QQMFϓϥοτϑΥʔϜͰ࣮ݱՄೳ qiita.com/temoki/items/b 8 5 9 b 5 5 a 0 6 bd 8 6 fdfe 2 5 w ϨΨγʔʹͳͬͯ͠·ͬͨײ͕͋Δʜ
  3. +40/"1* 👋͞Α͏ͳΒ3Y4XGJUͷલʹ ͱ͋ΔϓϩδΣΫτͷґଘؔ܎ʜʢ3Y4XJGUґଘ͞Ε͗͢໰୊ʣ "QQ "MBNP SF 3Y4XJGU .PZB +BQY 3FBDUJWF

    4XJGU +40/"1*1BSTFS /FUXPSL"CTUSBDUJPO )551/FUXPSLJOH "TZODISPOPVT1SPHSBNNJOH XJUI0CTFSWBCMF4USFBNT 👋
  4. +40/"1* 👋͞Α͏ͳΒ3Y4XGJUͷલʹ ͱ͋ΔϓϩδΣΫτͷґଘؔ܎ʜʢ3Y4XJGUґଘ͞Ε͗͢໰୊ʣ "QQ "MBNP SF 3Y4XJGU .PZB 3FBDUJWF 4XJGU

    +40/"1*1BSTFS /FUXPSL"CTUSBDUJPO )551/FUXPSLJOH "TZODISPOPVT1SPHSBNNJOH XJUI0CTFSWBCMF4USFBNT 👋
  5. 3Y4XGJU4JOHMFˠ import RxSwift func fetchIssues() -> Single<[Issue]> { ... }

    fetchIssues() .map { issues in issues.filter { $0.authorId == myId } } .subscribe( onSuccess: { myIssues in print(myIssues) }, onFailure: { error in print(error) } ) import Combine func fetchIssues() -> Future<[Issue], Error> { ... } fetchIssues() .map { issues in issues.filter { $0.authorId == myId } } .sink( receiveCompletion: { completion in switch completion { case .finished: print("finished") case .failure(let error): print(error) } }, receiveValue: { myIssues in print(myIssues) } ) $PNCJOF'VUVSF
  6. 3Y4XGJU4JOHMFˠ import RxSwift func fetchIssues() -> Single<[Issue]> { ... }

    fetchIssues() .map { issues in issues.filter { $0.authorId == myId } } .subscribe( onSuccess: { myIssues in print(myIssues) }, onFailure: { error in print(error) } ) func fetchIssues() async throws -> [Issue] { ... } do { let issues = try await fetchIssues() let myIssues = issues.filter { $0.authorId == myId } print(myIssues) } catch { print(error) } BTZODBXBJU
  7. 3Y4XGJU0CTFSWBCMFˠ import RxSwift func issuesObservable() -> Observable<[Issue]> { ... }

    issuesObservable() .map { issues in issues.filter { $0.authorId == myId } } .subscribe( onNext: { myIssues in print(myIssues) }, onError: { error in print(error) }, onCompleted: { print("completed") } ) import Combine func issuesPublisher() -> AnyPublisher<[Issue], Error> { ... } issuesPublisher() .map { issues in issues.filter { $0.authorId == myId } } .sink( receiveCompletion: { completion in switch completion { case .finished: print("finished") case .failure(let error): print(error) } }, receiveValue: { myIssues in print(myIssues) } ) $PNCJOF1VCMJTIFS
  8. 3Y4XGJU0CTFSWBCMFˠ import RxSwift func issuesObservable() -> Observable<[Issue]> { ... }

    issuesObservable() .map { issues in issues.filter { $0.authorId == myId } } .subscribe( onNext: { myIssues in print(myIssues) }, onError: { error in print(error) }, onCompleted: { print("completed") } ) func issuesStream() -> AsyncThrowingStream<[Issue], Error> { ... } do { for try await myIssues in issuesStream() .map({ issues in issues.filter { $0.authorId == myId } }) { print(myIssues) } } catch { print(error) } "TZOD4FRVFODF
  9. 🤗͜Μʹͪ͸"TZOD4FRVFODF ඇಉظγʔέϯεͰγϯϓϧͳߏ଄Խϓϩάϥϛϯά͕Ͱ͖Δ func issuesStream() -> AsyncThrowingStream<[Issue], Error> { ... }

    do { for try await issues in issuesStream() { let myIssues = issues.filter { $0.authorId == myId } if myIssues.isEmpty { print("No issues") continue } print(myIssues) } } catch { print(error) }
  10. "TZOD4FRVFODFͷͭ͘Γ͔ͨᶃ "TZOD*UFSBUPS1SPUPDPM "TZOD4FRVFODFͷ࣮૷ struct IssuesIterator: AsyncIteratorProtocol { typealias Element =

    [Issue] mutating func next() async throws -> [Issue]? { ... } } struct IssuesStream: AsyncSequence { typealias AsyncIterator = IssuesIterator typealias Element = [Issue] func makeAsyncIterator() -> IssuesIterator { ... } } let stream = IssuesStream()
  11. "TZOD4FRVFODFͷͭ͘Γ͔ͨᶄ "TZOD4USFBN "TZOD5ISPXJOH4USFBNͰ؆୯ʹ import CloudFirestore let stream = AsyncThrowingStream([Issue].self) {

    continuation in let listener = Firestore.firestore().collection(“issues”) .addSnapshotListener { snapshot, error in if let error { continuation.finish(throwing: error) return } let issues = snapshot?.documents?.map(Issue.init) ?? [] continuation.yield(issues) } continuation.onTermination = { _ in listener.remove() } }
  12. "TZOD4FRVFODFͷͭ͘Γ͔ͨᶅ "TZOD4USFBNNBLF4USFBN let (keywordStream, continuation) = AsyncStream.makeStream(of: String.self) Task {

    for await keyword in keywordStream { print(keyword) } } continuation.yield("keyword1") continuation.yield("keyword2")
  13. "TZOD4FRVFODFͷࠔΓ͝ͱ 3Y4XJGU΍$PNCJOFͷ୅ସͱͯ͠͸ػೳෆ଍ʁ w ඇಉظγʔέϯεʹ஋Λૹ৴͢ΔTVCKFDU w ෳ਺ͷඇಉظγʔέϯεΛ૊Έ߹ΘͤΔDPNCJOF [JQ NFSHF  w

    ඇಉظγʔέϯεͷ࣌ؒ࣠ʹ͓͚ΔEFCPVODF UISPUUMF w ಉ͡ඇಉظγʔέϯεΛڞ༗͢ΔTIBSF SFQMBZ NVMUJDBTU  👌