ios 131

언어의 기본 자료형 Dummy를 활용해 더 명확한 테스트 작성하기

언어의 기본 자료형 Dummy를 활용해 더 명확한 테스트 작성하기 테스트 코드를 작성하면서 언어에서 제공하는 기본 값을 그대로 사용하는 경우해당 값이 테스트에 영향을 주는 값인지혹은 단순히 기본값인지 다른 개발자가 판단하기 어려운 경우가 많음.이는 결국 가독성과 유지보수에 문제를 일으킬 수도 있음. 목차Swift의 기본 자료형을 Dummy 대신 사용한 테스트 코드를 마주한 경우Model 과 ViewModel의 구현체 확인테스트 코드에 Dummy 값을 명시적으로 사용한 경우 Swift의 기본 자료형을 Dummy 대신 사용한 테스트 코드를 마주한 경우아래처럼 테스트코드가 작성되어 있다면, 테스트가 올바르게 작성되었다고 생각하기보다 코드를 볼수록 많는 의문점들이 생겨남많은 의문점들은 테스트 본질이 아닌 부..

iOS Combine을 활용해 로그인 상태 관리 기능 구현

iOS Combine을 활용해 로그인 상태 관리 기능 구현 멀티캐스트 딜리게이트 패턴을 활용해 구현했던 코드를 개선하고자 함.멀티캐스트 딜리게이트 패턴 활용한 로그인 상태 관리 구현 : https://rldd.tistory.com/706Combine을 활용해 로그인 상태 관리 기능 구현 : https://rldd.tistory.com/707  목차아이디어데모 샘플 구현 코드Combine 기반 기능 모듈 구현로그인 기능 구현체사용 예제구현 후 분석아이디어이전에 키보드 상태를 감지하기 위해서 Combine을 활용한 적이 있었는데, 이번에도 해당 형태로 구현하면 별도의 주입 없이 더 간편하게 사용할 수 있다고 생각  데모 샘플 구현 코드 (Combine 기반 기능 모듈 구현)멀티캐스트 딜리게이트 패턴을 Com..

[Swift] Timer + RunLoop, backgroundQueue (swift-corelibs-foundation)

[Swift] Timer + RunLoop, backgroundQueue (swift-corelibs-foundation) 서비스 및 기능에 따라서 RunLoop.main에서 돌아가게 하면 안되는 케이스도 존재. 잘못 설계할 경우 Timer기반으로 동작하는 로그나 기능 등 예상치 못한 결과를 낼 수 있음. RunLoop.main에서 타이머가 아예 방출되지 않거나 RunLoop.main이 아닌 다른스레드에서 돌려야 하는 경우에 대하서 자세히 알아볼 예정 위 케이스들을 내부 구현 코드를 통해 근거 있게 정리해보고자 함. 글의순서 타이머 알아보기 swift-corelibs-foundation내에 Timer 구현 알아보기 Timer 선언부 Timer scheduledTimer 함수 RunLoop 간단히 알아보..

iOS CoreData Relationships

