1월, 2024의 게시물 표시

Android Kotlin StateFlow and SharedFlow

이미지
사용 언어: Kotlin 1.9.22 사용 버전: Kotlin Playground 안드로이드 코틀린 StateFlow and SharedFlow를 알아보겠습니다. Flow의 하나인 StateFlow와 SharedFlow를 알아보는 시간을 가져봅니다. 공식 문서입니다. https://developer.android.com/kotlin/flow/stateflow-and-sharedflow flow에는 cold flow와 hot flow가 있습니다. cold(콜드) flow는 값을 요청할 때에만 emit(방출) 하는 형식이고, hot(핫) flow는 값을 요청하지 않아도 혼자서 계속 방출을 하는 형식입니다. 역시 뜨거운 물 샤워는 물 낭비를 하게 되는군요. 크흠. StateFlow(스테이트 플로)와 SharedFlow(쉐어드 플로)는 hot flow입니다. StateFlow와 SharedFlow는 state(상태) update(최신화)와 여러 consumers(컨슈머)에게 값을 emit 하기 위해 사용합니다. 그리고 SharedFlow는 세부적 설정이 가능한 StateFlow입니다. ⊙ StateFlow; 스테이트 플로: value를 호출함으로 현재 state 값을 읽을 수 있습니다. 새로운 값을 넣기 위해서는 MutableStateFlow에 value 값을 새로운 값으로 넣어주면 됩니다. 아래는 예시입니다. MutableStateFlow는 Producer(생산자)가 되고, StateFlow는 Consumers(소비자)가 됩니다. StateFlow는 hot이므로 collect(콜렉트)가 producer code를 실행하지 않습니다. StateFlow는 항상 in memory(메모리)에서 작동합니다. 새로운 consumer가 collect(수집)을 하게 되면, 항상 마지막 값을 반환합니다. 이것은 LiveData와 동일한 동작입니다. • 주의: UI의 Update가 필요한 곳에서 launch 또는 launchIn을 사용하여 UI에서 직접적으로 flow를 collect...

iOS Swift callAsFunction

이미지
사용 언어: Swift 5 사용 버전: Playgrounds 4.4.1 iOS 스위프트 callAsFunction을 알아보겠습니다. callAsFunction은 struct를 함수처럼 부를 수 있게 해줍니다. 즉, 긴 함수 이름을 적을 필요 없이 바로 부를 수 있게 되어 편합니다. 공식 문서입니다. https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations#Methods-with-Special-Names 예시로 이런 게 있네요. Playground에서 한 번 테스트해 봅시다. CallableSumTest라고 struct를 만든 다음에 callAsFunction을 정의해 줍니다. 짜잔! 1과 2를 더한 3이 나왔네요. 물론 callAsFunction을 직접 불러도 됩니다. 하지만 이럴 경우에는 callAsFunction을 쓸 이유가 없지요. 끝. 카테고리: iOS

Android Compose Ktor

이미지
사용 언어: Kotlin 1.9.22 사용 버전: Android Studio 2023.1.1 Patch 1 안드로이드 컴포즈 Ktor를 알아보겠습니다. Ktor는 Server와 통신하는 것을 도와주는 프레임워크입니다. 특이한 것은 Server와 Client 모두 사용 가능하다는 것입니다. Ktor는 JetBrain에서 공식적으로 지원하고 있으며 Kotlin으로 이루어졌습니다. Retrofit이 적용된 프로젝트에 Ktor로 변경하는 과정을 같이해봅시다. 참고 프로젝트: https://github.com/Jaehwa-Noh/Practice-Amphibians/tree/compose-ktor-amphibians-app App 용 Build.gradle에 dependencies를 추가해 줍니다. implementation("io.ktor:ktor-client-content-negotiation:2.3.7") implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7") implementation("io.ktor:ktor-client-core:2.3.7") implementation("io.ktor:ktor-client-okhttp:2.3.7") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2") network 밑에 AmphibiansKtorApiService를 만듭니다. install에 ContentNegotiation을 적어줍니다. Text.Plain을 Json으로 변경할 것을 알려주고, ignoreUnknownKeys는 정의되지 않은 Key가 있으면 무시하겠다는 겁니다. defaultRequest는 기본 url 설정입니다. expectSuccess는 통신 성공을 예상한다는 뜻입니다. AmphibiansKtorApiService.kt Qualifie...

iOS SwiftUI Factory with test

