문제 상황 tuist edit으로 모듈의 구조를 설계하고 tuist generate로 프로젝트를 생성하여 작업하였다. 디자인 시스템 모듈을 만들고 다른 모듈에서 사용할 수 있도록 열심히 세팅을 하고 종료했다. 다음에 다시 generate로 실행해 보니 세팅한 Sources 폴더가 나타나지 않는 문제가 있었다. 해결 1. 먼저 생각한 것은 edit으로 Project.swift를 설정할 때 설정하지 않거나 빠트린게 있지 않을까였다. ["Sources/**"]를 안 적었다던지. 정말 한줄한줄 살펴봐도 문제를 찾을 수가 없었다. 보통은 이 방법으로 해결이 된다고 생각한다. 어딘가에 세팅을 뻈으니까 2. edit에서 해당 모듈 자체를 삭제하고, 미리 백업한 부분을 참고하여 다시 작성했다. 이유는 모르겠는데 완벽하..
문제 상황 RxSwift 의존성을 사용하다가 Combine으로 바꾸면서 RxSwift 의존성을 지웠다. 난 clean 명령어가 캐시를 정리해 준다고 들어서 이걸 이용하면 깔끔하게 청소가 가능할 것으로 생각했지만 오산이었다.. 해결방법 모든 사람이 같은 상황은 아니겠지만, 내 경우 Xcode의 DerivedData이 문제였다. clean 명령어가 여기 있는 파일들까지는 관리를 못 하는건지 아니면 거듭된 tuist edit - tuist fetch - tuist generate의 순환 속에서 캐시가 지울 수 없는 상황이 된 건지.. rm -rf ~/Library/Developer/Xcode/DerivedData 터미널에서 해당 코드를 이용하여 캐시를 박살 내버리면 된다. 난 조금 쫄려서 open.으로 gui..
문제상황 Firebase를 이용하여 Google 로그인 버튼을 문서를 보고 구현하고 미흡한 부분이 없는지 이전에 봐둔 예제를 보고 참고하려고 했다. 2022년 예제인데도 그새 방식이 바뀐 모양인지 Delegate를 이용하여 AppDelegate에서 이뤄지는 작업이 대폭 축소되고 로직을 구현하는 ViewController의 역할이 증가하였다. 지금은 아래의 코드가 AppDelegate에서 하는 역할의 전부다. func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { FirebaseApp.configure() ..
문제상황 Realtime database를 사용하려고 리전을 설정하고 이 데이터 베이스를 이용하여 sample 데이터를 전송해 봤다. 그런데 이상하게도 null이 존재할 뿐 내가 보낸 데이터가 있지 않았다. 로그를 살피니 아래의 문구가 적혀있었다. Firebase Database connection was forcefully killed by the server. Will not attempt reconnect. Reason: Database lives in a different region. Please change your database URL to https://[blabla].[리전이름].firebasedatabase.app 보아하니 기본으로 설정된 리전을 선택하지 않고 나름 줄여보겠다고 도쿄나..
두 라이브러리 모두 비동기환경에서 이미지를 받아오고 처리하는 라이브러리다. 여러 귀찮은 작업들(기본 이미지, 캐시, call 취소) 등이 구현되어 있어 편리하다는 장점이 존재한다. 무슨 차이일까? 1. 구현 언어 Kingfisher는 Swift로 짜여 있고 SDWebImage는 Objective-C로 짜여 있다는 차이점이 존재한다. (캐시를 처리해야 하므로 킹피셔에 Objective-C가 있긴 하다) 2. 동시성 처리 동시성 프로그래밍을 위해 Kingfisher는 GCD를 사용하지만 SDWebImage는 NSOperation을 사용한다. 나중에는 Swift Concurrency로 짜인 라이브러리가 나올지도? 3. 캐시 캐시를 처리할 때 Kingfisher는 기본적으로 메모리 캐시가 적용되어 있다. 원하는..
버튼을 눌렀을 때 성격 급한 사람은 버튼을 연타하는 경우가 적지 않다. API 통신 시에 이걸 적절하게 처리하지 않으면 통신이 여러 번 일어나는 상황이 발생하기 쉽다. 단순 조회면 그냥 하면 그만이지만 회원가입 버튼 같은 거면 까다로운 상황에 직면한다. 만약 내가 회원가입 시 UUID를 생성하고 이걸로 유저를 구분한다고 하자 이 상황에서 가입 시 연타해서 UUID가 4개 생길 수도 있다. 그럼 UUID가 의미가 있나? 이를 방지하는 기능이 보통 throttle과 debounce이다. debounce 특정 시간까지 기다려서 더 이상 입력이 없다면 마지막으로 발생한 이벤트를 전달한다. button.rx.tap .debounce(.milliseconds(500), scheduler: MainScheduler...
스위프트에서 메서드를 만들어 사용하다 보면 어느샌가부터 for, with와 같은 키워드를 사용했다. 이걸 매개변수 레이블(parameter labe)라고 한다. 함수를 보고 매개변수가 어떤 용도로 사용하는지 암시하여 이해를 돕기 위해 사용한다. 딱히 기능이 있는 것은 아니라 그냥 눈치껏 함수 이름에 맞춰서 붙여 사용하면 된다. for나 with 말고도 아래와 같은 레이블이 존재한다. by: 매개변수의 값이 증가/감소를 뜻하고 싶을 때 from: 특정 값을 기반으로 새로운 결과를 만들고 싶을 때. (url, data, String 등) to: 함수를 이용하여 특정 목적에 전달, 도달하기 위해 using: with와 유사 in: 어떠한 범위 안에서 작업을 할 때 조사하면서 알았던 것은 익숙하지 않으면 그냥 ..
결론만 아시려면 가장 아래의 해결을 보시면 됩니다. 문제상황 do { let result = try JSONDecoder().decode(UserProfile.self, from: data) print(result) } catch { print(error.localizedDescription) completion(.failure(error)) } REST API 통신으로 data를 받고 UserProfile이라는 모델로 decode 하여 인스턴스를 생성하고 있는 상황이었다. 그런데 이상하게도 자꾸 catch로 빠지는 일이 발생했다. 시도 1. 방금 전만 해도 되는 상황이었고 UserProfile을 세부조정하다가 발생한 일이라 원래의 모델을 원상태로 복구하여 시도했다. -> 실패 2. 이에 API 문서에 ..
두 메서드 모두 UIView를 초기화하다 보면 사용하는 녀석들이다. init(frame:) frame은 코드를 사용하여 뷰를 생성할 떄 호출하는 초기화 메서드다. (코드 베이스, programmatically 등) super.init(frame: ) 사용자 지정 뷰 클래스에서 UIVIew에 있는 init(frame: ) 메서드를 호출함으로써 초기화를 돕는다. 대표적으로 뷰의 프레임을 설정하거나 기본 속성을 설정한다. super.init(frame:. zero) frame 값을. zero로 주는 경우가 많은데 초기에 뷰가 화면에 나타나는 걸 방지하기 위해 한다. init(coder:) Storyboard, xib을 이용하여 화면을 구성할 때 필요한 녀석이다. NScoder를 이용하여 처리하게 되며, 컴파일..
Type of expression is ambiguous without more contextType of expression is ambiguous without more context 이 에러는 wrong argument 문제이다. 때문에 메서드를 이용하는 부분에서 문제가 생길 여지가 많다. 문제상황 내 경우에는 이 에러는 swicth에서 result를 이용해 success case, failure case를 두고 상황별로 동작을 정의하던 중에 발생했다. success에서는 let data를 생성하여 행동을 정의했고 failure에서는 let error를 만들고 그냥 break로 임시로 처리를 해놨다. public func configure(with viewModel: XYZViewModel) { v..