빠르게 프로젝트를 마무리 해야함 • Swift 라는 언어와 SwiftUI에 대한 숙련도가 아직 부족하여, 익숙한 Kotlin 기반의 Compose 로 공통의 UI 를 작성 해보는 것을 둘 다 선호 • Image Picker 라는 단순한 앱이기에, UI 를 Compose, SwiftUI 로 각각 작성 할 필요가 없다고 판단 • 이미지 로드를 위한 Coil 라이브러리가 3버전 부터 Compose Multiplatform 을 지원
없이 갤러리에 접근할 수 있는데, iOS 에서는??? 2. Coil3 을 통해 네트워크 이미지를 로드할 때, 기존의 Coil2 와 다른 점 3. moko-resources 라이브러리를 통해 국제화를 적용할 때, Android 측 Config Change 관련 이슈 4. Decompose 라이브러리의 Navigation 을 통해 데이터를 전달해야 하는데, 각 플랫폼에서 받아온 사진의 Data Type이 다른 문제
iOS 14 부터 PHPicker 를 사용 • 해당 기능을 구현하는 것이 이번 프로젝트의 핵심 • Peekaboo 라는 Compose Multiplatform 을 지원하는 imagePicker 라이브러리의 내부 코드를 참고해서 구현 https://github.com/TEAM-PREAT/peekaboo
iosApp 모듈이 아닌 composeApp 모듈에 포함되어 있기 때문에 Swift 가 아닌, Swift 와 호환 가능한 Kotlin-Native 기반으로 코드를 작성 • PHPickerViewController 를 호출하기 위해 PHPickerViewControllerDelegateProtocol 인터페이스를 구현하는 delegate 객체를 정의 • 결과적으로 선택된 이미지가 NSData 타입으로 내려오는데 이를 Kotlin-Native 에서 사용할 수 있는 ByteArray 타입으로 변환 참고) Compose-multiplatform 이미지 피커 라이브러리 배포하기 composeApp/iosMain/imagePickerLauncher.kt
Coil2.x 버전에서는 Network Image 를 로드할 때, Coil 내부에서 OkHttp 를 사용 Coil3 버전에서는 Multiplatform 을 지원하기 위해 OkHttp 가 아닌 Ktor 를 사용하는 것으로 변경 현재 alpha 버전인 Coil3 에서는 ImageLoader 가 기본적으로 network url 형태의 이미지를 로드하는 것을 지원하지 않음 별도로 coil-network 와 ktor 를 import 하여 NetworkFetcher.Factor()를 직접 설정
font, image) 등을 공유하여 사용하기 위해, 국제화를 지 원하기 위해 moko-resources 라이브러리를 사용 iOS 환경, Xcode 에서 resources 들을 복제하기 위한 환경 설정이 추가적으로 필요(공식 문서 참고) moko-resources 0.23.0 버전 기준) Android 기기에서 시스템 언어를 변경한 뒤, 앱에 다 시 진입했을 때, 변경된 언어가 반영이 되지 않는 문 제 (다시 앱을 실행해야 반영) https://github.com/icerockdev/moko-resources
Navigation 과 AAC ViewModel 과 비슷한 State holder 를 Multiplatform 에서 제공하는 라이브러리 문제는 Navigation 을 통해 상세 화면으로 전달해야 할 데이터의 타입이 Android 에서는 android.net.Uri, iOS 에서는 ByteArray 타입으로 같지 않다는 것 (심지어 android.net.Uri 타입은 android 플랫폼 종속성이 있어, commonMain 에서 접근 불가)
Kotlinx-Serialization 을 통해 직렬화 할 수 있는 ByteArray 로 통일하여 해결 • Uri 를 ByteArray 로 변환하기 위해, Coil3 를 이용 • 하지만 Coil3 는 Coil2 버전과 차이점이 존재해 오른쪽의 기존의 사용했던 함수를 사용할 수 없음 • 공식 문서도 확인해보았으나, alpha 버전이 나온 지 얼마 되지 않아, 레퍼런스가 없어 해결하는데 어려움이 존재
iOS UI를 그린다는것이 상상이 가지 않았 지만, 별개로 존재하는 iOS의 lifecycle 같은 부분들을 주의한다면 KMM 과 크게 다르 지 않다고 느꼈다. • 이번 KMM 스터디를 진행하면서 조금은 익숙해진 덕분에 공통 로직을 생성하여 각 플랫폼 별로 비즈니스 로직을 구현할 수 있었다. 특히 iOS 모듈에서는 kotlin-native 로 구현을 하면서 kotlin-native 에 큰 의존성을 갖고 있다보니, 제한사항을 마주할 수 있다는 생각이 들었다. • 그리고 지훈님이 decompose, moko-resources 등 여러 라이브러리 사용과 아이디어 를 주셔서 많이 배울 수 있었다.
과 조금이나마 친해질 수 있어서 좋았다. 프로젝트 초기에 환경 설정 단계(coil) 에서 어려움이 있었는데, 대원님께서 해결을 해주셔서, 빠르게 다음 단계로 넘어갈 수 있었다. • 다음에도 이런 좋은 기회가 있다면, Multiplatform 을 지원하는, 써보지 않았던 다른 라이브러리들도 사용 해보면서, 좀 더 규모 있는 앱을 만들어보고 싶다.
글 링크를 참고 • [Compose Multiplatform] Coil 을 이용한 Network Image Load • [Compose Multiplatform] moko-resources 를 이용하여 font 적용하기 • [Compose Multiplatform]moko-resources 라이브러리를 통해 국제화(i18n) 적용하기 • [Compose Multiplatform] Decompose 라이브러리를 통해 Navigation 구현하기 (깃허브 레포에도 링크 걸어놨어요!)