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

VIPERを利用した音声配信アプリの開発の裏側.pdf

entaku
July 20, 2022

 VIPERを利用した音声配信アプリの開発の裏側.pdf

entaku

July 20, 2022
Tweet

More Decks by entaku

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ Name: entaku Job: iOS / AndroidΤϯδχΞͳͲ SIer໿6೥ 2018/3~ εϙʔπϚονϯάΞϓϦ

    2019/3~ CBcloud ෺ྲྀITαʔϏε 2೥൒ 2021/12~ Voicy Twitter: @entaku_0818
  2. VIPER ͱ͸ʁ https://cheesecakelabs.com/blog/ios-project-architecture-using-viper/ • VIPER is a backronym for View,

    Interactor, Presenter, Entity and Router. It’s basically an approach that implements the Single Responsibility Principle to create a cleaner and more modular structure for your iOS project. The ideia behind this pattern is to isolate your app’s dependencies, balancing the delegation of responsibilities among the entities. • VIPERͱ͸ɺViewɺInteractorɺPresenterɺEntityɺRouterͷ಄จࣈΛͱͬͨ΋ͷ Ͱ͢ɻجຊతʹ͸ɺSingle Responsibility Principleʢ୯Ұ੹೚ݪଇʣΛ࣮૷͠ɺ iOSϓϩδΣΫτʹΫϦʔϯͰΑΓϞδϡʔϧԽ͞Εͨߏ଄Λ࡞Γग़ͨ͢ΊͷΞϓ ϩʔνͰ͋Δɻ͜ͷύλʔϯͷഎޙʹ͋Δߟ͑ํ͸ɺΞϓϦͷґଘؔ܎Λ෼཭ ͠ɺΤϯςΟςΟؒͷ੹೚ҕৡͷόϥϯεΛͱΔ͜ͱͰ͢ɻ
  3. νϟϯωϧৄࡉը໘ /// @mockable protocol ChannelDetailViewProtocol { func setupCustomNavigationBar(channelName: String, channelImageURL:

    URL?) func scrollToTop() ΢ϥଆ protocol ChannelDetailPresenterProtocol { func onViewDidLoad() func onViewWillAppear() func onViewDidAppear() func onViewWillDisappear() func onBackButtonTapped() func onRefreshControlTrigger() func onShareButtonTapped() • ViewͰ͸UI্ͷॲཧʹؔ͢ΔϝιουΛ༻ҙ • εςʔλεόʔͳͲ • Presenter͔Βݺͼग़͢
  4. /// @mockable protocol ChannelDetailInteractorProtocol { var channel: Channel? { get

    } var keyword: String { get } var live: Live? { get } var subscriptionInfo: SubscriptionInfo? { get } func getAllData() ΢ϥଆ protocol ChannelDetailPresenterProtocol { func onViewDidLoad() func onViewWillAppear() func onViewDidAppear() func onViewWillDisappear() func onBackButtonTapped() func onRefreshControlTrigger() func onShareButtonTapped() νϟϯωϧৄࡉը໘ • InteractorͰ৘ใऔಘॲཧ·ͨɺσʔλΛ ެ։ • Presenter͔Βݺͼग़͢
  5. ࢸΔॴ͔Βݺ͹ΕΔΫϥε /// @mockable protocol AudioControllerProtocol: AnyObject { /// Playing settings

    properies var playSpeed: AudioPlaySpeed { get set } var audioSpeaker: AudioSpeaker { get set } var bgm: AudioBGM { get set } var voiceVolume: Float { get set } var bgmVolume: Float { get set } var soundEffectVolume: Float { get set } var isSoundEffectEnabled: Bool { get set } /// Playing info properies var audioStatus: AudioStatus { get } var isPlayingOrLoading: Bool { get } var isVoiceOrBGMPlaying: Bool { get } var elapsedPlaytime: TimeInterval { get set } /// Playlist info properies var audioListStyle: AudioListStyle { get set } var playingChannel: Channel? { get } ΢ϥଆ Ի੠࠶ੜʹؔ͢Δ͜ͱΛ͜͜Ͱશͯ΍͍ͬͯ·͢ όοΫάϥ΢ϯυ࠶ੜ/࿈ଓ࠶ੜ/ϓϨϛΞϜ ࠓޙ΋ػೳ௥Ճͨ͠Βઈର૿͑Δ…
  6. Test ΢ϥଆ https://github.com/Quick/Quick • ར༻ϥΠϒϥϦ • QuickSpec • ςετͷ࣮ߦͰར༻ •

    https://github.com/Quick/Quick • mockolo • ϞοΫͷ࡞੒ʹར༻ • https://github.com/uber/mockolo
  7. Test class ChannelDetailPresenterSpec: QuickSpec { override func spec() { describe("ChannelDetailPresenter")

    { var presenter: ChannelDetailPresenter! var viewMock: ChannelDetailViewProtocolMock! var interactorMock: ChannelDetailInteractorProtocolMock! var routerMock: ChannelDetailRouterProtocolMock! var audioControllerMock: AudioControllerProtocolMock! var deviceManagerMock: DeviceManagerProtocolMock! ʙʙʙ // Prepare let commonSetupCallCount = viewMock.commonSetupCallCount let setContentBottomInsetCallCount = viewMock.setContentBottomInsetCallCount let showLoadingCallCount = viewMock.showLoadingCallCount let getAllDataCallCount = interactorMock.getAllDataCallCount // Action presenter.onViewDidLoad() // Expect expect(viewMock.commonSetupCallCount) == commonSetupCallCount + 1 expect(viewMock.setContentBottomInsetCallCount) == setContentBottomInsetCallCount + 1 expect(viewMock.showLoadingCallCount) == showLoadingCallCount + 1 expect(interactorMock.getAllDataCallCount) == getAllDataCallCount + 1 ΢ϥଆ • MockΛར༻͠ɺPresenter͔Βҙਤͨ͠View/Interractor/Routerͷϝιο υΛݺͼ͍ͩͯ͠Δ͜ͱΛ֬ೝ
  8. ·ͱΊ • VoicyͰ͸ΞʔΩςΫνϟʹVIPERΛ࠾༻͍ͯ͠·͢ • ΞʔΩςΫνϟͷಋೖΛ͔ͨ͠Βͱ͍ͬͯ׬ᘳͱ͸͍͖·ͤΜ • Ի੠ͷॲཧ͸ࢸΔॴ͔Βݺ͹ΕͨΓ… • ڞ௨Խ͞ΕͨΫϥε͕͋ͬͨΓ •

    PresenterͷςετΛॆ࣮͍ͤͯ͞·͢ • Presenterͷςετ͸վΊͯઃܭΛݟ௚͖͔͚ͬ͢ʹͳ͍ͬͯ ·͢ • BitriseͰઈରʹCIճ͢Α͏ʹͯ͠·͢