iOS CoreData Relationships iOS CoreData의 Relationship을 공부해보자.연관 포스팅[iOS CoreData 간단한 CRUD](https://rldd.tistory.com/587)[iOS SwiftData in UIKit](https://rldd.tistory.com/588)[iOS CoreData 이론](https://rldd.tistory.com/586)[iOS CoreData Relationships](https://rldd.tistory.com/661) 히스토리2024.10.13CoreData Relationship 정리2024.12.21CoreData Relationship 패키지 모듈화 정리샘플 코드에서 Commnutity Package 참고히스토리샘플코드목..

SwiftUI 하위뷰에서 상위뷰로 DelegatePattern을 활용해 이벤트 전달하기

SwiftUI 하위뷰에서 상위뷰로 DelegatePattern을 활용해 이벤트 전달하기  글의 순서상황어떻게 처리할까?코드 적용 예시마무리 상황홈 화면에서 프로필 리스트가 있는 네비게이션 방식으로 화면을 전환하고, 해당 화면에서 프로필을 전환하고 pop 혹은 dismiss로 홈 화면으로 돌아왔을 때, 프로필이 전환되어야 함. 즉, 하위 뷰가 상위 뷰로 프로필이 전환되었음(이벤트)을 알려야 함. 어떻게 처리할까?우선 UIKit에서라면 여러가지 방법이 있겠지만, 단순하게는 Delegate Pattern이 있음.SwiftUI에서는 Environment, preferenceKey를 활용할 수 있고, @State, @Binding을 활용해 하위 뷰와 연결할 수도 있음. SwiftUI에서 제안된 방법들은 사용..

모듈화 리팩토링 과정에서 고민했던 것들

모듈화 리팩토링 과정에서 고민했던 것들 Tuist 3.x 버전으로 사용한게 마지막이라 4.x 버전으로 학습하고 변경해보고자 함.하나의 설계 방법보단 여러가지 설계들을 보면서 느끼고 경험하는 것이 중요하다고 해서 기존 쓰던 방식을 완전히 배제하고 다른 사람들이 사용하는 방식을 따라하는 수준 + 내 스타일 적용 요정도로 해보고자 함. 글의 순서프로젝트 모듈화 구조 스크린샷리팩토링 시작 전 생각 정리NetwrokSDK 모듈에 대해서feature에서 ui를 분리한 이유화면전환 어떻게 할 것인지이미 구현된 UI가 필요한 경우는 어떻게 할 것인가?관리하는데 드는 비용에 대한 고민마무리 소감 프로젝트 모듈화 구조 스크린샷  리팩토링 시작 전 생각 정리깃헙에 레포 돌아다니면서 다른 사람들이 사용하는 Tuist 참고하..

Swift Concurrency를 적용하면서 발생한 동시성 문제

Swift Concurrency를 적용하면서 발생한 동시성 문제사내에서도 동일한 이슈가 발생했었어서 해당 부분에 대해서 정리하고자 함.기존 Combine으로 작성된 코드를 async-await으로 교체하는 작업을 진행.  글의 순서Combine으로 작성된 코드 살펴보기Swift Concurrency로 단계적으로 전환하기Swift Concurrency로 안전성 확보하기Combine에서 Swift Concurrency 적용 Combine으로 작성된 코드 살펴보기기존 코드는 캐싱을 위해 캐시 프로퍼티가 존재하며, Combine을 기반으로 작성되어 있었음.Combine을 선택한 이유는 RxSwift가 익숙하여, RxSwift와 닮은 애플 퍼스트파티 선택에서 Combine을 선택   Swift Concurre..

UseCase와 Repository 테스트 목적 정리

UseCase와 Repository 테스트 목적 정리 해당 형태의 구조의 프로젝트에서 테스트코드를 작성하면서 학습하고 느낀점들을 정리. 글의 순서UseCase 테스트 목적Repository 테스트 목적Repository 테스트 하기SearchSubwayUseCaseTests 실패 후 로직 보완 안드로이드 공식 앱 아키텍처 가이드를 확인하면서 UseCase 영역에 해당하는 Domain이 Optional로 되어 있음을 확인할 수 있었음.개인 경험에 의하면 실제로 UseCase에서 특별한 처리 없이 사실상 래핑에만 해당하는 경우도 많긴 함. 일반적인 상황에서는 Domain Optional 이어도 나쁘지 않겠지만, 기능이 하나 둘 추가되면서 Repository가 두꺼워지고 결국은 UseCase를 분리하는 과정에..

지하철 검색 기능에 캐싱 로직 도입하기

지하철 검색 기능에 캐싱 로직 도입하기 지하철 검색 로직에 캐싱 로직을 도입. 글의 순서SearchSubwayUseCase 개선SearchSubwayUseCase 테스트를 위한 Stub 객체 만들기SearchSubwayUseCaseTests 캐싱 로직 동작 검증 코드SearchSubwayUseCaseTests 실패 후 로직 보완  지하철 검색 로직은 사용자가 키보드를 통해 검색어를 입력할 때 throttle을 활용해 약간의 시간을 두어 검색을 실행.여기까지는 우리가 일반적으로 사용하는 검색 로직. 동일한 값에 대해 서버 요청을 줄이고, 동일한 결과값을 더 빨리 제공할 수 있으므로 이점은 확실. SearchSubwayUseCase 개선기존에 Combine을 활용해서 처리하고 있었는데, cache 프로퍼티..

UICollectionView Sticky Header

UICollectionView Sticky Header  UITableView처럼 헤더를 붙게 해달라는 요청이 들어왔는데, 해당 키워드로 검색했을 때UICollectionViewFlowLayout을 커스텀 해서 만드는 글들이 많아서 작성 if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout { layout.sectionHeadersPinToVisibleBounds = true // 헤더를 고정}  UITableView처럼 헤더를 붙게 사용할 수 있음.