이미지
사용 언어: Swift 5 사용 버전: Xcode 15.2 iOS 스위프트유아이 Factory with test를 알아보겠습니다. Factory는 DI(Dependency Injection, 의존성 주입)를 위한 라이브러리입니다. 그리고 Resolver라는 DI library를 대체하는 오픈 소스입니다. 공식 문서입니다. https://hmlongco.github.io/Factory/documentation/factory 참고 프로젝트: https://github.com/Jaehwa-Noh/Practice-Amphibians/tree/swiftui-factory-amphibians-app iOS SwiftUI Factory 게시글과 이어집니다. https://shwoghk14.blogspot.com/2024/01/ios-swiftui-factory.html Unit test부터 한 번 봅시다. import Factory를 해줍니다. AmphibiansViewModelTest.swift setUpWithError에 Container.shared.reset()을 해줍니다. 그리고 기존의 코드는 놔두고 그 밑에 Container.shared.networkAmphibiansInfoRepository.register를 적어줍니다. register는 우리가 이전 시간에 작성한 Container extension을 register에 적힌 함수로 대체하겠다는 뜻입니다. 즉, 가장 아래의 Container.shared.amphibiansViewModel()은 fakeAmphibiansInfoRepository가 사용되게 됩니다. 실행해 봅시다. 문제없이 잘 테스트가 됩니다. 다른 파일들도 이렇게 register를 사용해서 갈아주면 됩니다. NetworkAmphibiansRepositoryTest.swift AmphibiansRemoteDataSourceTest.swift UI test를 볼까요? 원래 앱의 Factory를 사용하기 때문에 따로 코드를 변경해 줄 필요가 없습니다...

iOS SwiftUI Factory

이미지
사용 언어: Swift 5 사용 버전: Xcode 15.2 iOS 스위프트유아이 Factory를 알아보겠습니다. Factory는 DI(Dependency Injection, 의존성 주입)를 위한 라이브러리입니다. 그리고 Resolver라는 DI library를 대체하는 오픈 소스입니다. 아래는 Factory Github입니다. https://github.com/hmlongco/Factory 그리고 공식 문서입니다. https://hmlongco.github.io/Factory/documentation/factory 참고 프로젝트: https://github.com/Jaehwa-Noh/Practice-Amphibians/tree/swiftui-factory-amphibians-app 우선 설치부터 합시다. CocoaPods와 SPM(Swift Package Manager)를 모두 지원합니다. SPM을 사용해서 설치해 봅시다. File - Add Package Dependencies... Github 주소를 넣어주고 Add Package를 누릅니다. Add Package 클릭. 그러면 Xcode에 Factory Package가 보입니다. 설치가 다 되었네요. 여기 수동으로 Dependency Injection 한 것을 Factory를 사용하여 Injection 하는 걸로 변경해 봅시다. AppContainer.swift Data 그룹에 FactoryContainer 파일을 만듭니다. 기존에 있던 AppContainer와 App delegate들을 모두 삭제합니다. AppContainer.swift, AppDelegate.swift 삭제. Container에 extension을 만들어서 적어줍니다. 한 번 만들 때 가볍지 않고, 오랫동안 쓸 변수이기 때문에 singleton을 적어줍니다. userInitiated도 container에 추가합니다. 기본으로 만들면 unique를 사용하는 것으로 매번 새로운 Instance를 만듭니다. NetworkAmphibiansD...

Android App architecture: About the data layer

이미지
안드로이드 App architecture: About the data layer를 알아보겠습니다. 출처: https://developer.android.com/topic/architecture/data-layer UI layer가 UI와 관련된 state(스테이트)와 UI logic을 다루는 것이라면, data layer는 앱 data와 business logic을 다룹니다. business logic(비즈니스 로직)은 앱에 가치를 주는 것들입니다. 실제 세계의 business로 이루어졌으며, 앱 data를 어떻게 만들고, 저장하고, 변경하는지를 다룹니다. 이러한 개념의 구분은 data layer를 여러 화면, 앱 부분들의 정보 공유를 할 수 있게 해줍니다. 그리고 business logic을 UI 밖에 둠으로써 unit test(단위 테스트)를 가능하게 합니다. 여기서 추천하는 내용들은 앱을 확장하기 쉽게 만들고 사용성과 품질을 향상시키고 테스트하기 쉽게 만들어줍니다. 그러나 반드시 따라야 하는 것은 아닌 지침이며 당신의 상황에 맞게 적용해야 합니다. ⊙ Data layer architecture; Data layer 구조: data layer는 repositories(레포지토리)로 이루어졌으며 repositories는 0 ~ 여러 개의 data sources(데이터 소스)를 가집니다. repository class(레포지토리 클래스)는 각기 다른 data type(데이터 타입)을 다룹니다. 예를 들면, MoviesRepository class는 movies와 관련된 data만 다루고, PaymentsRepository class는 payments와 관련된 data만 다룹니다. Repository classes는 아래의 작업을 수행합니다. • data를 앱 전체에 전달합니다. • data의 변화를 관리합니다. • 여러 data source의 충돌을 관리합니다. • 앱 전체에서 data source를 볼 수 있게 합니다. • business logic을 포함합...