분류 전체보기
-
[RxSwift6] "withUnretained" operator로 리펙토링하기iOS/RxSwift 2022. 2. 2. 22:17
이전에 글로 남겼다시피 subscribe, bind, drive등을 통해서 구독할 때 순환참조의 문제점을 방지하기 위해서 weak self를 통해서 약한참조를 만들어주었다. observable .subscribe(onNext: { [weak self] (string) in guard let self = self else { return } self.doSomething(string) }) .disposed(by: disposeBag)이 방식은 확실한 방법이였지만, 보일러 플레이트가 계속해서 만들어져 코드를 지저분하게 만들었다. RxSwiftCommunity의 RxSwiftExt에 있던 withUnretained operator은 이런 코드를 조금 더 명료하게 만들어주어 인기가 많았고, RxSwift 6...
-
[RxSwift] weak, unowned self에 대한 의문iOS/RxSwift 2022. 1. 27. 23:57
일단 기본적으로 두 용어의 개념은 생략하고 쓰임새를 써보자면 다음과 같다. weak는 객체를 Optional로 참조하기 때문에, 참조하는 객체가 도중에 사라질 가능성이 있을 때 사용한다. unowned는 객체를 Non Optional로 참조하기 때문에, 참조하는 객체가 항상 존재함(필요할 때)을 가정한다. weak는 필요할 때마다 Unwrapping에 대한 코드를 작성해야 하기 때문에 불편하다.. 기존에 갖고있던 생각 이제 RxSwift에서 두 키워드의 쓰임에 대해서 생각해보자. RxSwift에는 Observable의 생명주기를 관리(?)해주는 dispose 메서드, 그것을 더 편하게 도와주는 DisposeBag이 있다. DisposeBag은 최대 생명주기가 부모객체의 생명주기와 같다. 부모 객체가 de..
-
[RxSwift] Error Handling [2]iOS/RxSwift 2022. 1. 27. 01:40
이전 글에서 Error Handling에 대해서 탐구하는 과정을 기록했다. 그 이후 여러가지 Demo나 Article을 읽으며 어떤 방식이 더 좋은 선택일지 고민했다. 수 개의 프로젝트를 살펴보았을 때, 대게 몇가지 패턴으로 에러를 처리하고 있었다. 그 중, 나는 materialize를 활용한 방식에 주목했다. 일단 이 방식이 입증된 방식인지를 알기 위해서 해당 키워드에 대한 수많은 검색을 통해서 저명한 개발자들의 활용사례를 발견할 수 있었다. 더보기 https://github.com/ReactiveX/RxSwift/issues/729#issuecomment-621606909 What is the correct way to handle errors? · Issue #729 · ReactiveX/RxSwi..
-
[RxSwift] Error Handling [1]iOS/RxSwift 2022. 1. 25. 20:51
아래 코드는 Firebase/Auth의 전화번호 로그인과 idtoken발급에 대한 예제코드에 RxSwift를 적용한 것이다. 네트워크 레이어 분리를 위해서 viewModel과 다른 클래스에 메서드를 작성해 주었다. 분리하기 이전에는 네트워크 통신시 에러가 발생했을 때, errorToast관련 Subject에 accept만 해주고 onNext를 방출할 수 있었다. 하지만 분리한 뒤에는, 에러가 발생했을 때 viewModel에게 명확하게 에러가 발생했다는 것을 전달해 주기 위해서 Single(.failure)을 사용해야겠다고 판단했다. 해당 상황을 예제코드로 옮기면 아래와 같다. // // ViewController.swift // Practice // // Created by SEUNGMIN OH on 2..
-
[UITextField] 일정 포멧에 맞춰서 / 마스크 입혀주기iOS/UIKit 2022. 1. 22. 22:16
뭐라고 설명하기 어려운것 같아서 영상으로 설명을 대신한다. 아래 예시는 전화번호 포멧에 맞춰서 표시형식을 맞춰준 것이다. 간단하게 설명하자면, 텍스트필드 입력값을 받아서 포멧에 맞게 수정한 뒤에 다시 텍스트필드값을 바꿔주는 로직이다. 구현은 아래와 같다. extension String { var decimalFilteredString: String { return String(unicodeScalars.filter(CharacterSet.decimalDigits.contains)) } func formated(by patternString: String) -> String { let digit: Character = "#" let pattern: [Character] = Array(patternStrin..
-
[SwiftGen] Assets을 쉽고 안정적으로 사용하자!iOS 2022. 1. 20. 01:11
소개 SwiftGen이란 쉽게 말하자면 Assets을 코드로 바꿔주는 기능을 해준다고 생각하면 된다. 변환을 거친 후에는 아래와 같이 쉽게 사용할 수 있게 해준다. 이걸 왜 사용하느냐? 1. 리소스가 매우 많을 때, 자동으로 코드로 변환해주기 때문에 생산성이 향상된다. 2. 자칫 잘못 입력할 수 있는 String으로 된 파일명을 자동으로 변환해주기 때문에 안정성이 향상된다. 사용 설치 // Pod -> Podfile에서 pod 'SwiftGen', '~> 6.0' // Homebrew -> Terminal에서 $ brew update $ brew install swiftgen적용 프로젝트 최상단에 swiftgen.yml파일 생성 // swiftgen.yml xcassets: ..
-
[미세먼지 TIL] 퍼센트값으로 된 line height의 적용iOS/UIKit 2022. 1. 18. 22:12
처음으로 디자이너분들이 작업하신 UI 명세(?)를 Figma로 받아봤다. 그런데 line height에 퍼센트로 표시되어있었다. 그렇지만 Swift에서는 lineHeight의 자료형이 CGFloat이기 때문에 명세에 있는 line height을 어떻게 적용해야 할지 모르겠다. 검색을 통해서는 해결하지 못했고, Figma를 살펴보던 중 값을 계산해보면서 적용방법을 알아낼 수 있었다. lineHeight(px) = fontSize(px) * lineHeight(percent) 즉, 위의 첫번째 예시처럼 font의 fontsize = 20px이고 lineHeight(px) = 160%라면 lineHeight(px) = 32px로 계산할 수 있다.
-
UIButton.Configuration으로 리펙토링 아이디어iOS/UIKit 2022. 1. 14. 00:31
UIButton.Configuration에는 애플에서 사전에 만들어놓은 여러가지 스타일들이 있다. button.configuration = UIButton.Configuration.plain()이런 형태로 쉽게 스타일을 적용할 수 있다. 이걸 토대로 custom style도 쉽게 만들어 리펙토링하면 괜찮을 것 같다. extension UIButton.Configuration { static func style() -> UIButton.Configuration { var configuration = UIButton.Configuration.bordered() configuration.baseForegroundColor = .white configuration.imagePlacement = .bottom c..