본문 바로가기

분류 전체보기212

Swift: print가 값을 출력하는 방법 func print( _ items: Any..., separator: String = " ", terminator: String = "\n")print(Character("G"))print("S")print(3.14) 어떤 값이든 print를 사용하면 값이 출력된다.모든 타입의 항목을 받아 텍스트 표현으로 출력한다고 하는데,커스텀 구조체/클래스에서도 CustomStringConvertible을 채택하지 않았는데, 값이 출력되는 원리가 궁금해서 찾아봤다. print는 내부적으로 String(describing:)을 호출한 결과와 같다고 한다.그렇다면 String(describing:)은 무엇이냐? struct Point { let x: Int, y: Int}let p = Point.. 2025. 7. 13.
UIKit: Nib, Xib init(coder:)스토리보드/Nib을 통해 뷰를 로드할 때, 커스텀을 추가해서 초기화하고 싶을 때 사용 init(frame: CGRect)코드 기반으로 뷰를 로드할 때 사용하는 초기화기 ArchiveObject Graph를 저장하기 위한 방법 중 하나 XibXML Interface BuilderIB를 통해 구성한 정보를 단순 나열한 파일아무런 구조적 상호관계 없는 레코드들이 모인 파일XML 형식 NibXib가 컴파일하여 메모리에 로드할 때 사용하는 파일Object Graph가 아카이빙된 형태바이너리 형식 Object Graph뷰 요소와 같은 객체들의 관계를 나타내는 그래프 Placeholders빠져있는 요소를 연결해주는 역할 Placeholders - File's Owner앱 코드와 Nib 파일을 연.. 2025. 7. 13.
UIKit: View, View Controller Lifecycle UIKit은 뷰를 표시하기 전에 뷰 컨트롤러와 뷰를 구성할 수 있는 몇 가지 기회를 제공스토리보드에서 뷰 컨트롤러의 인스턴스를 생성하면 init(coder:) 메서드를 사용하여 해당 객체 생성 뷰 컨트롤러를 표시하는 단계(이때 뷰 컨트롤러를 사용하기 위한 일회성 설정 수행)init(coder:)으로 각 뷰 생성뷰를 뷰 컨트롤러의 액션 및 아울렛에 연결각 뷰와 뷰 컨트롤러의 awakeFromNib() 호출뷰 컨트롤러의 뷰 속성에 뷰 계층 할당뷰 컨트롤러의 viewDidLoad() 호출이때 스토리보드의 일부가 아닌 추가 뷰를 생성 및 구성 뷰가 화면에 나타날 때(이때 뷰의 레이아웃 업데이트)viewWillAppear 호출하며 전환 시작 알림계층 구조에 뷰 추가뷰 컨트롤러, 뷰의 trait collecti.. 2025. 7. 13.
Storyboard UILabel Text 줄 바꿈 스토리보드에서 Text에 줄 바꿈 하는 방법Text에 \n 삽입 시, 그대로 텍스트로 나옴\n 대신, option + enter로 줄 바꿈 가능 2025. 7. 13.
UIKit: Storyboard 검은 화면 스토리보드에서 검은 화면만 나오고, 아무런 UI도 볼 수 없는 문제해결법: DerivedData 삭제, 맥북 껏다 키기DerivedDate 위치: /Users/사용자/Library/Developer/Xcode/DerivedData 2025. 7. 13.
UIKit: Responder Chain 앱을 통해 전파되는 이벤트를 처리하는 방법앱은 responder 객체를 사용하여 이벤트를 수신/처리responder 객체는 UIResponder 클래스의 인스턴스이벤트에 응답하고 처리하기 위한 추상적인 인터페이스UIView, UIViewController, UIApplication, ...responder는 raw 이벤트 데이터를 수신하고 이벤트를 처리 혹은 다른 responder 객체로 전달앱이 이벤트를 수신하면UIKit은 해당 이벤트를 first responder라는 객체로 안내처리되지 않은 이벤트는 active responder chain에서 responder -> responder로 전달active responder chain은 responder 객체의 dynamic configuration 이미.. 2025. 7. 13.
Tuist Xcode Cloud “Command exited with non-zero exit-code: 127” tuist generate를 통해 생성된 프로젝트를 git에 반영하지 않기 때문에, xcode cloud에서는 빌드할 프로젝트를 찾지 못한다.따라서 워크플로우의 전처리 단계에서 프로젝트를 생성해 주는 과정이 필요함 이를 유연성(flexibility)을 제공한다고 하며, xcode cloud 워크플로우에는 3가지의 유연성 단계가 존재하며, 스크립트를 기반함Post-clone(ci_post_clone.sh): Xcode Cloud가 Git 레포지터리를 클론 한 후 실행하는 스크립트Pre-XcodeBuild(ci_pre_xcodebuild.sh): Xcode Cloud가 xcodebuild를 실행하기 전에 실행하는 스크립트Post-Xcodebuild(ci_post_xcodebuild.sh): Xcode Cl.. 2025. 6. 12.
Tuist Xcode Cloud에서 프로젝트 & 타겟 설정 Tuist를 도입함에 따라 기존의 Xcode Cloud 워크플로우를 사용할 수 없게 됨기존 프로젝트의 PpuDaeSik.xcodeproj를 수행 프로젝트로 지정해 둔 상태 App Store Connect - 앱 - Xcode Cloud - Workflow 경로에서 기존 프로젝트를 Tuist 프로젝트로 경로 입력 아카이브의 경우 경로 지정이 아닌 실제 타겟을 기반으로 설정해야 함 따라서, Tuist 프로젝트에서 Xcode Cloud 창을 열고, 플랫폼과 스킴을 지정하면 끝 2025. 6. 12.
Tuist 화면 잘리는 문제 Tuist 프로젝트에서 SwiftUI 앱 실행 시 아래와 같이 위아래로 잘려서 보이는 문제 plist에 launchScreen 값을 추가"UILaunchScreen": .dictionary([ "UILaunchScreen": .dictionary([:])]) 2025. 6. 12.
Tuist iPhone Orientation 설정 프로젝트의 Deployment Info - iPhone Orientation에 해당하는 앱 방향을 설정하고 싶을 때 plist에 아래 값을 추가"UISupportedInterfaceOrientations": .array([ .string("UIInterfaceOrientationPortrait")]) 2025. 6. 12.
Tuist signing for app requires a development team plist와 마찬가지로 tuist를 통해 생성된 프로젝트엔 개발자 서명이 포함되지 않는다. 따라서, 매니페스트에서 개발자 서명을 포함해줘야 하는데 단순히 개발자 계정이나 팀 명을 넣으면 당연히 인식되지 않음.개발자 인증서에 대한 정보를 넣어야 하며, 이를 위한 정보는 “키체인 접근” 앱에 포함되어 있음. 올바른 인증서를 선택하고, 인증서의 “조직 단위” 값을 사용 tuist 타깃에서 setting 값으로 “CODE_SIGN_STYLE”: “Automatic”, “DEVELOPMENT_TEAM”: “조직 단위”를 추가해 주면 반영됨 2025. 6. 12.
Tuist Plist 설정하는 방법 tuist를 통해 생성된 프로젝트에 앱 카테고리, 앱 이름, 번들 아이디 등 설정 값들이 빈 값으로 출력되는 문제.매번 프로젝트를 생성하고, 프로젝트 설정 값을 직접 입력하는 건 tuist를 쓰는 의미가 없다고 생각했기 때문에 매니페스트 단계에서 값을 주입해 주기로 결정. 설정 값과 plist 값이 있는데, 기존 프로젝트의 값을 재사용하기로 함두 가지 경로에서 값을 추출했는데, 설정은 프로젝트의 xcworkspace, plist는 빌드 데이터의 info.plist를 사용해 매니페스트에 작성 2025. 6. 12.
Tuist Font & 이미지 미적용 문제 Tuist로 모듈화를 진행하면서 폰트와 이미지 같은 공유 에셋은 Shared 모듈을 통해 관리하도록 구성.그런데, 앱을 실행해 보니 폰트가 적용되지 않는 것을 발견3:51 → 기존 프로젝트3:54 → 모듈화 후 프로젝트 모듈을 살펴보니 Derived - Sources 폴더에 에셋에 대한 코드가 존재해서 기존 폰트와 이미지 같은 에셋 코드를 해당 코드로 변경 후 해결 2025. 6. 12.
GitHub Actions 빌드 에러 65 아래 스크립트에서 “Process completed with exit code 65.” 발생 name: iOS Build Teston: push: branches: [ "development" ] pull_request: branches: [ "development" ]jobs: build: name: Build and analyse default scheme using xcodebuild command runs-on: macos-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set Default Scheme run: | scheme_list=.. 2025. 6. 12.
운영체제 참고면접을 위한 CS 전공지식 노트 https://www.gilbut.co.kr/book/view?bookcode=BN003386 운영체제, OS, Operating System사용자가 컴퓨터를 쉽게 다루게 해주는 인터페이스 운영체제와 컴퓨터운영체제의 역할CPU 스케줄링 및 프로세스 관리, 메모리 관리, 디스크 파일 관리, I/O 디바이스 관리 CPU 스케줄링 및 프로세스 관리: CPU 소유권을 어떤 프로세스에 할당할지, 프로세스의 생성 및 삭제, 자원 할당 및 반환 관리메모리 관리: 메로리를 어떤 프로세스에 얼마나 할당할지 관리디스크 파일 관리: 디스크 파일을 어떠한 방법으로 보관할지 관리I/O 디바이스 관리: 마우스, 키보드와 같은 컴퓨터 간 데이터를 주고받는 것 관리 운영체제의 구조유저 프로그램 -.. 2025. 5. 2.
네트워크 참고면접을 위한 CS 전공지식 노트 https://www.gilbut.co.kr/book/view?bookcode=BN003386 네트워크컴퓨터 등의 장치들이 통신 기술을 이용하여 구축하는 연결망을 지칭하는 용어 네트워크 기초네트워크란 노드와 링크가 서로 연결되어 있으며, 리소스를 공유하는 집합노드란 네트워크 장치, 링크란 유무선 연결 처리량, 지연 시간처리량(throughput)은 링크 내에서 성공적으로 전달된 데이터의 양. 보통 얼마큼의 트래픽을 처리했는지를 나타냄bps(bits per second)를 단위로 사용.트래픽은 특정 시점에 링크 내에 흐르는 데이터의 양지연 시간(latency)은 요청이 처리되는 시간 네트워크 토폴로지네트워크 토폴로지(network topology)란 노드와 링크가 배치되.. 2025. 4. 29.
디자인 패턴, 프로그래밍 패러다임 참고면접을 위한 CS 전공지식 노트: https://www.gilbut.co.kr/book/view?bookcode=BN003386 디자인 패턴, Design Pattern프로그램을 설계할 때 발생하는 특정 문제점을 해결하기 위한 특정 패턴 싱글톤 패턴, Singleton Pattern하나의 클래스는 하나의 인스턴스만 가지는 패턴하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어 이를 기반한 로직을 만들 때 사용하나의 인스턴스를 다른 모듈들이 공유해 사용하기 때문에 인스턴스 생성 비용이 줄어들지만 의존성이 높아짐 싱글톤 패턴 단점TDD에서 사용하기 어려움TDD는 단위 테스트를 진행하는 데, 단위 테스트는 각자 독립적이어야 한다.하지만 싱글톤 패턴은 하나의 인스턴스를 가지므로 각 테스트마다 독립적인 인스.. 2025. 4. 27.
주니어 iOS 개발자 Swift 면접 질문 1. Swift에서 옵셔널이란 무엇인가? 옵셔널을 안전하게 다루려면 어떻게 해야 하는가?옵셔널이란 변수가 값을 가지거나, 아무런 값(nil)도 가지지 않는 Swift의 기능 var name: String? = "John" // 옵셔널 스트링name = nil // name은 nil 안전하게 다루기 위한 방법: 옵셔널 바인딩(Optional Binding), 가드문(Guard Statement), Nil-결합 연산자(Nil-Coalescing) // 옵셔널 바인딩(Optional Binding)if let unwrappedName = name { print(unwrappedName)}// 가드문(Guard Statement)func greet(_ name: String?) { guard let.. 2025. 4. 23.
파이썬 알고리즘 문법 컴파일 타임에 변수 이름 잘못 넣어도 추론 안됨elif last_four_words == "infl": print("Orthopedics")elif last_for_words == "skin":  주석# 123asdasd 연산# 반올림round(0.7) # 1round(123.456, 2) # 123.46# 나누기2 / 3 # 0.6666666666666666# 나머지2 % 3 # 2# 몫2 // 3 # 0# 제곱2 ** 3 # 8# 삼항 연산True if x % 2 == 0 else False# or, 하나라도 True면 Trueany([True, False, False]) # True# and, 모두 True여야 Trueall([False, False, False]) # False 함수 정의de.. 2025. 3. 30.
Swift: add, adds, append, appends 속도 비교 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]을 배열에 더하는 연산을 다중 add, adds, 다중 append, appends로 각각 수행할 때의 속도 비교다중 add를 제외하면 평이하며, 다중 add의 경우 n이 100000000 일 때, 다른 API에 비해 3배의 속도 차이가 발생  import SwiftUIfunc measure(label: String, repeatCount: Int, function: () -> ()) { let time = ContinuousClock().measure { for _ in 1...repeatCount { function() } } print(label, ":", time)}struct ContentView: View { @State .. 2025. 3. 30.
Swift: add, append 속도 비교 n이 커질 수록 append가 속도 면에서 더 빨라지는 추세  import SwiftUIstruct ContentView: View { @State var count = 1 var body: some View { VStack { Button("count up") { count *= 10 } Button("act") { print("count:", count) DispatchQueue.global(qos: .default).async { var array1: [Int] = [] .. 2025. 3. 30.
Swift: if let, guard let 속도 비교 유의미한 차이는 없음  struct ContentView: View { @State var count = 1 var body: some View { VStack { Button("count up") { count *= 10 } Button("act") { print("count:", count) DispatchQueue.global(qos: .default).async { let time1 = ContinuousClock().measure { for _ in 1...co.. 2025. 3. 30.
Swift: async let 수행 순서 async let의 수행 순서는 await 순서에 따름func function(_ name: String, _ i: Int) async -> Int { print("sleep: ", name, i) sleep(UInt32(i)) print("wake up: ", name, i) return i}async let a = function("a", 10)async let b = function("b", 3)async let c = function("c", 2)async let d = function("d", 5)async let e = function("e", 3)async let f = function("f", 5)async let g = function("g", 3)async let .. 2025. 3. 30.
Swift 알고리즘 관련 문법 조건 splitlet str = "abd124kbksbjb62".split { !$0.isNumber }print(str) // ["124", "62"] dict 필터let s = [1, 2, 2, 3, 3, 3, 4, 4, 4]let dict = Dictionary(grouping: Array(s).map(String.init), by: { $0 }).filter { $0.value.count > 1 }print(dict) // ["3": ["3", "3", "3"], "2": ["2", "2"], "4": ["4", "4", "4"]] 여러 조건 splitlet str = "nabcvcvacbacac".split { $0 == "a" || $0 == "b" || $0 == "c" }.map { Str.. 2025. 3. 30.