이번 프로젝트를 하면서 MVVM에 Coordinator를 더한 MVVMC패턴을 활용했는데요,
Coordinator를 이전부터 프로젝트에 적용해보면서 느꼈던 점들이 있는데
우선 MVC보다는 MVVM의 Input, Output패턴에서 함께 썼을때 플로우도 깔끔하고 궁합이 잘 맞았다는 생각이 들었고,
재사용하는 화면이 많을때, 복잡한 화면이동을 관리할때 편하다는 생각이 들었습니다.
이번 제가 만든 앱에서는 재사용하는 화면이 많았는데요,
이렇게 첫번째 탭과 세번째 탭에서 플레이리스트를 누르면
List화면이 나오고, 노래를 누르면 플레이어 화면이 나오는 구조로 만들었습니다.
그래서 첫번째, 세번째 탭에서 각각 같은 화면인 List화면과 플레이어 화면이 나와야 해서
ListCoordinator와 MusicPlayerCoordinator를 만들어 화면을 재사용하며 이동했습니다.
애플뮤직 권한 요청
이렇게 기본적으로 사용하고 있었는데,
출시를 앞두고 생각해보니
1.우선적으로 MusicKit을 사용하려면 애플뮤직 권한 승인을 받아야 하고,
2.저는 애플뮤직을 구독하고 있어서 당연히 노래를 들을 수 있었지만,
애플뮤직을 아직 구독하지 않은 사용자는 애플뮤직 구독 유도화면을 띄워주는 흐름이 자연스럽겠다고 생각했습니다.
그래서 AppCoordinator에서 처음 start할때
launch화면을 보여주며 권한을 요청하고
권한을 승인하면 탭바를 만들고 앱 시작,
권한을 거절하면 설정화면으로 이동해 권한을 승인할 수 있도록 구성했습니다.
참고로 저는 StoreKit의 함수를 사용했지만, MusicKit에서도 async함수로 기본제공 해줍니다.
이렇게 기본 구성을 했는데, 바로 애플뮤직 구독 요청을 하기보다는
앱을 사용하다가, 필요할때 구독요청을 띄워주고 싶었습니다.
제 앱에서 뮤직비디오는 미리보기URL을 사용해서 따로 계정이 필요하지는 않지만,
노래를 듣으려면 계정이 필요해서 노래를 play하는 시점에서 구독여부를 확인하고, 알맞은 화면을 띄워주기로 생각했습니다.
play시 뷰모델 분기처리
musicKIt에서는 구독유무를 확인하고, 필요시 결제 유도 컨트롤러를 띄우는 메서드가 존재하는데요,
이것도 SwiftUI 메서드기 때문에 UIKit에서는 사용하기 힘들어서
기존StoreKit의 메서드를 찾아서 활용했습니다.
재생을 누를때마다 구독여부를 확인하고, 구독이 안되어있다면
coordinator의 구매제안 컨트롤러를,
구독이 되어있다면 musicPlayer를 띄우도록 구현했습니다.
하지만 구독유무를 확인하는것도 네트워크 통신이고, 노래를 재생할때마다 확인하는 것은 불필요한 네트워크 통신을 하게된다고 생각했습니다.
이것도 MusicKit에서 기본 제공하는 SwiftUI의 @State를 바인딩해서 확인할 수 있지만
UIKit에서는 활용하기 힘드니 SubscriptionManager를 만들고,
앱이 foreground로 올때 한번만 UserDefault에 저장유무를 bool값으로 저장하고, 사용하기로 구현해보았습니다.
- SubscriptionManager
- UserDefaultsManager
- SceneDelegate의 sceneWillEnterForeground()
이렇게 구성해서 테스트를 해보니 앱이 켜지거나 foreground로 올때 구독유무를 bool값으로 가져와 저장하게 되고,
플레이버튼을 누르는 시점에 저장된 bool값을 통해 화면이동을 분기처리했습니다.