본문 바로가기

All

(44)
[iOS] Custom ContainerViewController 활용시 주의할 점 ChildViewController로 추가/제거 될 때 willMove, didMove 메소드가 자동으로 호출됩니다. 코드로 ContainerViewController를 구현했다면 child를 추가할 땐 didMove, 제거할 땐 wilMove 메소드를 직접 호출해주어야 합니다. 트랜지션도 커스텀했다면 트랜지션이 종료된 후 적절한 시점에 메소드를 호출해주면 됩니다. 참고로, child를 제거할 때 didMove가 자동으로 중복되어 호출될 수 있습니다. func addChild() { let viewController = ChildViewController() addChildViewController(viewController) // addChild 후 호출, 커스텀 트랜지션이 있다면 완료 후에 호출 vi..
[Mac] 터미널에 보이는 컴퓨터, 호스트이름(hostname) 변경하는 방법 sudo scutil --set ComputerName "newname" sudo scutil --set LocalHostName "newname" sudo scutil --set HostName "newname" dscacheutil -flushcache 터미널(Terminal)에서 위 명령어 수행 후 재시동하면 반영된다.
[Git] fork한 repository 최신화하기 1. fork한 repository 주소를 upstream에 등록하기 $ git remote add upstream https://github.com/~/~.git 2. 할당된 git 주소 확인하고 싶을 경우 $ git remote -v 3. 원본 저장소 fetch 해오기 $ git fetch upstream 4. 내 master(main) 브랜치와 merge 하기 $ git checkout master $ git merge upstream/master
[iOS] Swift 참조 타입이 앱 기동 시간에 안 좋은 영향을 끼치는 이유 (번역) 앱 기동(launch) 경험은 앱 사용자에 대한 첫 인상입니다. 앱이 시작될 때까지 기다리는 시간은 수치상으로는 짧지만 실제로 짧게 느껴지지 않을 수 있는 중요한 시간입니다. 해당 앱을 하루에 여러번 사용되는 경우 사용자는 앱 기동을 계속해서 기다려야 합니다. Apple은 첫 번째 프레임을 400ms 미만으로 그릴 것을 권장합니다. 이렇게 하면 Springboard의 앱 열기 애니메이션이 완료 될 때 앱을 사용할 수 있습니다. 400ms 시간 내에서 개발자는 실수로 앱 시작 시간을 늘리지 않도록 유의해야 합니다. 그러나 앱 기동은 하는 일이 너무 많아서 정확히 어떤 것이 기동 시간을 늘리는지 알기가 어렵습니다. Swift 참조 유형이 바이너리 크기와 느려진 앱 시작 시간에 어떻게 영향을 미치는지 알아보도..
[Swift] Metatype 이란? (.Type, .self, .Protocol) (번역) 이번 포스팅에서는 Metatype에 대해 정확히 알아보고자 합니다. 실제로 자주 사용해왔지만 이것이 무엇이냐 묻는다면 정확히 답변하기는 어려웠을 것입니다. 각 접미사들의 차이는 정확히 무엇인지 알아보겠습니다. Metatype 이란? 애플 문서를 살펴보면 Metatype은 타입의 타입이라고 정의되어 있습니다. String 타입의 타입? 이미 타입인데 이 타입의 타입이 있다는 것이라고 합니다. 이론적으로는 이상하게 들리지만 Swift의 쉬운 사용성을 위해 이러한 세세한 사항들을 숨기는 Swift 문법에 익숙해 졌기 때문일 수 있습니다. struct Device { static let name = "iPhone" func turnOn(name: String) {} } let myPhone: Device = D..
[Swift] defer의 동작 원리는 무엇일까? (번역) Swift2에 도입된 defer는 실제로 많이 사용되진 않습니다. 그래서 보통 defer가 어떻게 동작하고 있는지 궁금해하지 않습니다. defer는 현재 scope에서 제일 끝에서 실행되어야하는 코드를 포함하는 클로저와 함께 사용되는 연산자입니다. 함수에 return문이 많고 각 return문 앞에 동일한 코드를 복사하여 붙여 넣어야 하는 경우 유용하게 사용됩니다. 또는 스레드로부터 안전한 동작을 구현하기 위해 로직을 실행하기 전에 NSLock 객체를 lock() 하였다면, defer { lock.unlock() } 을 함께 넣으면 교착 상태에 빠지거나 메모리 누수가 발생하는 걸 방지할 수 있습니다. 함수의 끝에서 실행된다는 것은 알고 있지만 정확히 어떻게 동작되는 것인지 자세히 살펴보도록 하겠습니다. ..
[iOS] DispatchSourceTimer로 일시정지 구현이 쉬운 타이머 만들기 스택오버플로우에 일시정지와 재시작이 가능한 Timer를 구현하는 방법에 대한 질문에 Timer를 invalidate 시켰다가 새로운 Timer를 할당하는 등의 까다로운 방법들로만 답변이 달린 것을 보았습니다. 내가 본 질문과 답변들.. Pausing and Resuming a Timer in iOS Swift : Pause and Resume NSTimer 만약 DispatchSourceTimer를 알고 있더라면 좀 더 쉽게 해결가능한 문제입니다. 1초마다 시간을 출력해야 한다면 아래처럼 Timer를 만들 수 있습니다. var timer: DispatchSourceTimer? if timer == nil { // 1 timer = DispatchSource.makeTimerSource(flags: [],..
[SwiftUI] 버튼 스타일 (ButtonStyle) 만들어 쉽게 재사용하기 앱 하나에 사용하는 버튼 스타일은 보통 규격화되어 있습니다. 따라서 버튼을 추가할 때마다 해당하는 스타일 값을 일일이 세팅하게되면 매우 수고스러운 일일 것입니다. UIKit을 사용하고 있다면 UIButton 클래스를 상속받아 커스텀 클래스를 활용하여 이 문제를 해결하였을 것입니다. SwiftUI에서는 ButtonStyle 프로토콜을 채용한 구조체를 만들어 쉽게 버튼 스타일을 재사용할 수 있습니다. ButtonStyle을 적용하지 않은 Button Button(action: viewModel.refresh) { Text(viewModel.refreshButtonTitle) } .frame(width: 230, height: 45) .font(.system(size: 14)) .foregroundColor(..