본문 바로가기
반응형

기술적인 이야기/애플 플랫폼 개발48

iPhone 8 Plus 런타임이 없다? 이전에 스크린샷 문제로 아이폰 8 플러스 시뮬레이터 설치 과정을 설명한 적이 있었다. 그런데 그 이후 Xcode가 15 버전으로 업그레이드되었는데, 또 구버전용 스크린샷 생성 과정에서 쓸 iPhone 8 Plus 시뮬레이터가 목록에서 사라졌다. 일단은 침착하게 이전에 글을 썼던 방식과 동일하게 다시 추가를 시도했다. 그런데 이번에는 한 가지 문제가 더 생겼다. 설치 과정에서 런타임을 찾을 수 없다는 오류를 만나게 된 것이다. 뭔가 일시적 오류일까 싶어 다시 시도해 보려고 했는데 아래 스크린샷 처럼 OS Version 필드에서 선택할 수 있는 런타임이 아예 없었다. 중요한 사실은 iPhone 8 시리즈는 이번 iOS 17 지원 대상에서 제외되었다는 점이 있다. 그래서 최신 버전의 런타임으로는 iPhone .. 2023. 9. 27.
5.5인치 Xcode 시뮬레이터가 없을 때 애플 앱스토어에 앱을 올리기 위해서는 반드시 앱 스크린샷을 준비해서 업로드해야 한다. 이 과정에서 현재는 최소 두 종류의 스크린샷을 준비해야 하는데 하나는 가장 최신 폰의 Pro Max 같은 가장 해상도가 큰 시뮬레이터에서 스크린샷을 찍으면 쉽게 준비할 수 있다. 나머지 하나는 5.5인치용 스크린샷인데 홈 버튼이 있는 시뮬레이터 중 가장 마지막에 나온 것을 고르면 역시 쉽게 준비할 수 있는데 현시점에선 아이폰 8 플러스가 가장 적절한 대상이다. 그런데 문제가 있다면 가장 최신의 Xcode에서는 이 아이폰 8 플러스가 시뮬레이터 목록에 없다는 것이다. 물론 당황할 필요는 없다. 시뮬레이터 추가하기 시뮬레이터 디바이스를 추가하는 것은 간단하다. Xcode 메뉴에서 Window - Devices and Sim.. 2023. 9. 18.
Xcode 프로젝트 Info.plist 실종 사건 새로운 앱 프로젝트를 만들 필요가 생겨 오랜만에 Xcode에서 새로운 프로젝트를 하나 만들었다. 프로젝트를 세팅하면서 권한 설정을 해야 해서 Info.plist를 파일을 열려고 프로젝트 내비게이터를 뒤져보는데 아니 도대체 이 파일이 어디 숨은 건지 도저히 참을 수 없었다. 말 그대로 실종 사건이다. 이게 없으면 빌드도 제대로 안 될 텐데 도대체 어디로 사라진 걸까? Xcode가 13 버전으로 업그레이드된 이후 겉으로 보이는 가장 큰 변화가 있다면 프로젝트에서 항상 보이던 Info.plist 파일이 사라졌다는 것이다. 앱 이름에서 부터 장치 권한 등 여러 중요한 설정을 해야 할 이 파일이 필요 없어졌을 리는 없다. Info.plist 파일이 사라진 것은 맞다. 정확하게 말해서 Xcode 13부터 Info... 2023. 8. 16.
Objective-C에서 인터페이스 공개시키기 C 언어는 OOP 언어가 아니기 때문에 애초에 접근 제어(Access Control)와 관련된 기능이 없다. 그래서 보통은 헤더파일에 공개하기를 원하는 변수나 함수 등의 선언문을 작성해 놓고 필요한 곳에서 해당 헤더를 포함(include)시켜서 사용한다. 하지만 항상 헤더가 제공되는 법은 아니다. 만약 헤더 파일이 없다면 extern이라 불리는 키워드를 이용해 외부에서 구현된 기능을 적당히 참조하거나 호출하는 것이 가능하다. 예를 들어 아래의 코드가 있다고 치자. int globalvalue = 0; int foobar(int left, char *right) { ... } 위 코드의 인터페이스가 없더라도 아래와 같이 선언하면 위의 변수와 함수를 그대로 쓸 수 있게 된다. extern int global.. 2023. 3. 13.
Objective-C 블록 문법 블록(block)은 Objective-C에서 쓸 수 있는 동적 함수 혹은 클로저(Closure)와 비슷한 기능이다. 필요할 때 동적으로 생성될 수 있고 이름 없이도 구현할 수 있는 등 다른 여러 언어들의 클로저 개념과 상당히 유사하다. 블록이 컴파일될 때는 실제로는 함수 포인터 형식으로 변경되는 것으로 유추된다. 실제 코드에 포인터를 의미하는 * 문자가 사용되지 않지만 nil 을 가질 수 있는 등 포인터로 대체되어 컴파일되는 것 같다. 문법 꺽쇠 즉 ^ 문자가 블록을 가리키는 핵심적인 오퍼레이터다. ^{ ... } 위가 블록 문법을 알려주는 가장 기본적인 문법이지만 실제로는 아래와 같은 식의 문법을 쓰게 되는 것 같다. returntype (^name)(parameters) = ^(parameters) .. 2023. 3. 11.
WKWebView에서 Page Down 구현하기 특정 사이트나 웹 페이지를 브라우징 하는 앱을 개발하고 있자면 WKWebView를 사용하고 있을 것이다. 그런데 이 뷰의 기본 키 입력을 Local Monitor 등으로 가로채고 있다면 스페이스 키 등으로 페이지 스크롤이 동작하지 않을 수 있다. 이 경우 키 입력을 로우 레벨로 처리하게 될 텐데 수동으로 웹 뷰를 한 페이지 아래로 스크롤시킬 수 있을까? 사실 WKWebView는 스크롤뷰를 이용해 구현되어 있기 때문에 스크롤뷰의 기능을 이용해 구현할 수 있다. 하지만 구현할 코드의 양이 많고 계산식이 귀찮고 따라서 버그를 유발할 가능성이 있다. 더 쉬운 방법이 있을까? 자바스크립트를 이용하는 방법 어이없게도(?) Objective-C 코드도 아니고 Swift 코드도 아닌 Javascript 코드를 사용하는.. 2022. 5. 8.
Xcode Playground에서 Swift Package 이용하기 요즘처럼 외부 패키지를 쓸 일이 많은 상황에서 Xcode Playground는 큰 제약 사항이 있다. 외부 패키지를 import 해서 바로 쓸 수 없다는 문제다. 물론 그렇다고 아예 방법이 없는 것은 아니다. 아예 별도의 프로젝트를 하나 생성해서 여기에 Playground 및 패키지를 추가해서 쓰는 방법이 있다. 이미 답은 적었지만 아래에 조금 더 자세히 절차를 나열한다. 별도의 프로젝트 생성 원하는 플랫폼의 원하는 방식으로 프로젝트를 생성한다. 아래 스크린샷은 macOS App 프로젝트를 생성하는 화면이다. Playground 추가 이제 생성한 프로젝트에 플레이그라운드를 추가해주자. 위치는 아무 곳이나 상관없고 New File 메뉴를 이용해 생성하면 된다. 타입이 워낙 많아서 위처럼 검색해서 추가하는 .. 2022. 4. 17.
Swift에 어울리는 Objective-C 코드 작성하기 이 글은 Swift 호환성이 좋은 Objective-C 코드를 작성하는 방법에 관한 내용이다. Swift라는 언어가 워낙 쓰기 편하게 나와서 이제는 과연 얼마나 Objective-C 코드가 쓰일까 알 수 없는 요즘이다. 그래도 개인적으로는 쓸 수밖에 없는 상황이기도 하고 아직 쓰이는 곳이 분명 있으리라는 믿음으로 이런 글을 쓰게 되었다. 참고로 이 글의 핵심 키워드는 아마도 NS_SWIFT_NAME인 것 같다. C 함수 별명 Objective-C 코드로 작성한 C 함수의 인터페이스는 Swift 측에서 보면 좀 답답할 수도 있다. 예를 들어 아래 함수가 있다고 치자. int SuperGoodAdditionFeature(int a, int b) { return a + b; } 이 함수를 Swift에서 접근하.. 2022. 3. 6.
UserDefaults 기초 정리 UserDefaults는 iOS나 macOS 등 애플 플랫폼 용 앱에서 간단한 정보나 설정을 저장하고 읽어 들이기 위해 사용하는 클래스다. 데이터를 키-값(Key-Value) 스타일로 읽거나 쓸 수 있게 구성되어 있다. 해당 데이터는 각 앱의 전용 공간에 plist 형태로 저장되며 따라서 앱이 종료되어도 기록이 남아서 앱이 실행되었을 때 다시 읽을 수 있다. Swift에서는 UserDefaults라는 이름으로 사용되고 있지만 원래 이름은 NSUserDefaults이고 Objective-C 코드에서는 아직도 이 이름이 사용되고 있다. 참고로 이 글은 Swift 기준이다. 이 클래스의 레퍼런스 매뉴얼을 살펴보면 굉장히 다양한 기능을 제공하고 있지만, 보통은 .standard라는 싱글톤 객체를 이용해 저장하거.. 2021. 10. 17.
SwiftUI로 액션시트 띄우기 (iOS 15, macOS Monterey) 앞서 작성한 경고창을 띄우는 방법이 최신 SDK에서 변경된 점이 있었던 것과 비슷하게 액션시트(ActionSheet)도 최신 SDK에서 조금 바뀌었다. 그래서 바뀐 내용으로 사용법을 간략히 작성해본다. 당연하게도 Xcode 13 이상의 버전에서 개발해야 하며 iOS 15 혹은 macOS Monterey 등에서만 동작하는 내용이다. 기본 예제 iOS 14까지만 해도 .actionSheet(...) 식의 코드가 있었다. 그런데 이게 최신 SDK에서는 낡음(deprecated) 처리가 되었고 대신 .confirmationDialog(...)를 사용할 수 있게 된다. 아래는 바뀐 코드 예제다. struct ContentView: View { @State private var showingActionSheet =.. 2021. 10. 12.
SwiftUI에서 경고창(Alert Dialog) 띄우기(iOS 15, macOS Monterey) iOS 15와 macOS Monterey에서 구현할 수 있는 SwiftUI용 경고창(Alert Dialog)을 띄우는 방법이 새로 추가되었다. 새 방법이 아무래도 코드가 더 간결한 것 같아서 정리해본다. 가장 기본적인 경고창 예제 가장 기본적으로 제목과 메시지 그리고 확인 버튼 하나가 있는 경고창을 띄우는 예제 코드는 아래와 같은 식이다. struct ContentView: View { @State private var showingAlert = false var body: some View { Button("Show Alert") { showingAlert = true } .alert("Alert Title", isPresented: $showingAlert) { Button("Ok") {} } mes.. 2021. 10. 8.
SwiftUI에서 각 플랫폼의 배경색 사용하기 SwiftUI에서 색상을 지정하기 위해서는 Color라는 구조체를 사용한다. 여기에는 당연히 RGB 값을 넣어서 마음대로 색상을 만들 수 있지만 특별히 정해진 색상을 별도의 이름으로 정의해 두기도 했다. 예를 들자면 accentColor나 primary 혹은 secondary와 같은 일반적인 용도의 플랫폼 별 색상을 쉽게 사용할 수 있다. 그런데 모든 색상이 제공되는 것은 아니다. 예를 들어 윈도우의 배경색 종류가 몇 가지 있는데 이를 SwiftUI에서는 제공해 주지 않는다. 이를 위해서는 해당 플랫폼용, 즉 iOS의 경우 UIKIT 그리고 macOS의 경우 AppKit을 이용해 해당 색상을 가져오도록 코드를 작성할 수 있다. 아래와 같은 식으로 말이다. public extension Color { #i.. 2021. 10. 5.
오늘도 Xcode에게 졌다 Xcode에서 Flutter 프로젝트를 디버깅할 일이 있어서 이런저런 삽질을 하다가 아래와 같은 오류를 만났다. invalid reuse after initialization failure '초기화 실패 후 잘못된 재사용'이라는 말의 의미는 도대체 무엇일까? 원인 알 수 없다. 만약 원인을 알았다면 이번 글의 제목에 '졌다'라는 단어가 안 들어갔을 것이다. 해결 단순하게도 Command + Shift + K 키를 눌러서 프로젝트 폴더를 청소하고 나서 다시 빌드하니 문제가 해결되었다. 이 글을 왜 쓰나 왜긴 열 받아서 쓰지. 😤 솔직히 이런 말도 안 되는 오류가 최근 자주 보이는 것에서 애플에 불만이 좀 많다. 그냥 Xcode를 포기하고 터미널 기반의 개발 환경을 구축할 수 있게 해주는 편이 더 낫지 않겠나? 2021. 9. 3.
Swift 5.5의 Continuation Swift 5.5의 동시성(Concurrency) 기능의 강화로 드디어 async와 await를 사용할 수 있게 되었다. 하지만 우리가 사용하게 될 기존의 프레임워크들은 여전히 이런 연속성 구현이 빠진 형태도 많을 것이고 레거시도 종종 사용하게 될 수도 있다. 다행히도 Swift 5.5에서 이런 동시성 인터페이스를 제공하기 힘든 코드를 동시성 코드에 어울리게 쓸 수 있는 방법이 제공된다. 이름하야 연속성(Continuation)이라 불리는 방법이다. 개발자가 약간 고생해서 감싸는(wrapping) 코드를 작성해야 되겠지만 말이다. 문제가 될 만한 예제 예를 들어 아래와 같은 인터페이스의 함수를 사용해야 한다고 생각해보자. func fetchResults(name: String, completion: ([.. 2021. 7. 16.
Swift 5.5의 async/await 살펴보기 Swift는 전통적(?)으로 GCD(Grand Central Dispatch)라 불리는 병렬 프로그래밍 패러다임을 제공해왔다. 하지만 이 방식은 GCD(Grand Central Dispatch)의 Dispatch Queue를 활용한 모델로 현재로 치자면 코딩하기가 귀찮은 좀 구식인 스타일이었다. 문법만 보면 사실상 Objective-C를 위한 기능이라고 생각될 정도였으니 말이다. 어쨌든 이를 개선하기 위한 여러 요구가 있어왔다. 그리고 드디어 Swift 5.5부터 새로운 비동기 프로그래밍 패턴으로 동시성(Concurrency) 개념이 지원되면서 (이제야) async와 await 키워드가 도입되었다. 내부에서는 여전히 GCD를 사용할 수는 있겠으나 표면적으로 이제는 동시성을 이용한다고 생각하면 될 것 같다.. 2021. 7. 13.
아직은 절망스러운(?) Xcode 13 Beta의 Vim 모드 이번 WWDC21은 소프트웨어적으로는 정말 새롭고 풍부한 변화의 발표가 있었다. 물론 국내 언론 기사에는 OS가 새로 나왔다 정도만 나오고 당연히 상세한 내용이 나오진 않았지만 말이다. 어쨌든 이번 행사에서 Xcode 13도 발표되었는데 이 발표에서 직접 언급되지 않았지만 여러 사람들을 통해 알려진 신기능이 있다. 바로 Vim 모드다. Vim 모드 켜기 Xcode 13의 첫 베타 기준으로 Preferences - Text Editing - Editing 항목을 들여다보면 제일 아래에서 Enable Vim key bindings 체크박스를 발견할 수 있었다. 체크를 하게되면 이제 Vim 모드가 가동된다. 위 스크린샷의 코드 하단에 검은 네모 박스가 커서다. 아직 입력 모드로 전환하지 않은 상태라 커서가 블.. 2021. 6. 16.
728x90
반응형