본문 바로가기

Swift

Divide Stream with "FlatMap" 처음 Combine을 공부할 때 map과 flatMap의 차이점을 공감할 수 없었습니다. 단순히 [String] -> String으로 flat하게 만들어주는 메소드로 이해했습니다. 하지만 이 친구는 생각보다 더 많은 일을 할 수 있는 친구였습니다. 오늘은 비동기적인 작업을 처리할 때 큰 힘이 될 flatMap에 대해서 소개하도록 하겠습니다. func flatMap( maxPublishers: Subscribers.Demand = .unlimited, _ transform: @escaping (Self.Output) -> P ) -> Publishers.FlatMap where P : Publisher, P.Failure == Never 파라미터 인자중에 transform을 보게 되면 새로운 Publish.. 더보기
Memory issue with closure injection Swift는 일급객체이기 때문에 클로저도 주입할 수 있어요! 적절한 상황에서 사용해야 이득이지, 잘못 사용하면 사용하지 않는 게 오히려 좋은 줄 몰랐습니다... (클로저 주입이 무조건 나쁘다는 말은 아닙니다. 환경에 맞게 잘 작성하시면 문제가 발생하지 않을 수도 있습니다.) 위 그림은 Store.dispatch 메소드를 ViewController로 클로저를 주입을 한 후, ViewController에서 Action이 발생했을 때 해당 클로저를 사용하는 부분입니다. 사실은 해당 클로저를 호출하게 되면, dispatch를 정의한 객체를 strong하게 잡은 상태입니다.(Store 객체) 그렇기에 클로저 주입을 하면, 참조에 관한 제어권을 잃어버리며 각 객체가 클로저 주입을 할 경우에 메모리에서 해제되지 않는.. 더보기
Custom Redux Testable 리덕스 패턴을 사용하면 여러가지 이득이 존재하지만, 오늘은 그중 하나인 "테스트"에 대해서 소개해 드리겠습니다. 글을 시작하기 앞 써 왜 많은 사람이 Test에 대해서 강조하는지, 제 개인적인 생각을 공유해드리겠습니다. 작성자가 아닌 다른 사람이 해당 코드를 수정할 때, 체크리스트를 제공합니다. 일하면서 가장 무서운 코드는 왜인지는 모르겠지만, 동작하는 코드였습니다. 다시 말해서 사이드 이펙트가 어디서 발생하고, 어디서 핸들링하는지 알 수 없는 코드였습니다. 이런 상황을 방지하기 위해서 우리는 해당 코드를 수정할 다른 사람에게 준수해야 할 체크리스트를 제공할 의무가 있습니다. Q: 그래서 어떤 객체를 테스트 해야 하나요? 여러 개의 객체 중에 Reducer를 테스트할 겁니다. 특정 Action이 발생했을.. 더보기
Real Time UI Test 앱을 개발하다 보면 크고 작은 이슈 때문에 뷰를 디버깅하는 상황이 빈번하게 발생합니다. alignment 수정하고, 간격 줄여보기 또는 hugging 값 변경하기 등등. 그 후 원하는 결과 값이 나오는지 확인하기 위해서 프로젝트를 빌드를 하고, 새로운 뷰를 개발할 때 원하는 결과가 나오는지 수시로 빌드를 합니다. 빌드하고 해당 뷰를 확인할 때 소모되는 시간을 무시할 수 없을정도로 크다고 생각합니다. 매번 이런 번거로운 작업을 도움을 줄 기능은 바로 SwiftUI입니다. 앱 최소 버전이 iOS 13.0이 아닌데요? 신경 쓸 필요 없습니다. 모듈을 분리하거나 디버깅 용도로만 사용할 수 있습니다. Preview with SwiftUI SwiftUI에서 UIKit을 사용하기 위해서 제공되는 두 가지 프로토콜이 .. 더보기
Custom Redux in Swift Redux는 무엇인가요? 위 그림이요. "예측 가능한 상태 컨테이너." 한 문장으로 디자인 패턴을 표현했기 때문에, 처음 Redux를 공부하는 사람에게는 아무 도움이 되지 않는 문장일 겁니다. 위 문장을 이해하기 위해서 도움을 줄 멤버를 소개하겠습니다. 1. Action 뷰에서 특정한 장소(Store)로 이벤트를 전달할 때 사용할 멤버입니다. 아래 그림을 봤을 때 사용자 이벤트가 발생했을 때, 이를 Action이라는 열거형으로 정의하게 될 겁니다. 뷰에서 버튼이 눌렀을 때 추가적인 작업을 할 필요 없이, 특정 Action이 발생했다고 특정한 장소(Store)로 보내기만 할 겁니다. 추가로사용자 이벤트뿐만 아니라 사용자 눈에 보이지 않는 이벤트들도 존재할 수 있습니다. (가령 초기 데이터를 받거나, 다른 .. 더보기
App Lifecycle 오늘 다룰 내용은 현재 공식문서에서 숨겨진 내용을 포함한다. RunLoop는 무엇일까라는 고민에서부터 출발했고, 여러 블로그 글을 정리해서 작성했다. storyboard를 사용할 때도 시작점을 설정하고, view를 코드로 작성할 때도 시작점을 설정해야 한다. App Lifecycle을 공부하면서 한 번도 main함수에 대해서 생각을 해본 적이 없다. 이 글은 application(_:willFinishLaunchingWithOptions:)을 부르기 전부터 시작한다. start 함수는 화면에서 앱을 실행시킬 때 호출되며 내부적으로 main 함수가 호출된다. Swift만 사용했다면 main 함수를 한 번도 본적이 없을 것이다. objc를 사용했다면 main.m 파일이 있지만, Swift는 아래 코드를 보면.. 더보기
@autoreleasepool applifecycle을 공부하던 중 @autoreleasepool를 발견하고 의문점이 생겼다. autorelease pool는 objc와 연관이 있어서 다른 블로그를 참고하면서 작성했다. int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(...); } } autorelease pool은 객체의 소유권을 포기할 수 있는 메커니즘을 제공하지만 즉시 해제 될 가능성을 방지한다. objc는 Swift와 달리 MRC(Manual Referencing Counting)을 (사용한다) 사용할수 있다. ARC가 나오면서 objc도 MRC가 아닌 ARC를 기본적으로 사용한다. 설정을 변경하면서 프로그래머가 선택할 수 있다. re.. 더보기
POP Swift 2.0으로 업데이트 되면서 Swift는 Protocol Oriented Programming라고 발표했다. 많은 Protocol이 생겼고, 구조체와 클래스에서 프로토콜을 채택하고, 클래스 상속에서 받지 못했던 이점을 챙겼다. 왜 OOP에서 POP로 변경된 건가? OOP는 클래스를 기반으로 상속을 통한 유연함을 유지했다. 하지만 상속은 생각보다 유연하지 못했다. 추상화된 클래스를 구체화했을 때 공통적인 책임을 갖는 여러 클래스가 존재할 수 있고 중복된 코드가 생성된다. 참조 타입을 사용하면서 발생하는 문제들(멀티 스레드 환경에서의 다중 접근, 동적 할당과 참조 카운팅으로 인한 자원 소모)이 있다. 위와 같은 문제점을 해결하고자 Swift 2.0에서는 Protocol + Extension + Ge.. 더보기