<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>MungGu Story</title>
    <link>https://0urtrees.tistory.com/</link>
    <description>안녕하세요, 개발자 멍구의 이야기입니다.  </description>
    <language>ko</language>
    <pubDate>Fri, 3 Jul 2026 03:02:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>applebuddy</managingEditor>
    <image>
      <title>MungGu Story</title>
      <url>https://tistory1.daumcdn.net/tistory/2837849/attach/52a6ec3f59b64df3b4270e7be6d8ce6c</url>
      <link>https://0urtrees.tistory.com</link>
    </image>
    <item>
      <title>Swift Concurrency, Task와 GCD: QoS 우선순위 설정 사용 방법</title>
      <link>https://0urtrees.tistory.com/450</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;iOS환경에서 비동기 작업을 관리하는 두 가지 핵심 기술이 있는데요. &lt;b&gt;GCD(Grand Central Dispatch)&lt;/b&gt;와 &lt;b&gt;Swift Concurrency의 작업단위인 &lt;code&gt;Task&lt;/code&gt;입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이들은 내부적으로 QoS(Quality of Service)&lt;/b&gt;라는 통일된 시스템을 사용하여 작업의 우선순위를 관리하는데요. 오늘은 이 QoS에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Task와 GCD의 우선순위 연관 관계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GCD와 &lt;code&gt;Task&lt;/code&gt; 모두 &lt;b&gt;QoS(Quality of Service)&lt;/b&gt;를 통해 시스템에 작업의 중요도를 알립니다. GCD의 DispatchQueue와 Swift Concurrency의 Task를 사용할때 시스템은 설정된 QoS 정보를 기반으로 스레드 풀에서 작업을 스케줄링하고, 필요한 CPU 및 리소스 할당을 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 작업의 특징에 따라서 바로 동작해야하거나, 중요도가 후순위인 경우가 있을텐데, 이러한 작업 성격에 맞게 작업을 실행하고자 할때 사용할 수 있습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;b&gt;기술&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;우선순위 설정 방식&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;내부 처리 원리&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;GCD (DispatchQueue)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;qos 매개변수에 &lt;code&gt;DispatchQoS.QoSClass&lt;/code&gt; (예: &lt;code&gt;.userInitiated&lt;/code&gt;, &lt;code&gt;.background&lt;/code&gt;)를 큐에 직접 지정합니다.&lt;/td&gt;
&lt;td&gt;해당 QoS로 태그된 스레드에서 작업이 실행됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Task (Swift Concurrency)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Task&lt;/code&gt; 초기화 시 &lt;code&gt;priority&lt;/code&gt; 매개변수로 TaskPriority (예: &lt;code&gt;.userInitiated&lt;/code&gt;, &lt;code&gt;.background&lt;/code&gt;)를 지정해서 사용합니다.&lt;/td&gt;
&lt;td&gt;지정된 QoS를 기반으로 GCD의 스레드에서 작업을 실행합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;연관 관계:&lt;/b&gt; &lt;code&gt;Task&lt;/code&gt;의 &lt;code&gt;priority&lt;/code&gt;는 내부적으로 &lt;b&gt;GCD의 QoS Class에 매핑&lt;/b&gt;되어 동일한 스케줄링 시스템을 사용합니다. 즉, 새로운 &lt;code&gt;Task&lt;/code&gt; 시스템도 기존의 GCD 인프라를 활용하여 우선순위를 처리합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;Task, GCD DispatchQueue QoS 사용 예시&lt;/h5&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Task(priority: .medium) { // .default도 사용 가능하나, deprecated case로 .medium 으로 대체
  // do something
}

DispatchQueue.global(qos: .default).async {
  // do something
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. QoS (Quality of Service) Class 특징 및 사용 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QoS 클래스는 총 6가지가 있으며, 각각의 특징과 적절한 사용 예시는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;QoS관련 Task 특이사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.userInteractive 옵션 deprecated&lt;/li&gt;
&lt;li&gt;.default 옵션 -&amp;gt; .medium 으로 rename&lt;/li&gt;
&lt;li&gt;.unspecified 옵션 deprecated -&amp;gt; 옵션 미지정 혹은 QoS 를 nil로 지정하는것을 권장합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Task { ... } 처럼 옵션 미지정 시 기본으로 지정되는 옵션입니다. unstructured concurrency 방식으로 Task 중첩 등이 있을때 작업 취소 전파가 되지 않으니 사용에 유의해야합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;b&gt;QoS Class&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;특징 및 중요도&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;CPU 스케줄링&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;사용 예시&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.userInteractive&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;최고 중요도&lt;/b&gt; 작업에 사용합니다. 사용자가 &lt;b&gt;즉각적인 반응&lt;/b&gt;을 기대하는 작업에 사용할 수 있는 QoS입니다.&lt;/td&gt;
&lt;td&gt;높은 우선순위. 메인 스레드에 자주 사용됨.&lt;/td&gt;
&lt;td&gt;애니메이션, 이벤트 처리, UI 새로고침, 사용자 입력에 대한 즉각적인 피드백.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;높은 중요도.&lt;/b&gt; 사용자가 결과를 &lt;b&gt;즉시 기대&lt;/b&gt;하며, 결과를 기다리는 동안 UI가 차단될 수 있는 작업.&lt;/td&gt;
&lt;td&gt;높은 우선순위. 사용자 인터페이스와 직접적으로 관련됨.&lt;/td&gt;
&lt;td&gt;&quot;저장&quot; 버튼 클릭 후 데이터 저장, 문서 로딩, 사용자가 시작한 데이터 가져오기.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.default&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;중간 중요도.&lt;/b&gt; QoS가 명시적으로 지정되지 않은 대부분의 작업에 사용되는 기본값. (시스템이 적절히 조절)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.userInitiated&lt;/code&gt;와 &lt;code&gt;.utility&lt;/code&gt; 사이의 우선순위를 가집니다.&lt;/td&gt;
&lt;td&gt;우선순위를 명확히 설정하지 않을 때 사용. 대부분의 일반 비동기 작업.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;중간/낮은 중요도.&lt;/b&gt; 시간이 걸릴 수 있지만 &lt;b&gt;즉각적인 응답이 필요 없는&lt;/b&gt; 작업. 진행 표시줄 등을 제공함.&lt;/td&gt;
&lt;td&gt;낮은 우선순위. 에너지 효율을 위해 설계됨.&lt;/td&gt;
&lt;td&gt;긴 네트워크 요청, 데이터 다운로드, 이미지 필터링, 사용자에게 보이지 않는 백업.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.background&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;최저 중요도.&lt;/b&gt; 사용자에게 &lt;b&gt;보이지 않으며&lt;/b&gt; 시간 제약이 거의 없는 작업. 리소스 경합을 피하기 위해 최저 우선순위로 실행됨.&lt;/td&gt;
&lt;td&gt;가장 낮은 우선순위. 주로 I/O 및 유지보수 작업에 사용.&lt;/td&gt;
&lt;td&gt;데이터베이스 정리, 로그 업로드, 사전 로드(Prefetching), 인덱싱.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;code&gt;.unspecified&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;시스템이 가장 적절한 QoS를 추론하도록 맡기는 경우. (주로 레거시 코드 호환성)&lt;/td&gt;
&lt;td&gt;시스템 추론에 따름.&lt;/td&gt;
&lt;td&gt;명확한 QoS가 필요 없거나 시스템에 맡길 때.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Task 및 GCD 사용 예시 코드&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-1. Task에서 QoS 사용 (iOS 13+ / Swift Concurrency)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Task&lt;/code&gt;를 생성할 때 &lt;code&gt;priority&lt;/code&gt; 파라미터를 지정해서 사용합니다. &lt;code&gt;priority&lt;/code&gt; 미지정 시, default로 .unspecified 옵션이 지정됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-01 오후 7.42.20.png&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AaYq4/dJMb99ScT9c/5Di5EUkHKAC2GOTNTcMKx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AaYq4/dJMb99ScT9c/5Di5EUkHKAC2GOTNTcMKx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AaYq4/dJMb99ScT9c/5Di5EUkHKAC2GOTNTcMKx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAaYq4%2FdJMb99ScT9c%2F5Di5EUkHKAC2GOTNTcMKx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1258&quot; height=&quot;262&quot; data-filename=&quot;스크린샷 2025-11-01 오후 7.42.20.png&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;//   사용자에게 즉시 결과를 보여줘야 하는 중요한 작업
Task(priority: .userInitiated) {
    print(&quot;User Initiated Task: 데이터 로딩 시작&quot;)
    // 데이터를 서버에서 즉시 가져오는 비동기 함수 호출
    await loadImportantData() 
    print(&quot;User Initiated Task: 데이터 로딩 완료&quot;)
}

//   백그라운드에서 실행되어도 무방하며, 배터리 효율이 중요한 작업
Task(priority: .background) {
    print(&quot;Background Task: 로깅 및 정리 작업 시작&quot;)
    // 로그 파일 정리, 캐시 삭제 등 시간이 오래 걸려도 되는 작업
    await cleanUpLogs()
    print(&quot;Background Task: 로깅 및 정리 작업 완료&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2. GCD에서 QoS 사용 (Legacy 방식)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GCD 방식의 경우 &lt;code&gt;DispatchQueue.global&lt;/code&gt;에 &lt;code&gt;qos&lt;/code&gt; 파라미터를 사용하여 우선순위를 지정합니다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;// 중간 우선순위 작업 (예: 오래 걸리는 이미지 처리)
DispatchQueue.global(qos: .utility).async {
    print(&quot;Utility Queue: 이미지 프로세싱 시작&quot;)
    // ... 이미지 필터링 코드 ...

    // UI 업데이트는 thread-safe 하지 않으므로 반드시 .userInteractive (main) 큐에서 수행해야합니다.
    DispatchQueue.main.async { 
        print(&quot;Utility Queue: UI 업데이트 완료&quot;)
        // self.imageView.image = processedImage
    }
}

// 메인 스레드와 동일한 최고 우선순위 (시스템이 즉각 반응하도록 보장)
DispatchQueue.global(qos: .userInteractive).async {
    print(&quot;User Interactive Queue: 탭 이벤트 처리 시작&quot;)
    // 작은 계산을 빠르게 처리
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Task와 GCD를 사용할때 &lt;b&gt;작업의 중요도에 맞는 적절한 QoS를 설정하는 것이 가장 중요&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;.userInteractive&lt;/code&gt;&lt;/b&gt;, &lt;b&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;/b&gt;는 꼭 필요한 곳(UI 관련)에만 사용하고, 장시간 소요되는 작업은 &lt;b&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;/b&gt;나 &lt;b&gt;&lt;code&gt;.background&lt;/code&gt;&lt;/b&gt;를 사용하여 작업 중요도를 지정하고 시스템 리소스를 효율적으로 관리할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>GCD QoS</category>
      <category>iOS QoS</category>
      <category>iOS 비동기 QoS</category>
      <category>swift concurrency</category>
      <category>swift qos</category>
      <category>swift Task QoS</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/450</guid>
      <comments>https://0urtrees.tistory.com/450#entry450comment</comments>
      <pubDate>Sat, 1 Nov 2025 19:42:46 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode DP 문제, House Robber Swift 알고리즘 풀이</title>
      <link>https://0urtrees.tistory.com/449</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제 링크:&lt;/b&gt; &lt;a href=&quot;https://leetcode.com/problems/house-robber/&quot;&gt;LeetCode 198. House Robber&lt;/a&gt;&lt;br /&gt;&lt;b&gt;유형:&lt;/b&gt; Dynamic Programming (DP)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도둑이 일렬로 늘어선 집들을 털려고 합니다.&lt;br /&gt;단, &lt;b&gt;인접한 두 집을 동시에 털 수는 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 집마다 돈의 양이 담긴 배열 &lt;code&gt;nums&lt;/code&gt;가 주어졌을 때,&lt;br /&gt;도둑이 털 수 있는 &lt;b&gt;최대 금액을 반환해야합니다!&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  예시&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Input: nums = [2,7,9,3,1]
Output: 12
// 2 + 9 + 1 = 12&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  접근 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 전형적인 &lt;b&gt;Dynamic Programming(DP)&lt;/b&gt; 문제입니다.&lt;br /&gt;핵심은 &lt;b&gt;현재 집을 털지, 건너뛸지 선택하는 것&lt;/b&gt;인데요. 이를 점화식으로 정리해서 해결할 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;점화식 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;dp[i]&lt;/code&gt; = &lt;b&gt;0번째부터 i번째 집까지 털었을 때 얻을 수 있는 최대 금액&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 점화식에 활용되는 2가지 케이스는 아래와 같아요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-31 오전 1.13.16.png&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z1eCX/dJMb99YXZYf/Pj8FtuSmlRevKXrNXTEmaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z1eCX/dJMb99YXZYf/Pj8FtuSmlRevKXrNXTEmaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z1eCX/dJMb99YXZYf/Pj8FtuSmlRevKXrNXTEmaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ1eCX%2FdJMb99YXZYf%2FPj8FtuSmlRevKXrNXTEmaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1398&quot; height=&quot;340&quot; data-filename=&quot;스크린샷 2025-10-31 오전 1.13.16.png&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;i번째 집을 털지 않는다.&lt;/b&gt;&lt;br /&gt;&amp;rarr; 이전까지의 최대 금액은 그대로 유지된다 &amp;rarr; &lt;code&gt;dp[i-1]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;i번째 집을 턴다.&lt;/b&gt;&lt;br /&gt;&amp;rarr; i-1번째는 털 수 없으므로, &lt;code&gt;dp[i-2] + nums[i]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;점화식은 다음과 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;dp[i] = max(dp[i-1], dp[i-2] + nums[i])&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;구현 코드 (Swift)&lt;/h2&gt;
&lt;pre class=&quot;swift&quot;&gt;&lt;code&gt;class Solution {
    /// DP 를 활용해서 문제를 해결합니다. 
    /// dp[i] = 0...i 까지의 집에서 얻을 수 있는 최댓값
    func rob(_ nums: [Int]) -&amp;gt; Int {
        // 1) 집이 단 한개면 그 집의 돈만 털면 됩니다.
        if nums.count == 1 {
            return nums[0]
        }

        // 2) 집이 두개면 둘 중 돈 더 많은 곳을 털면 됩니다.
        if nums.count == 2 {
            return nums.max()!
        }

        // 3) dp는 0~i번째 집까지 털었을대 얻을 수 있는 최대 금액이 들어갑니다.
        var dp = [Int](repeating: 0, count: nums.count)

        // 3-1) 0, 1번째 케이스 최댓값을 미리 넣고,
        dp[0] = nums[0]
        dp[1] = nums[...1].max()!

        // 3-2) 점화식 적용
        for i in 2..&amp;lt;nums.count {
            dp[i] = max(dp[i-1], nums[i] + dp[i-2])
        }

        return dp.last!
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예시 시뮬레이션&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;nums = [2, 7, 9, 3, 1]&lt;/code&gt;&lt;/pre&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;i&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;nums[i]&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;dp[i] 계산식&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;dp[i] 값&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;7&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;max(2, 7)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;9&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;max(7, 9+2=11)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;max(11, 3+7=10)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;max(11, 1+11=12)&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 결과: &lt;b&gt;12&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시간 및 공간 복잡도&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;구분&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;복잡도&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;시간 복잡도&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;O(n)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;모든 집을 한 번씩 탐색&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;공간 복잡도&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;O(n)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;DP 배열 사용 (공간 최적화 시 O(1) 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;+ 공간 최적화 버전&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;dp[i]&lt;/code&gt;는 &lt;code&gt;dp[i-1]&lt;/code&gt;과 &lt;code&gt;dp[i-2]&lt;/code&gt;만 참조하므로,&lt;br /&gt;배열 대신 두 변수로 관리할 수도 있습니다. 이렇게 되면 공간복잡도를 O(1) 상수복잡도로 처리할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;swift&quot;&gt;&lt;code&gt;func rob(_ nums: [Int]) -&amp;gt; Int {
    if nums.count == 1 { return nums[0] }

    var prev2 = nums[0]
    var prev1 = max(nums[0], nums[1])

    for i in 2..&amp;lt;nums.count {
        let current = max(prev1, prev2 + nums[i])
        prev2 = prev1
        prev1 = current
    }

    return prev1
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✨ 마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 &lt;b&gt;DP의 핵심 개념을 명확하게 연습하기 좋은 대표 문제&lt;/b&gt;였습니다.&lt;br /&gt;&amp;ldquo;&lt;b&gt;현재 최적의 선택은 이전 두 상태의 최적해로부터 결정된다&lt;/b&gt;&amp;rdquo;는 원리를 잘 활용해야했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP문제는 평소 풀지 않으면 점화식이 생각나더라도 풀기 어려운 경우가 있기때문에 꾸준한 연습이 필요합니다.&lt;br /&gt;지금까지 릿코드의 House Robber DP swift 언어 기반 알고리즘 풀이였습니다. 감사합니다!&lt;/p&gt;</description>
      <category>알고리즘 정보/Swift 알고리즘</category>
      <category>DP Algorithm</category>
      <category>DP 알고리즘</category>
      <category>dp 점화식</category>
      <category>Dynamic Programming</category>
      <category>House Robber</category>
      <category>leetcode swift</category>
      <category>swift DP</category>
      <category>다이나믹프로그래밍</category>
      <category>릿코드 swift</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/449</guid>
      <comments>https://0urtrees.tistory.com/449#entry449comment</comments>
      <pubDate>Fri, 31 Oct 2025 09:17:07 +0900</pubDate>
    </item>
    <item>
      <title>Swift Structured Concurrency, 비동기 작업 간 취소 전파 제어방법</title>
      <link>https://0urtrees.tistory.com/448</link>
      <description>&lt;h1&gt;Swift Concurrency의 핵심: Structured Concurrency로 안전한 비동기 작업 제어하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swift Concurrency를 활용하여 비동기 처리를 구현하고 계시다면, &lt;b&gt;Structured Concurrency(구조화된 동시성)&lt;/b&gt; 형태로 작업을 구성하는 것이 강력하게 권장됩니다. 왜냐하면 이는 &lt;b&gt;작업 간의 부모/자식 관계&lt;/b&gt;를 명시적으로 설정하여, 복잡한 비동기 작업을 &lt;b&gt;예측 가능하고 유연하게 제어&lt;/b&gt;할 수 있게 하기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 이 원칙의 가장 큰 장점인 &lt;b&gt;'취소(Cancellation) 전파'&lt;/b&gt; 기능을, 중첩된 Task 작업이 있는 상황을 가정해서 코드 작성해보며 실험해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;playground 에서 emtpy project를 생성해서 swift concurrency 기반 코드 작성 및 테스트를 해보실 수 있습니다!&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Unstructured Concurrency: 취소 신호가 멈추는 곳&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Task { ... }&lt;/code&gt; 블록 내에서 새로운 &lt;code&gt;Task { ... }&lt;/code&gt;를 생성하는 방식은 &lt;b&gt;Unstructured Concurrency (비구조화된 동시성)&lt;/b&gt;의 대표적인 예입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 생성된 &lt;code&gt;Task&lt;/code&gt;는 바깥 &lt;code&gt;Task&lt;/code&gt;의 컨텍스트(예: &lt;code&gt;actor&lt;/code&gt; 컨텍스트)는 물려받을 수 있지만, &lt;b&gt;별도의 최상위 비동기 작업&lt;/b&gt;으로 간주됩니다. 이 때문에 부모 &lt;code&gt;Task&lt;/code&gt;의 취소 신호가 자식 &lt;code&gt;Task&lt;/code&gt;로 &lt;b&gt;자동으로 전파되지 않습니다.&lt;/b&gt; 이 방식은 세부 비동기 작업의 생명 주기 제어가 어렵다는 명확한 단점을 가집니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실험 1: 취소 전파 실패 (Unstructured Task)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.29.51.png&quot; data-origin-width=&quot;1912&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1MMhM/dJMcacOVlMa/Frr9e9f4HF2cOzM04Hbev0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1MMhM/dJMcacOVlMa/Frr9e9f4HF2cOzM04Hbev0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1MMhM/dJMcacOVlMa/Frr9e9f4HF2cOzM04Hbev0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1MMhM%2FdJMcacOVlMa%2FFrr9e9f4HF2cOzM04Hbev0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1912&quot; height=&quot;668&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.29.51.png&quot; data-origin-width=&quot;1912&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// outerTask와 innerTask는 별도의 최상위 비동기 작업으로 간주됩니다.
let outerTaskWithUnstructuredConcurrency = Task {
    // ⚠️ 이 innerTask는 outerTask와 독립적인 별도의 Task입니다.
    let innerTask = Task {
        for num in 1...5 {
            // Task.sleep은 취소 가능 지점입니다.
            try? await Task.sleep(for: .seconds(1))
            try Task.checkCancellation() 
            debugPrint(&quot;inner task \(num) 초 with unstructured concurrency&quot;)
        }
    }

    do {
        // innerTask의 완료를 기다립니다. (innerTask의 value를 await)
        try await innerTask.value 
    } catch is CancellationError {
        // 이 catch는 innerTask 내부의 오류가 아닌,
        // outerTask 내부에서 발생한 CancellationError만 잡습니다.
        debugPrint(&quot;inner task cancelled with unstructured concurrency&quot;) 
    }
}
// outerTask 취소 신호가 innerTask로 전달되지 않습니다.
outerTaskWithUnstructuredConcurrency.cancel()

//   출력 결과 (취소 신호를 무시하고 5초까지 완료)
// &quot;inner task 1 초 with unstructured concurrency&quot;
// ...
// &quot;inner task 5 초 with unstructured concurrency&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Structured Concurrency: TaskGroup을 통한 안전한 제어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;TaskGroup&lt;/code&gt;은 Swift Concurrency의 Structured Concurrency 개념 중 하나입니다. &lt;code&gt;withTaskGroup&lt;/code&gt;이나 &lt;code&gt;withThrowingTaskGroup&lt;/code&gt;을 사용하면 &lt;b&gt;명시적인 부모-자식 관계&lt;/b&gt;가 형성되어, 부모 &lt;code&gt;Task&lt;/code&gt;의 생명 주기가 자식 &lt;code&gt;Task&lt;/code&gt;의 생명 주기와 강하게 연결됩니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실험 2: 취소 전파 성공 (Structured TaskGroup)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.30.03.png&quot; data-origin-width=&quot;1988&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAAKdo/dJMcahiouKm/SezMTKh2e8Mf91qHw3rabK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAAKdo/dJMcahiouKm/SezMTKh2e8Mf91qHw3rabK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAAKdo/dJMcahiouKm/SezMTKh2e8Mf91qHw3rabK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAAKdo%2FdJMcahiouKm%2FSezMTKh2e8Mf91qHw3rabK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1988&quot; height=&quot;1018&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.30.03.png&quot; data-origin-width=&quot;1988&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;func sampleTaskGroup() async throws {
    // withThrowingTaskGroup: 이 블록 내의 모든 Task는 부모 Task의 자식이 됩니다.
    try await withThrowingTaskGroup(of: Void.self) { group in

        // group.addTask: 자식 Task를 생성하여 그룹에 추가합니다.
        group.addTask {
            for num in 1...5 {
                try await Task.sleep(for: .seconds(1))
                // 부모 Task가 취소되면 여기서 CancellationError가 발생합니다.
                try Task.checkCancellation() 
                debugPrint(&quot;inner task \(num) 초 with structured concurrency&quot;)
            }
        }

        // 부모 Task가 자식들의 완료를 기다리도록 보장합니다.
        for try await _ in group { } 
    }
}

let outerTaskWithStructuredConcurrency = Task {
    do {
        // sampleTaskGroup을 호출함으로써 부모 Task와 자식 TaskGroup 간의 관계가 형성됩니다.
        try await sampleTaskGroup() 

    } catch is CancellationError {
        // outerTask가 취소되면, sampleTaskGroup이 CancellationError를 던지고 이 곳에서 포착됩니다.
        debugPrint(&quot;inner task cancelled with structured concurrency&quot;)
    } catch {
        debugPrint(&quot;other error : \(error) with structured concurrency&quot;)
    }
}
// outerTask 취소 신호가 TaskGroup을 통해 innerTask로 전파됩니다.
outerTaskWithStructuredConcurrency.cancel()

//   출력 결과 (취소 신호 감지 후 즉시 종료)
// (1초 경과 로그 후)
// &quot;inner task cancelled with structured concurrency&quot; &lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론 및 활용&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.30.11.png&quot; data-origin-width=&quot;1624&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ySCYI/dJMcagw1ntF/Emg6vJw12hZAyVEeK6y5ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ySCYI/dJMcagw1ntF/Emg6vJw12hZAyVEeK6y5ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ySCYI/dJMcagw1ntF/Emg6vJw12hZAyVEeK6y5ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FySCYI%2FdJMcagw1ntF%2FEmg6vJw12hZAyVEeK6y5ek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1624&quot; height=&quot;426&quot; data-filename=&quot;스크린샷 2025-10-31 오전 12.30.11.png&quot; data-origin-width=&quot;1624&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 중첩 비동기 작업이 존재할때의 swift concurrency 사용예시를 몇가지 작성 및 실험해봤습니다. 한번 더 내용을 정리해보자면...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TaskGroup&lt;/b&gt;, &lt;b&gt;async let&lt;/b&gt;, &lt;b&gt;AsyncStream&lt;/b&gt; 등의 Structured Concurrency 도구들은 비동기 작업에 명확한 계층 구조를 부여하여 다음을 가능하게 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;안전한 취소&lt;/b&gt;: 부모가 취소되면 관련된 모든 자식 작업이 자동으로 정리됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;쉬운 에러 핸들링&lt;/b&gt;: 자식 Task에서 발생한 오류는 부모 Task로 명확하게 전달됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swift Concurrency의 작업이 복잡해질 때, 단순 &lt;code&gt;Task { ... }&lt;/code&gt; 대신 &lt;code&gt;TaskGroup&lt;/code&gt;과 &lt;code&gt;async let&lt;/code&gt;을 활용하는 것이 &lt;b&gt;코드를 더 예측 가능하고 안정적&lt;/b&gt;으로 만드는 핵심 비결입니다.&lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>iOS 비동기 작업</category>
      <category>iOS 취소 전파</category>
      <category>structured concurrency</category>
      <category>swift concurrency</category>
      <category>swift taskGroup</category>
      <category>TaskGroup</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/448</guid>
      <comments>https://0urtrees.tistory.com/448#entry448comment</comments>
      <pubDate>Fri, 31 Oct 2025 00:31:10 +0900</pubDate>
    </item>
    <item>
      <title>iOS 개발, Cocoa Touch 개념 및 UIKit, Foundation과의 관계</title>
      <link>https://0urtrees.tistory.com/447</link>
      <description>&lt;p&gt;안녕하세요, iOS 개발자 여러분~! 오늘은 iOS 앱의 근간을 이루는 핵심 계층으로, &lt;strong&gt;Cocoa Touch&lt;/strong&gt;라는 개념이있는데요.&lt;br&gt;개발을 하다보면 자주 사용하게 되는 UIKit, Foundation 등의 프레임워크와도 연관이 깊습니다. 오늘은 이것들에 대해서 얘기해봐요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Cocoa Touch: iOS 앱을 만드는 모든 것의 시작&lt;/h2&gt;
&lt;p&gt;가장 먼저, Cocoa Touch가 무엇인지부터 확실히 짚고 넘어가죠. 간단하게 말해, &lt;strong&gt;Cocoa Touch는 iOS 앱을 개발하는 데 필요한 대부분의 도구와 기술을 모아놓은 최상위 프레임워크, 최상위 계층&lt;/strong&gt;입니다. 우리가 만드는 앱의 화면(UI), 사용자와의 상호작용, 데이터 관리 등 앱의 생명주기 전반을 관리하는 강력한 기반이 되는 개념입니다.&lt;/p&gt;
&lt;p&gt;Mac OS 앱을 만들때에는 Cocoa 프레임워크를 사용하는데요. 터치 기반의 인터페이스에 맞게 변형 및 최적화 된 버전이 바로 Cocoa Touch 프레임워크입니다.&lt;/p&gt;
&lt;p&gt;Cocoa Touch안에는 각자의 역할을 담당하는 여러 하위 프레임워크들이 유기적으로 얽혀서 동작하고 있습니다. Foundation, UIKit, MapKit 등 다양한 프레임워크들이 말이지요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Cocoa Touch와 하위 프레임워크들의 관계&lt;/h2&gt;
&lt;p&gt;Cocoa Touch라는 개념 아래로 iOS개발에 사용되는 다양한 프레임워크들이 존재합니다. 대표적인 것들만 봐도 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UIKit&lt;/strong&gt;: 사용자 인터페이스(UI)를 만들고 관리하는 모든 것을 담당합니다. UIButton, UILabel, UIScrollView, UICollectionView 등... 화면에 보이는 거의 모든 요소가 UIKit에 속해있죠.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundation&lt;/strong&gt;: 앱의 가장 기본적인 데이터와 서비스를 다룹니다. 문자열, 숫자, 날짜 같은 원시 데이터 타입을 관리하고, 파일 시스템, 네트워크 통신 같은 핵심 기능을 제공하죠. UI와는 직접적인 관련이 없는, 앱의 뼈대를 만드는 역할을 합니다. 예로 UIKit 내에도 Foundation을 import 하고 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MapKit&lt;/strong&gt;: 지도 기반 서비스를 구현할 때 사용합니다. 지도 표시, 경로 찾기, 위치 검색 등의 기능을 손쉽게 추가할 수 있게 도와줍니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CoreML &amp;amp; Vision&lt;/strong&gt;: 머신러닝과 컴퓨터 비전 기능을 담당합니다. CPU, GPU를 적절히 활용하며 이미지 분석, 객체 탐지, 텍스트 인식 같은 고수준의 기능을 앱에 통합할 수 있게 해줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;UIKit&lt;/strong&gt;이나 &lt;strong&gt;MapKit&lt;/strong&gt; 같은 프레임워크들이 사용자에게 직접 보이는 부분을 담당한다면, &lt;strong&gt;Foundation&lt;/strong&gt;은 그 아래에서 묵묵히 앱의 중심을 잡아주는 역할을 합니다. CoreML이나 Vision 같은 고수준의 프레임워크들도 결국 Foundation이 제공하는 기본적인 데이터 처리 능력 위에서 동작하고 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;UIKit vs Foundation&lt;/h2&gt;
&lt;p&gt;iOS 개발자라면 &lt;code&gt;import UIKit&lt;/code&gt; 코드를 하루에도 수십 번씩 작성할 겁니다. 그만큼 UIKit과 Foundation은 iOS 개발의 알파이자 오메가라고 할 수 있는데요. 이 둘의 관계를 명확히 이해하는 것이 매우 중요합니다.&lt;/p&gt;
&lt;h3&gt;UIKit: 앱의 UI와 밀접한 프레임워크&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;UIKit&lt;/strong&gt;은 이름 그대로 &lt;strong&gt;U&lt;/strong&gt;ser &lt;strong&gt;I&lt;/strong&gt;nterface &lt;strong&gt;Kit&lt;/strong&gt;의 약자입니다. 앱의 화면을 구성하고 사용자와의 터치 이벤트를 처리하는 모든 책임을 집니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;주요 개념:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UIView &amp;amp; UIViewController&lt;/strong&gt;: 화면에 보이는 모든 요소(버튼, 레이블, 이미지 뷰 등)는 &lt;code&gt;UIView&lt;/code&gt;를 상속받습니다. 그리고 이 View들을 관리하고 생명주기를 제어하는 것이 바로 &lt;code&gt;UIViewController&lt;/code&gt;입니다. iOS 개발의 가장 기본이 되는 MVC(Model-View-Controller) 패턴의 핵심이죠.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIWindow&lt;/strong&gt;: 앱의 모든 View를 담는 최상위 컨테이너입니다. 기본적인 앱들은 최상위 window의 rootViewController를 지정해서 초기 앱을 보여줍니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIResponder&lt;/strong&gt;: 터치, 흔들기 같은 사용자 이벤트를 받고 처리하는 객체입니다. &lt;code&gt;UIView&lt;/code&gt;, &lt;code&gt;UIViewController&lt;/code&gt;, &lt;code&gt;UIApplication&lt;/code&gt; 등이 모두 &lt;code&gt;UIResponder&lt;/code&gt;를 상속받아 이벤트 체인을 형성합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto Layout &amp;amp; Storyboard&lt;/strong&gt;: 다양한 화면 크기에 대응하여 UI를 유연하게 배치하는 시스템(Auto Layout)과, UI를 시각적으로 디자인하고 화면 간의 전환을 설계하는 도구(Storyboard) 역시 UIKit의 중요한 개념입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;쉽게 말해, 사용자의 눈에 보이고 손으로 만지는 UI에 대한 기능들은 모두 UIKit과 밀접한 연관을 갖습니다.&lt;/p&gt;
&lt;h3&gt;Foundation: 앱의 뼈대 기반을 구성하는 프레임워크&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Foundation&lt;/strong&gt;은 앱의 기반, 즉 영어 뜻대로 &lt;strong&gt;토대(Foundation)&lt;/strong&gt; 를 다지는 프레임워크입니다. UI와는 전혀 관련이 없는, 데이터 처리, 객체 관리, 운영체제 서비스 연동 등 앱의 핵심 로직을 담당합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;주요 개념:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Value Types&lt;/strong&gt;: &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Double&lt;/code&gt;, &lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;Dictionary&lt;/code&gt; 등 프로그래밍의 가장 기본이 되는 데이터 타입들을 제공합니다. (정확히는 Swift 표준 라이브러리와 긴밀하게 연결되며 실제로 &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;등은 Objective-C 시절의 &lt;code&gt;NSString&lt;/code&gt;, &lt;code&gt;NSArray&lt;/code&gt; 등을 대체하고 보완합니다.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reference Types (NSObject 기반)&lt;/strong&gt;: &lt;code&gt;NSObject&lt;/code&gt;는 대부분의 Objective-C 클래스의 루트 클래스로, 객체의 생성과 소멸, 런타임 시스템과의 상호작용 등 객체 지향 프로그래밍의 근간을 이룹니다. &lt;code&gt;NSDate&lt;/code&gt;, &lt;code&gt;URLSession&lt;/code&gt;, &lt;code&gt;FileManager&lt;/code&gt; 등 수많은 중요 클래스들이 &lt;code&gt;NSObject&lt;/code&gt;를 기반으로 합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Persistence&lt;/strong&gt;: &lt;code&gt;UserDefaults&lt;/code&gt;를 이용한 간단한 데이터 저장, &lt;code&gt;Codable&lt;/code&gt; 프로토콜을 통한 데이터 직렬화/역직렬화(JSON 파싱 등) 기능을 제공합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concurrency&lt;/strong&gt;: &lt;code&gt;GCD(Grand Central Dispatch)&lt;/code&gt;와 &lt;code&gt;OperationQueue&lt;/code&gt;를 통해 복잡한 비동기 처리와 멀티스레딩을 쉽게 구현할 수 있도록 돕습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Foundation이 없다면, 우리는 데이터를 다루거나 네트워크 통신을 하는 기본적인 작업조차 매우 복잡하게 처리해야 할 겁니다. 그야말로 보이지 않는 곳에서 앱의 안정성과 성능을 책임지는 핵심 프레임워크라 할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;UIKit과 Foundation 사이의 관계&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-10 오전 1.16.57.png&quot; data-origin-width=&quot;1368&quot; data-origin-height=&quot;1184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg2bXr/btsQ3fF7thB/sb5DeEKKdy8AFbkyNCU0Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg2bXr/btsQ3fF7thB/sb5DeEKKdy8AFbkyNCU0Tk/img.png&quot; data-alt=&quot;UIKit.h 헤더 구성, Foundation.h를 import 하고 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg2bXr/btsQ3fF7thB/sb5DeEKKdy8AFbkyNCU0Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg2bXr%2FbtsQ3fF7thB%2Fsb5DeEKKdy8AFbkyNCU0Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1368&quot; height=&quot;1184&quot; data-filename=&quot;스크린샷 2025-10-10 오전 1.16.57.png&quot; data-origin-width=&quot;1368&quot; data-origin-height=&quot;1184&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UIKit.h 헤더 구성, Foundation.h를 import 하고 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 둘의 관계는 명확합니다. &lt;strong&gt;UIKit은 Foundation에 의존합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import UIKit&lt;/code&gt;을 하면 내부적으로 &lt;code&gt;import Foundation&lt;/code&gt;이 함께 이루어집니다. 왜냐하면 UIKit의 모든 클래스와 객체들은 결국 Foundation이 제공하는 기본적인 데이터 타입과 객체 모델 위에서 만들어지기 때문입니다.&lt;/p&gt;
&lt;p&gt;예를 들어 볼까요?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UILabel&lt;/code&gt;에 텍스트를 표시하려면 Foundation의 &lt;code&gt;String&lt;/code&gt; 데이터 타입이 필요합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIImageView&lt;/code&gt;에 인터넷의 url에 맞는 이미지를 띄우려면 Foundation의 &lt;code&gt;URLSession&lt;/code&gt;으로 이미지 데이터를 다운로드해야 합니다.&lt;/li&gt;
&lt;li&gt;사용자의 위치 정보를 &lt;code&gt;MapKit&lt;/code&gt; 뷰에 표시하려면, 그 위치 좌표(위도, 경도)는 Foundation의 &lt;code&gt;Double&lt;/code&gt; 타입으로 관리됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이처럼 UIKit은 Foundation이라는 튼튼한 기반 위에서 화려한 사용자 인터페이스를 그려내는 구조입니다. 개발자는 이 두 프레임워크의 역할을 명확히 이해하고, 각자의 역할에 맞는 코드를 작성해야 효율적이고 안정적인 앱을 만들 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;정리하며&lt;/h2&gt;
&lt;p&gt;오늘은 iOS 개발의 핵심인 &lt;strong&gt;Cocoa Touch&lt;/strong&gt;와 그 생태계를 이루는 &lt;strong&gt;UIKit&lt;/strong&gt;, &lt;strong&gt;Foundation&lt;/strong&gt; 등의 프레임워크에 대해 알아보았습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cocoa Touch&lt;/strong&gt;: iOS 앱 개발 환경의 최상위 프레임워크.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIKit, MapKit, Vision, CoreML, Foundation 등&lt;/strong&gt;: Cocoa Touch를 구성하는 하위 프레임워크들.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIKit&lt;/strong&gt;: 눈에 보이는 UI와 사용자 상호작용을 담당하는 프레임워크.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundation&lt;/strong&gt;: 눈에 보이지 않는 데이터 처리와 핵심 로직을 담당하는 핵심 프레임워크.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIKit과 Foundation 사이의 관계&lt;/strong&gt;: UIKit은 Foundation이라는 기반 위에 세워져 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;궁금한 점이나, 의견이 있다면 언제든지 댓글 남겨주세요! 그럼 다음에도 유익한 정보로 찾아뵙겠습니다.&lt;br&gt;그럼 모두들 즐거운 코딩 하세요. 감사합니다!  &lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>Cocoa Touch</category>
      <category>iOS Cocoa</category>
      <category>iOS Foundation</category>
      <category>iOS framework</category>
      <category>ios UIKit</category>
      <category>ios 프레임워크</category>
      <category>iOS 핵심</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/447</guid>
      <comments>https://0urtrees.tistory.com/447#entry447comment</comments>
      <pubDate>Fri, 10 Oct 2025 01:18:02 +0900</pubDate>
    </item>
    <item>
      <title>iOS AppDelegate, 앱 초기설정 및 생애주기 관리 방법</title>
      <link>https://0urtrees.tistory.com/446</link>
      <description>&lt;h1&gt;&lt;strong&gt;iOS 앱 초기설정, AppDelegate 역할 및 생애주기 정리&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;iOS 앱의 루트 뷰 지정과 앱 딥링크 실행 외에도 핵심적으로 전반적인 생애주기를 관리할 수 있는 &lt;code&gt;AppDelegate&lt;/code&gt;에서는 앱의 상태 변화에 따라 호출되는 다양한 메서드가 정의되어 있습니다.&lt;/p&gt;
&lt;p&gt;iOS 13 이후 멀티 윈도우 개념이 생기면서 &lt;code&gt;SceneDelegate&lt;/code&gt;가 추가되었지만, 그 이후에도 앱 전체 수준의 이벤트를 다루는 역할은 여전히 &lt;code&gt;AppDelegate&lt;/code&gt;가 담당하고 있습니다.&lt;/p&gt;
&lt;p&gt;아래 소개하는 생애주기 메서드들은 &lt;strong&gt;필수 구현이 아니며&lt;/strong&gt;, 필요에 따라 선택적으로 정의해 사용할 수 있습니다. AppDelegate의 생애주기 메서드를 활용하면 앱의 원하는 시점에 맞게 다양한 동작을 수행할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;willFinishLaunchingWithOptions&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func application(
    _ application: UIApplication,
    willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -&amp;gt; Bool {
    // do something
    return true
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;willFinishLaunchingWithOptions&lt;/code&gt;는 앱이 완전히 실행되기 직전에 호출됩니다.&lt;br&gt;이 시점은 UI가 표시되기 전 단계이기 때문에 &lt;strong&gt;UI 세팅보다는 초기 설정에 적합한 시점&lt;/strong&gt;입니다.&lt;br&gt;앱의 설정값을 불러오거나, 의존성 주입 등 기본적인 세팅을 처리할 때 활용할 수 있습니다.&lt;br&gt;&lt;code&gt;true&lt;/code&gt;를 반환해야 앱 실행이 이어지며, 실행 시 초기 1회만 호출됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;didFinishLaunchingWithOptions&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -&amp;gt; Bool {
    return true
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;didFinishLaunchingWithOptions&lt;/code&gt;는 앱 실행 준비를 모두 마치고, &lt;strong&gt;첫 화면이 표시되기 직전&lt;/strong&gt;에 호출됩니다.&lt;br&gt;앱 전반에서 필요한 &lt;strong&gt;Logger, Firebase Crashlytics, APNS Push&lt;/strong&gt; 등의 초기 설정 작업을 이 시점에 수행합니다.&lt;br&gt;보통 &lt;code&gt;rootViewController&lt;/code&gt; 초기화도 이 단계에서 이뤄집니다.&lt;br&gt;&lt;code&gt;true&lt;/code&gt;를 반환하면 다음 단계로 실행이 이어지며, 미구현 시 기본적으로 &lt;code&gt;true&lt;/code&gt;가 반환됩니다.&lt;br&gt;실행 시 초기 1회만 호출됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;applicationDidBecomeActive&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func applicationDidBecomeActive(_ application: UIApplication) {
    // do something
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;앱이 사용자와 &lt;strong&gt;상호작용 가능한 상태&lt;/strong&gt;가 되면 호출됩니다.&lt;br&gt;백그라운드에 있다가 포어그라운드로 돌아와 상호작용할 준비가 되면 실행되며,&lt;br&gt;앱 실행 초기에 &lt;code&gt;didFinishLaunchingWithOptions&lt;/code&gt; 이후에도 이어서 호출됩니다.&lt;/p&gt;
&lt;p&gt;다른 앱의 음악을 듣다가 본 앱으로 복귀했을 때 오디오 세팅을 조정하거나,&lt;br&gt;일시정지된 애니메이션을 재개하는 등  &lt;strong&gt;앱 활성화 이후 처리 로직&lt;/strong&gt;에 활용됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;applicationWillResignActive&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func applicationWillResignActive(_ application: UIApplication) {
    // 앱이 활성 상태를 잃기 직전에 호출됩니다.
    // 홈 버튼 누름, 알림창 등장, 전화 수신 등으로 일시 중단되기 전 단계입니다.
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;포어그라운드에서 &lt;strong&gt;active → inactive&lt;/strong&gt; 상태로 전환되기 직전에 호출됩니다.&lt;br&gt;전화가 오거나, 알림창이 뜨거나, 홈 화면으로 이동하는 등 일시적인 중단 상황에서 실행됩니다.&lt;/p&gt;
&lt;p&gt;이 시점에는 불필요한 작업을 잠시 중단하거나, 데이터 저장 및 정리 등 &lt;strong&gt;일시중단 전 처리&lt;/strong&gt;를 수행하기에 적합합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;applicationDidEnterBackground&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func applicationDidEnterBackground(_ application: UIApplication) {
    // 앱이 백그라운드로 진입했을 때 호출됩니다.
    // 데이터 저장이나 네트워크 세션 종료 등의 작업을 수행합니다.
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;didEnterBackground&lt;/code&gt;는 사용자가 홈 화면으로 이동하거나,&lt;br&gt;다른 앱으로 전환해 &lt;strong&gt;앱이 백그라운드 상태가 되었을 때&lt;/strong&gt; 호출됩니다.&lt;br&gt;이 시점에 백그라운드에서 필요한 작업이나, 사용자 데이터 저장, 세션 종료 등을 처리할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;applicationWillTerminate&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;func applicationWillTerminate(_ application: UIApplication) {
    // 앱이 완전히 종료되기 직전 호출됩니다.
    // 단, 백그라운드 상태에서 시스템이 앱을 강제 종료할 경우엔 호출되지 않습니다.
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;willTerminate&lt;/code&gt;는 앱이 &lt;strong&gt;정상적으로 종료되기 직전&lt;/strong&gt; 호출됩니다.&lt;br&gt;앱이 강제로 종료될 때는 호출되지 않으며, 종료 전 필요한 작업을 수행할 수 있는 마지막 단계입니다.&lt;br&gt;예를 들어, 앱 종료 직전에 저장해야 하는 데이터나 로그 처리를 담당할 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;앱 실행 후 바로 종료 시 호출 순서&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;앱을 실행했다가 바로 종료하면 일반적으로 아래 순서대로 메서드들이 호출됩니다.&lt;br&gt;메서드 이름만 봐도, 흐름이 자연스럽게 이어지는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 앱 실행 및 종료 시의 일반적인 호출 순서
willFinishLaunchingWithOptions
→ didFinishLaunchingWithOptions
→ applicationDidBecomeActive
→ applicationWillResignActive
→ applicationDidEnterBackground
→ applicationWillTerminate&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;앱 실행 후, 바로 홈화면으로 복귀 시 호출 메서드 예시&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-06 오전 1.01.01.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo50OZ/btsQ2xNhX4I/a5s9AIGDeZHxaghv7KSwM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo50OZ/btsQ2xNhX4I/a5s9AIGDeZHxaghv7KSwM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo50OZ/btsQ2xNhX4I/a5s9AIGDeZHxaghv7KSwM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo50OZ%2FbtsQ2xNhX4I%2Fa5s9AIGDeZHxaghv7KSwM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;984&quot; height=&quot;302&quot; data-filename=&quot;스크린샷 2025-10-06 오전 1.01.01.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;앱 실행 후, 홈화면 복귀 시 호출되는 AppDelegate 생애주기메서드 예시입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;&lt;strong&gt;iOS13 이후 추가된 SceneDelegate&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;iOS 13 이후 아이패드 등에서 &lt;strong&gt;멀티 윈도우 개념&lt;/strong&gt;이 도입되면서 &lt;code&gt;SceneDelegate&lt;/code&gt;가 추가되었습니다.&lt;br&gt;이에 따라 일부 역할이 &lt;code&gt;SceneDelegate&lt;/code&gt;로 분리되었지만,&lt;br&gt;앱 전반적인 관리는 여전히 &lt;code&gt;AppDelegate&lt;/code&gt;가 담당합니다.&lt;/p&gt;
&lt;p&gt;멀티 윈도우 기능이 필요하지 않은 일반적인 앱에서는&lt;br&gt;&lt;code&gt;SceneDelegate&lt;/code&gt; 없이 &lt;code&gt;AppDelegate&lt;/code&gt;만으로도 충분히 서비스 개발이 가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;마무리&lt;/h2&gt;
&lt;p&gt;오늘은 앱의 전반적인 생애주기를 관리하는 &lt;code&gt;AppDelegate&lt;/code&gt;의 역할과 주요 메서드들을 정리해봤습니다.&lt;br&gt;앱이 실행되고 종료되는 전체 흐름을 이해하면,&lt;br&gt;상태 변화에 따라 어떤 시점에 어떤 처리를 해야 하는지 명확하게 판단할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다음에는 &lt;code&gt;SceneDelegate&lt;/code&gt; 중심으로 화면 단위 생애주기에 대해 정리해보겠습니다. 감사합니다!  &lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>appdelegate</category>
      <category>iOS AppDelegate</category>
      <category>iOS 개발 팁</category>
      <category>iOS 생애주기</category>
      <category>iOS 앱 설정</category>
      <category>iOS 초기설정</category>
      <category>SceneDelegate</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/446</guid>
      <comments>https://0urtrees.tistory.com/446#entry446comment</comments>
      <pubDate>Mon, 6 Oct 2025 01:04:34 +0900</pubDate>
    </item>
    <item>
      <title>iOS26 개발, 시뮬레이터 테스트 위한 Xcode26 설치 방법</title>
      <link>https://0urtrees.tistory.com/445</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. 개발자 멍구입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Liquid Glass 디자인이 적용되는 iOS26, 이제 개발자에게는 추가로 테스트 및 대응해야하는 영역인데요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;오늘은 iOS26 테스트를 위한 환경 설정 과정을 가볍게 기록 및 공유할게요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;macOS 버전 및 Xcode 버전 확인&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.04.15.png&quot; data-origin-width=&quot;2608&quot; data-origin-height=&quot;1828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhJdEU/btsQPESM1t6/2SDnADOy7VVVkFZIx8Mmgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhJdEU/btsQPESM1t6/2SDnADOy7VVVkFZIx8Mmgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhJdEU/btsQPESM1t6/2SDnADOy7VVVkFZIx8Mmgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhJdEU%2FbtsQPESM1t6%2F2SDnADOy7VVVkFZIx8Mmgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2608&quot; height=&quot;1828&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.04.15.png&quot; data-origin-width=&quot;2608&quot; data-origin-height=&quot;1828&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;먼저, iOS26 테스트를 위해서는 iOS26 시뮬레이터를 지원하는 Xcode 26.0 release 버전을 다운로드해야합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Xcode 26.0 release 버전을 설치하기 위해서는 macOS 15.6 이상 버전이 필요하기 때문에, 그 미만 macOS 버전이라면, 업데이트를 해주어야 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Xcode26 설치를 위한 macOS 버전 15.6 이상 업데이트 하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2WkYa/btsQN9lKhGG/NluRGIkzalhTMRnfqkIJk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2WkYa/btsQN9lKhGG/NluRGIkzalhTMRnfqkIJk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2WkYa/btsQN9lKhGG/NluRGIkzalhTMRnfqkIJk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2WkYa%2FbtsQN9lKhGG%2FNluRGIkzalhTMRnfqkIJk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;534&quot; height=&quot;732&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;좌상단 애플 로고를 클릭 후, 이 Mac에 관하여... 를 클릭하시면 현재 macOS 버전을 알 수 있어요. 저는 15.5였는데, Xcode 26 설치를 위해서 15.7로 업데이트 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.04.51.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfnGN6/btsQRpNS26Y/sm8ORgGKs2bMipqLaFE7dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfnGN6/btsQRpNS26Y/sm8ORgGKs2bMipqLaFE7dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfnGN6/btsQRpNS26Y/sm8ORgGKs2bMipqLaFE7dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfnGN6%2FbtsQRpNS26Y%2Fsm8ORgGKs2bMipqLaFE7dK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;996&quot; height=&quot;278&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.04.51.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;좌상단 애플로고 클릭 &amp;gt; 시스템 설정 &amp;gt; 일반 &amp;gt; 소프트웨어 업데이트 를 클릭하시면, 업데이트 가능한 버전을 확인 가능합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;macOS 버전 15.6 이상 업데이트 후 Xcode26, iOS26 시뮬레이터 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.05.12.png&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wan54/btsQNGD9lH4/QiWRPj4NklaMfHMwrQSm3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wan54/btsQNGD9lH4/QiWRPj4NklaMfHMwrQSm3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wan54/btsQNGD9lH4/QiWRPj4NklaMfHMwrQSm3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwan54%2FbtsQNGD9lH4%2FQiWRPj4NklaMfHMwrQSm3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;638&quot; height=&quot;138&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.05.12.png&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇게 macOS 15.5 -&amp;gt; 15.7로 업데이트 후, Xcode 26.0.1 release 버전을 설치했어요. 저는 M1 칩이 있는 맥북이라서 Apple silicon 버전으로 받았습니다. 기존 Xcode 대비 아이콘이 변경되었네요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.05.34.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uKCEQ/btsQOiQJVlx/kl3zLVsZTpJiKH0IkcG5Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uKCEQ/btsQOiQJVlx/kl3zLVsZTpJiKH0IkcG5Mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uKCEQ/btsQOiQJVlx/kl3zLVsZTpJiKH0IkcG5Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuKCEQ%2FbtsQOiQJVlx%2Fkl3zLVsZTpJiKH0IkcG5Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;660&quot; height=&quot;328&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.05.34.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Xcode 26을 실행하시면, iOS 26 개발 tool 설치가 가능하고, 여기에서 iOS 26 simluator 를 설치가능해요. 설치 이후에는 iOS 26의 iPhone Air 같은 기종을 시뮬레이터로 선택해서 개발하실 수 있으니 참고하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.06.05.png&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mXHLV/btsQRqsuoo9/cgUxyxEIhLKARm6jI6EUDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mXHLV/btsQRqsuoo9/cgUxyxEIhLKARm6jI6EUDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mXHLV/btsQRqsuoo9/cgUxyxEIhLKARm6jI6EUDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmXHLV%2FbtsQRqsuoo9%2FcgUxyxEIhLKARm6jI6EUDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;150&quot; data-filename=&quot;스크린샷 2025-09-26 오전 12.06.05.png&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;iOS26 시뮬레이터 아이콘도 변경되었네요. 전체적으로 기존보다 심플하고, 확연히 개성있는 모습을 보여주는 것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;오늘은 iOS26 iOS 개발 테스트를 위해서...! macOS 15.6이상 업데이트 후, Xcode26 설치 및 iOS26 simulator 를 통해 iOS26 개발 테스트가 가능한 환경을 준비하는 과정을 가볍게 알아봤습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;iOS26 부터는 앱 시스템 디자인이 전체적으로 변경된게 많으니, 기존에 문제없던 곳에서도 많은 버그나 레이아웃 이슈가 발생할 수 있는데요. 또 아이폰 유저들은 업데이트가 빠른 편이니. voc 발생할 수 있는 부분인 것 같아요.&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇기에 현업이나, 사이드프로젝트 하는 분들은 관심 갖고 유지보수하시면 좋을 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지금까지 iOS26 시뮬레이터로 iOS 개발 준비하는 방법이었어요. 감사합니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>ios26</category>
      <category>iOS26 simulator</category>
      <category>iOS26 개발</category>
      <category>iOS26 시뮬레이터</category>
      <category>iOS26 테스트</category>
      <category>Xcode26</category>
      <category>Xcode26설치</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/445</guid>
      <comments>https://0urtrees.tistory.com/445#entry445comment</comments>
      <pubDate>Fri, 26 Sep 2025 00:33:18 +0900</pubDate>
    </item>
    <item>
      <title>App Store Connect 애플 개발자 계정 비밀번호 변경하는 방법</title>
      <link>https://0urtrees.tistory.com/444</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.40.56.png&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwQtyY/btsQoIOiOdM/sjOHZmo6NZxBDgh3R6511K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwQtyY/btsQoIOiOdM/sjOHZmo6NZxBDgh3R6511K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwQtyY/btsQoIOiOdM/sjOHZmo6NZxBDgh3R6511K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwQtyY%2FbtsQoIOiOdM%2FsjOHZmo6NZxBDgh3R6511K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2406&quot; height=&quot;1106&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.40.56.png&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;안녕하세요. 개발자 멍구입니다~!  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들은 App Store Connect의 애플 개발자 계정 많이 사용하시나요? 애플 개발자 프로그램을 등록해서 iOS앱 심사를 내고, 배포 및 런칭할 일이 있다면, 사용하게 되는 계정인데요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 App Store Connect의 애플 개발자 계정 비밀번호 변경방법 간단하게 기록해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.43.35.png&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sc54k/btsQohpVOpO/yDUiXsB8KKCEkaW5t8lY81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sc54k/btsQohpVOpO/yDUiXsB8KKCEkaW5t8lY81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sc54k/btsQohpVOpO/yDUiXsB8KKCEkaW5t8lY81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSc54k%2FbtsQohpVOpO%2FyDUiXsB8KKCEkaW5t8lY81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2216&quot; height=&quot;1000&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.43.35.png&quot; data-origin-width=&quot;2216&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App Store Connect 개발자 계정은 애플 공식 홈페이지와도 연동되는 계정입니다. apple 공시 홈페이지 하단을 보시면, 계정 섹션 하단에 Apple 계정 관리 메뉴가 있어요. 여기를 들어갑니다.&lt;/p&gt;
&lt;figure id=&quot;og_1757084833500&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apple (대한민국)&quot; data-og-description=&quot;Apple이 제시하는 혁신적인 세상을 만나고, iPhone, iPad, Apple Watch, Mac, Apple TV 등을 구입하는 것은 물론, 액세서리, 엔터테인먼트, 전문가 기기 지원에 대해서도 살펴볼 수 있습니다.&quot; data-og-host=&quot;www.apple.com&quot; data-og-source-url=&quot;https://www.apple.com/kr&quot; data-og-url=&quot;https://www.apple.com/kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/B8Hql/hyZG4VQm4f/hcKI5zolkGiwat9lLOy8k0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.apple.com/kr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.apple.com/kr&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/B8Hql/hyZG4VQm4f/hcKI5zolkGiwat9lLOy8k0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apple (대한민국)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Apple이 제시하는 혁신적인 세상을 만나고, iPhone, iPad, Apple Watch, Mac, Apple TV 등을 구입하는 것은 물론, 액세서리, 엔터테인먼트, 전문가 기기 지원에 대해서도 살펴볼 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.43.57.png&quot; data-origin-width=&quot;2034&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW2NyF/btsQnRrskOd/IF7VNUqELqoKEKGn69ShhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW2NyF/btsQnRrskOd/IF7VNUqELqoKEKGn69ShhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW2NyF/btsQnRrskOd/IF7VNUqELqoKEKGn69ShhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW2NyF%2FbtsQnRrskOd%2FIF7VNUqELqoKEKGn69ShhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2034&quot; height=&quot;816&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.43.57.png&quot; data-origin-width=&quot;2034&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple 계정 관리 페이지의 로그인 및 보안 &amp;gt; 암호 메뉴를 보시면, 최근 비밀번호 업데이트 일자와 함께 클릭 후 비밀번호 변경이 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.52.45.png&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;1268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQajV9/btsQpbvWeiT/LHGGaR026o365RmzYhCyb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQajV9/btsQpbvWeiT/LHGGaR026o365RmzYhCyb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQajV9/btsQpbvWeiT/LHGGaR026o365RmzYhCyb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQajV9%2FbtsQpbvWeiT%2FLHGGaR026o365RmzYhCyb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1490&quot; height=&quot;1268&quot; data-filename=&quot;스크린샷 2025-09-05 오후 11.52.45.png&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;1268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비밀번호 변경 페이지에서 현재 암호와 새 암호를 입력해서 쉽게 비밀번호 변경이 가능했습니다. 변경된 비밀번호는 공식 apple 홈페이지 및 App Store Connect 계정 로그인으로 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 간단하게 App Store Connect 애플 개발자 계정 비밀번호 변경하는 방법을 기록해봤습니다. 모두 주기적으로 애플 계정, 개발자 계정 비밀번호 관리하시면서, 안전한 계정 관리 되시길 바랍니다~  &lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>App store connect</category>
      <category>Apple 비밀번호 변경</category>
      <category>애플 개발자 계정</category>
      <category>애플 계정 관리</category>
      <category>애플 계정 비밀번호 변경</category>
      <category>애플 비밀번호 변경</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/444</guid>
      <comments>https://0urtrees.tistory.com/444#entry444comment</comments>
      <pubDate>Sat, 6 Sep 2025 00:11:44 +0900</pubDate>
    </item>
    <item>
      <title>iOS Xcode16 WebKit, nw_proxy_config_t 컴파일 에러 수정방법 feat. chatGPT</title>
      <link>https://0urtrees.tistory.com/443</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요, 개발자 멍구입니다!&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;오랜만에 사이드 프로젝트를 만지다가 Xcode 16.4로 업데이트한 이후, 컴파일 에러가 발생했어요.  &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예전에 Xcode 15를 사용할 때 겪었던 비슷한 에러가 또 발생해서, 이전에 제가 작성했던 블로그 글을 참고해보기로 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;사이드프로젝트 컴파일 에러 발생&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Could not build Objective-C module 'WebKit',&amp;nbsp;No type or protocol named 'nw_proxy_config_t'&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 5.26.27.png&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1776&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dejJRx/btsOBfO6rwh/oXyDkKBEr2h4ut07UJobSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dejJRx/btsOBfO6rwh/oXyDkKBEr2h4ut07UJobSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dejJRx/btsOBfO6rwh/oXyDkKBEr2h4ut07UJobSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdejJRx%2FbtsOBfO6rwh%2FoXyDkKBEr2h4ut07UJobSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;1776&quot; data-filename=&quot;스크린샷 2025-06-14 오후 5.26.27.png&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;1776&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지겨워요 Webkit 관련 이슈인데요. tuist 등의 외부 라이브러리 의존성과 연관이 있는 것 같아요. tuist, TCA 기반의 프로젝트에서만 경험했던 컴파일 에러입니다. 근원지는 WKWebsiteDataStore.h 입니다. 왜 아냐면, 이미 이걸 작년에도 경험해봤거든요. ㅠㅠ&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;WKWebsiteDataStore.h는 WebKit 프레임워크의 헤더 파일로, &lt;br /&gt;WKWebsiteDataStore 클래스의 인터페이스를 정의합니다. 이 클래스는 웹 콘텐츠(웹페이지 등)가 사용하는 데이터 저장소를 관리&lt;br /&gt;하는 역할을 해요. WKWebView와도 연관이 깊은 놈이라고 볼 수 있겠어요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;WebKit 이슈의 근원지, WKWebsiteDataStore.h 수정 시도&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 5.31.22.png&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rFWQR/btsOBdRcm7z/DjjbQGY743kUakg6aA7UV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rFWQR/btsOBdRcm7z/DjjbQGY743kUakg6aA7UV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rFWQR/btsOBdRcm7z/DjjbQGY743kUakg6aA7UV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrFWQR%2FbtsOBdRcm7z%2FDjjbQGY743kUakg6aA7UV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;866&quot; data-filename=&quot;스크린샷 2025-06-14 오후 5.31.22.png&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1749905775136&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;iOS Xcode 15.2, module 'WebKit' build 이슈 해결방법&quot; data-og-description=&quot;안녕하세요~ iOS앱을 개발하다가 문제가 생겼던 멍구입니다!  오늘은 Xcode 15.2 버전을 통해 앱을 개발하면서 자주 발생했던 'WebKit' module build 이슈 해결방법을 간략하게 소개하려 합니다!&amp;nbsp;'WebKit'&quot; data-og-host=&quot;0urtrees.tistory.com&quot; data-og-source-url=&quot;https://0urtrees.tistory.com/421&quot; data-og-url=&quot;https://0urtrees.tistory.com/421&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bjsCl0/hyY79bTchY/V2WbZZqKIYsHMjQLnP9SJ0/img.png?width=786&amp;amp;height=566&amp;amp;face=0_0_786_566,https://scrap.kakaocdn.net/dn/chMujR/hyY8MHykfP/cxh7X92y9K0qfOZU0tcBhk/img.png?width=786&amp;amp;height=566&amp;amp;face=0_0_786_566,https://scrap.kakaocdn.net/dn/hkial/hyY79JKjFx/3FINUiQa8ZRnHSAVvsKjVK/img.png?width=1460&amp;amp;height=860&amp;amp;face=0_0_1460_860&quot;&gt;&lt;a href=&quot;https://0urtrees.tistory.com/421&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://0urtrees.tistory.com/421&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bjsCl0/hyY79bTchY/V2WbZZqKIYsHMjQLnP9SJ0/img.png?width=786&amp;amp;height=566&amp;amp;face=0_0_786_566,https://scrap.kakaocdn.net/dn/chMujR/hyY8MHykfP/cxh7X92y9K0qfOZU0tcBhk/img.png?width=786&amp;amp;height=566&amp;amp;face=0_0_786_566,https://scrap.kakaocdn.net/dn/hkial/hyY79JKjFx/3FINUiQa8ZRnHSAVvsKjVK/img.png?width=1460&amp;amp;height=860&amp;amp;face=0_0_1460_860');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;iOS Xcode 15.2, module 'WebKit' build 이슈 해결방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요~ iOS앱을 개발하다가 문제가 생겼던 멍구입니다!  오늘은 Xcode 15.2 버전을 통해 앱을 개발하면서 자주 발생했던 'WebKit' module build 이슈 해결방법을 간략하게 소개하려 합니다!&amp;nbsp;'WebKit'&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;0urtrees.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1749906394800&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// WKWebsiteDataStore.h
&quot;__IPHONE_OS_VERSION_MAX_ALLOWED &amp;gt;= 170000&quot;&amp;nbsp; 에서 170000 -&amp;gt; 180000로 변경시도&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 이슈를 Xcode 15.2에서도 경험했던 터라, 그때 작성했던 위 블로그 포스팅을 참고해서 수정해보기 시도를 했으나, 실패했습니다. 골치아파요. 그래서 chatGPT에게 도움을 요청했습니다...!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;chatGPT에게 WKWebsiteDataStore.h 수정 요청&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 9.58.15.png&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;1306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDagQs/btsOAJpnDYe/gBPqXS6wQAWOUlz2Rq4p0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDagQs/btsOAJpnDYe/gBPqXS6wQAWOUlz2Rq4p0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDagQs/btsOAJpnDYe/gBPqXS6wQAWOUlz2Rq4p0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDagQs%2FbtsOAJpnDYe%2FgBPqXS6wQAWOUlz2Rq4p0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1696&quot; height=&quot;1306&quot; data-filename=&quot;스크린샷 2025-06-14 오후 9.58.15.png&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;1306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;WKWebsiteDataStore.h에서 nw_proxy_config_t 타입을 인식 못함 &amp;rarr; &lt;span style=&quot;color: #ee2323;&quot;&gt;No type or protocol named 'nw_proxy_config_t' 에러 발생&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Could not build Objective-C module 'WebKit', No type or protocol named 'nw_proxy_config_t'&lt;/span&gt; 관련 컴파일에러가 발생해서 컴파일 에러 내용과 함께 해당 에러가 발생하는 WKWebsiteDataStore.h 파일을 수정해달라고 chatGPT에게 요청했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇게 우리의 chatGPT는 nw_proxy_config_t를 인식하지 못하니, 이걸 NSArray로 바꾸라고 해서 그렇게 수정했습니다. 파일 내용 vi 편집기로 일괄 수정!&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇게 수정 후 tuist clean &amp;gt; tuist fetch &amp;gt; tuist generate &amp;gt; build 시도...!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇게 프로젝트 빌드가 되네요...   &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 방법은 Xcode를 업데이트 하거나, 변경하면 다시 별도 처리가 필요한 단편적인 방법이라, 정해는 아닙니다. 그래도 당장 사이드프로젝트 빌드 및 개발 진행을 할 수 있었습니다. ㅠㅠ tuist, TCA 등의 외부라이브러리 의존이 많다보니 이런 저런 예기치 못한 문제들이 더 발생하는 것 같아요. 이 또한 좋은 경험이라 생각하며... 이만 포스팅 마치겠습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 이슈 관련 더 좋은 해결방안이 있다면 공유 부탁드려요. 수정된 WKWebsiteDataStore.h 코드 내용 공유와 함께 포스팅 마칠게요. 감사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;수정한 WKWebsiteDataStore.h 파일 코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1749906259644&quot; class=&quot;objectivec&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;/*
 * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS 'AS IS'
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import &amp;lt;WebKit/WKFoundation.h&amp;gt;
#import &amp;lt;WebKit/WKWebsiteDataRecord.h&amp;gt;

#if __has_include(&amp;lt;Network/proxy_config.h&amp;gt;)
#import &amp;lt;Network/Network.h&amp;gt;
#endif

NS_ASSUME_NONNULL_BEGIN

@class WKHTTPCookieStore;

WK_SWIFT_UI_ACTOR
WK_EXTERN API_AVAILABLE(macos(10.11), ios(9.0))
@interface WKWebsiteDataStore : NSObject &amp;lt;NSSecureCoding&amp;gt;

+ (WKWebsiteDataStore *)defaultDataStore;
+ (WKWebsiteDataStore *)nonPersistentDataStore;

- (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

@property (nonatomic, readonly, getter=isPersistent) BOOL persistent;
+ (NSSet&amp;lt;NSString *&amp;gt; *)allWebsiteDataTypes;

- (void)fetchDataRecordsOfTypes:(NSSet&amp;lt;NSString *&amp;gt; *)dataTypes completionHandler:(WK_SWIFT_UI_ACTOR void (^)(NSArray&amp;lt;WKWebsiteDataRecord *&amp;gt; *))completionHandler WK_SWIFT_ASYNC_NAME(dataRecords(ofTypes:));

- (void)removeDataOfTypes:(NSSet&amp;lt;NSString *&amp;gt; *)dataTypes forDataRecords:(NSArray&amp;lt;WKWebsiteDataRecord *&amp;gt; *)dataRecords completionHandler:(WK_SWIFT_UI_ACTOR void (^)(void))completionHandler;

- (void)removeDataOfTypes:(NSSet&amp;lt;NSString *&amp;gt; *)dataTypes modifiedSince:(NSDate *)date completionHandler:(WK_SWIFT_UI_ACTOR void (^)(void))completionHandler;

@property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore API_AVAILABLE(macos(10.13), ios(11.0));
@property (nonatomic, readonly, nullable) NSUUID *identifier API_AVAILABLE(macos(14.0), ios(17.0));

+ (WKWebsiteDataStore *)dataStoreForIdentifier:(NSUUID *)identifier API_AVAILABLE(macos(14.0), ios(17.0));

+ (void)removeDataStoreForIdentifier:(NSUUID *)identifier completionHandler:(WK_SWIFT_UI_ACTOR void(^)(NSError * _Nullable))completionHandler API_AVAILABLE(macos(14.0), ios(17.0));

+ (void)fetchAllDataStoreIdentifiers:(WK_SWIFT_UI_ACTOR void(^)(NSArray&amp;lt;NSUUID *&amp;gt; *))completionHandler WK_SWIFT_ASYNC_NAME(getter:allDataStoreIdentifiers()) API_AVAILABLE(macos(14.0), ios(17.0));

#if ((TARGET_OS_OSX &amp;amp;&amp;amp; __MAC_OS_X_VERSION_MAX_ALLOWED &amp;gt;= 140000) \
    || ((TARGET_OS_IOS || TARGET_OS_MACCATALYST) &amp;amp;&amp;amp; __IPHONE_OS_VERSION_MAX_ALLOWED &amp;gt;= 180000) \
    || (TARGET_OS_WATCH &amp;amp;&amp;amp; __WATCH_OS_VERSION_MAX_ALLOWED &amp;gt;= 100000) \
    || (TARGET_OS_TV &amp;amp;&amp;amp; __TV_OS_VERSION_MAX_ALLOWED &amp;gt;= 170000) \
    || (defined(TARGET_OS_VISION) &amp;amp;&amp;amp; TARGET_OS_VISION))

@property (nullable, nonatomic, copy) NSArray *proxyConfigurations NS_REFINED_FOR_SWIFT API_AVAILABLE(macos(14.0), ios(17.0));
#endif

@end

NS_ASSUME_NONNULL_END&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>iOS 개발/iOS 개발 팁</category>
      <category>ios 에러</category>
      <category>iOS 컴파일에러</category>
      <category>ios 컴파일오류</category>
      <category>ios 트러블슈팅</category>
      <category>nw_proxy_config_t</category>
      <category>webkit 에러</category>
      <category>webkit 이슈</category>
      <category>wkwebsitedatastore.h</category>
      <category>xcdoe16</category>
      <category>xcode16 에러</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/443</guid>
      <comments>https://0urtrees.tistory.com/443#entry443comment</comments>
      <pubDate>Sun, 15 Jun 2025 09:13:08 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode swift, Letter Combinations of a Phone Number 문제풀이</title>
      <link>https://0urtrees.tistory.com/442</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;안녕하세요~ 개발자 멍구입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;오늘은 LeetCode의 Letter Combinations of a Phone Number 를 풀어보았어요. 바로 보겠습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;릿코드 Letter Combinations of a Phone Number 문제 설명&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.22.39.png&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;892&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmlO1o/btsOBZkjmH6/41aXt9ZMYq0nsQ4RMEguzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmlO1o/btsOBZkjmH6/41aXt9ZMYq0nsQ4RMEguzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmlO1o/btsOBZkjmH6/41aXt9ZMYq0nsQ4RMEguzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmlO1o%2FbtsOBZkjmH6%2F41aXt9ZMYq0nsQ4RMEguzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1556&quot; height=&quot;892&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.22.39.png&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;892&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;해당 문제는 2~9의 키패드에 입력가능한 문자가 정의되어있는데요. 특정 digits 가 주어졌을때 해당 digits로 입력 가능한 모든 문자 케이스를 반환하는 문제였습니다. 이때 반환하는 케이스는 문자열 배열 형태로 반환하고, 반환되는 문자열의 순서는 신경 안써도 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;바로 문제 풀어보겠습니다. 보시기 전에, 안푸셨다면 먼저 릿코드에서 해당 문제를 직접 풀어보시고 보시길 추천드립니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;릿코드 swift 문제 풀이 시작&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.30.52.png&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;1166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sSmBM/btsOBeP27qq/chLXuW9dQ5UIq8wDwQkXFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sSmBM/btsOBeP27qq/chLXuW9dQ5UIq8wDwQkXFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sSmBM/btsOBeP27qq/chLXuW9dQ5UIq8wDwQkXFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsSmBM%2FbtsOBeP27qq%2FchLXuW9dQ5UIq8wDwQkXFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1810&quot; height=&quot;1166&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.30.52.png&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;1166&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;문제 풀어볼게요. 3행에서는 digits 입력값이 비었을때의 케이스를 미리 필터링해줍니다. 이때에는 입력가능한 문자가 없으므로 빈 배열을 반환합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;5~16행) 이어서 2 ~ 9의 키패드로 입력가능한 문자들을 digitToLetters에 정의했어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;17~19행) 정답을 넣을 res 배열, digits 길이를 digitsLen에 담아두고, Character 배열의 digitArray도 담아놓습니다. 이렇게 미리 담아놓는 이유가 뭘까요?&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;swift의 String는 일반 배열처럼 간단하게 첨자접근을 하기 어렵습니다. 또한 String 에서 제공하는 인덱스로 접근하는 경우 시간복잡도가 O(N)입니다. 그리고 String count 를 통해 문자열 길이를 반환받을 시에도 시간복잡도가 O(N)입니다. -&amp;gt; 그렇기 때문에 이런 연산이 많아지는 경우에는 미리 해당 결과를 초반에 한번 받아두고 사용하는 것이 더 좋습니다!&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.31.01.png&quot; data-origin-width=&quot;1886&quot; data-origin-height=&quot;1086&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sUKBz/btsOBZkjmKL/hpkCRY2FB3ZCKt3yxTSPk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sUKBz/btsOBZkjmKL/hpkCRY2FB3ZCKt3yxTSPk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sUKBz/btsOBZkjmKL/hpkCRY2FB3ZCKt3yxTSPk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsUKBz%2FbtsOBZkjmKL%2FhpkCRY2FB3ZCKt3yxTSPk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1886&quot; height=&quot;1086&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.31.01.png&quot; data-origin-width=&quot;1886&quot; data-origin-height=&quot;1086&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;backtract 이라는 메서드를 정의했습니다. DFS로 돌리는 메서드입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;21행) backtrack 메서드를 정의합니다. dfs로 활용되며, solution 메서드 내에 중첩 메서드로 정의했습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;22 ~ 25행) &quot;23&quot; 과같은 digits 입력을 받았을때 입력 가능한 문자는 전부 digits 입력 길이와 같은 길이가 됩니다. 따라서 digitsLen과 현재 순회하는 index가 같아지게 될때 (현재 입력된 문자 길이가 digits 길이와 같아지면) 정답으로 쌓아놓습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;27 ~30행) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이 다음 체크해야하는 digitNumber를 반환받습니다. Character 타입에서는 swift 5.1 부터 asciiValue 라는 프로퍼티를 제공합니다. '1' Character 의 asciiValue 에서 48을 빼면, 1 이라는 값을 얻을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;digitNumber로 입력가능한 모든 케이스를 순회하는 모습입니다. 2를 방문한다면, 'a', 'b', 'c'를 추가한 문자열 케이스를 방문하게 됩니다! 그렇게 dfs를 순회하면서 입력가능한 모든 문자열을 res에 쌓게 됩니다. 입력으로 주어진 digits 를 순차적으로 방문하는 케이스이므로 이 이상 복잡한 로직을 필요로 하지 않았어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;문제풀이 끝, 결과를 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;LeetCode swift 문제풀이 후 제출 결과&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.22.25.png&quot; data-origin-width=&quot;1560&quot; data-origin-height=&quot;1622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FQf86/btsOA8oNLxK/VFF8D9f0AgE09jUmHTmIY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FQf86/btsOA8oNLxK/VFF8D9f0AgE09jUmHTmIY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FQf86/btsOA8oNLxK/VFF8D9f0AgE09jUmHTmIY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFQf86%2FbtsOA8oNLxK%2FVFF8D9f0AgE09jUmHTmIY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1560&quot; height=&quot;1622&quot; data-filename=&quot;스크린샷 2025-06-14 오후 7.22.25.png&quot; data-origin-width=&quot;1560&quot; data-origin-height=&quot;1622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Beats 100.00%가 나오네요. 이번 문제의 핵심은 모든 2~9의 키패드로 입력 가능한 모든 케이스를 dfs 등의 순회로 찾을 수 있느냐가 될 것 같고, 그에 따른 기저조건 (더이상 방문할 필요가 없는 케이스를 필터링) 설정도 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;추가로 swift 언어로 풀게 된다면, 유니코드 호환이 가능한 swift 문자열의 원리를 감안하고 count, 첨자접근 방식을 고려해볼 수 있었던 문제였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;해당 문제는 LeetCode study plan에서 풀었습니다. 종종 해당 페이지에 있는 문제를 풀어보려고해요. 지금까지 Letter Combinations of a Phone Number swift 풀이였습니다. 더 좋은 아이디어나 질문이 있다면 언제든 댓글 주세요. 감사합니다~! ☺️&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘 정보/Swift 알고리즘</category>
      <category>LeetCode</category>
      <category>leetcode swift</category>
      <category>Letter Combinations of a Phone Number</category>
      <category>swift algorithm</category>
      <category>swift backtracking</category>
      <category>swift DFS</category>
      <category>Swift 알고리즘</category>
      <category>릿코드</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/442</guid>
      <comments>https://0urtrees.tistory.com/442#entry442comment</comments>
      <pubDate>Sat, 14 Jun 2025 19:56:34 +0900</pubDate>
    </item>
    <item>
      <title>개발자 경력 관련 고민, F-Lab 커리어 관련 멘토 Q&amp;amp;A 참여후기</title>
      <link>https://0urtrees.tistory.com/441</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕하세요~ 개발자 멍구입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요즘 개발자 시장, 특히 주니어나 커리어 전환을 고려하는 분들에게 참 혼란스러운 시기죠. AI로 인한 변화, 채용 트렌드의 급변, 실무 능력과 이력서 준비 등 수많은 고민들이 쏟아지고 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런 상황에서 오늘 F-Lab에서 진행된 &lt;b&gt;Fitz 멘토님의 &quot;무엇이든 물어보세요&quot; 세션&lt;/b&gt;이 진행되었습니다. 무료로 열렸던 행사여서 취업, 이직 고민 있는 지인들께도 공유드리면서 참여해봤어요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;무려 2시간 동안 쉼 없이 질의응답이 진행되었는데요. 개발자 커리어에 대한 실제적인 조언들이 오갔던 시간이었습니다. &lt;br /&gt;몇가지 기억나는 질문에 대한 Fitz 멘토님의 답변을 정리했어요. 커리어에 고민이 많으신 분들께 조금이라도 도움이 되었으면 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-12 오후 11.00.35.png&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baWDAT/btsOAjoYvAR/29XZHALJSSRHkyaJmEh3TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baWDAT/btsOAjoYvAR/29XZHALJSSRHkyaJmEh3TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baWDAT/btsOAjoYvAR/29XZHALJSSRHkyaJmEh3TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaWDAT%2FbtsOAjoYvAR%2F29XZHALJSSRHkyaJmEh3TK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;991&quot; height=&quot;320&quot; data-filename=&quot;스크린샷 2025-06-12 오후 11.00.35.png&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;물경력 5년, 이직은 가능할까요?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 물경력으로 5년 채웠는데, 어떻게 취업 방향을 잡고 발전해야 할지 모르겠어요.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 물경력이라 해도 분명한 장점이 있습니다. 실무에 노출된 만큼 완전 신입보다는 기술 습득 속도가 빠를 수 있어요. 다만, 다시 시작한다는 마음으로 &lt;b&gt;1~2년 정도는 집중적으로 학습하고 포트폴리오를 채우는 걸 추천&lt;/b&gt;드립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음부터 다시 준비한다기보다, 기존의 경험 위에 제대로 된 기반을 쌓는 전략이 중요합니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발자가 꼭 읽어야 할 책은?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 기술력을 쌓기 위해 어떤 책부터 읽으면 좋을까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 아래 책들을 추천드립니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;『객체지향의 사실과 오해』&lt;/b&gt; &amp;ndash; 객체지향 개념을 직관적으로 이해할 수 있어요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;『가상 면접 사례로 배우는 대규모 시스템 설계 기초』&lt;/b&gt; &amp;ndash; 기술 면접 대비에도 좋습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;『한 장 보고서의 정석』&lt;/b&gt; &amp;ndash; 문서나 이력서 작성 능력을 높여주는 필수템입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코딩 테스트, 꼭 잘해야 하나요?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 코딩테스트 준비가 부족해서 걱정이에요. 꼭 잘해야 갈 수 있는 곳이 많을까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 물론, &lt;b&gt;코테를 보는 회사는 많지만, 과제 전형을 택하는 회사도 많아졌어요.&lt;/b&gt; 즉, 다양한 루트를 고려해보세요. 코테 준비는 &lt;b&gt;하루 30분씩이라도 꾸준히&lt;/b&gt; 해보는 걸 권장합니다. 꾸준히, 실행하는 작은 습관이 결국 실력을 만듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;빅테크 도전? 불황기에는 어디든 가는게 나을까요?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 빅테크를 도전해보고 싶은데, 불황기인 지금 도전하는 건 무모한 걸까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 최근에도 토스 등 일부 빅테크는 주니어 채용을 활발히 하고 있어요. 조건만 맞는다면 도전해볼 만합니다. 하지만, &lt;b&gt;지금 내 상황에 맞는 전략도 중요&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내가 꾸준히 학습하고 있는가?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;좋은 동료, 커뮤니티와의 교류가 가능한 환경인가?&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 요소들이 더 큰 성장의 발판이 될 수 있으므로, 이런 환경 조성을 할 수 있도록 합시다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  이력서는 어떻게 써야 눈에 띌까?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 이력서에서 첫인상이 정말 중요하다던데, 가장 중요한 포인트는 뭘까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; &lt;b&gt;첫 장에 '이력서'가 아니라 '제안서'처럼 구성하세요.&lt;/b&gt; 간결하고 눈에 띄는 요약, 키워드 중심의 문장, 직관적인 레이아웃이 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;평균 7초 안에 1차 판단이 된다고 하니, 첫인상을 사로잡는 게 관건이에요.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  이력서/자소서/경력기술서 분량은?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 너무 짧으면 정보가 부족하고, 너무 길면 읽기 싫어집니다. 가장 좋은 전략은:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;앞부분에 &lt;b&gt;요약 및 주요 경력&lt;/b&gt;, 그리고 &lt;b&gt;임팩트 있는 자기 어필&lt;/b&gt;을 담기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;필요하면 몇 장 분량이 돼도 괜찮지만, &lt;b&gt;핵심은 &amp;lsquo;내용의 밀도&amp;rsquo;&lt;/b&gt;입니다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 중요한 한 마디:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;완벽한 이력서는 없습니다. &lt;b&gt;지금의 나를 솔직하면서도 매력적으로 표현하는 것&lt;/b&gt;이 더 중요해요.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이력서에 사진, 꼭 넣어야 할까?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Q. 이력서에 사진을 넣을까요 말까요? 어떤 사진이 좋을지도 고민돼요.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 정답은 없지만, 자신을 충분히 어필할 수 있는&lt;b&gt;&amp;nbsp;이미지 1~2장을 첨부&lt;/b&gt;하는 것도 괜찮습니다. 단, 너무 강조하진 마세요. 핵심은 여전히 &lt;b&gt;내용&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커뮤니케이션 능력 키우는 법&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 개발자에게도 커뮤니케이션은 필수 역량입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #333333; text-align: start;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멘토링을 해보거나&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;자신있게 무대뽀로 설명해보는 습관&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;동료들과 자주 이야기 나누며 피드백 받기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 활동들이 &lt;b&gt;생각 정리력, 전달력, 협업 능력&lt;/b&gt;등의 전반적인 커뮤니케이션 능력을 빠르게 키워줍니다.&lt;br /&gt;+ SBI(Situation, Behavior, Impact) 상황/행동/임팩트 기반으로 대화하는 습관을 가지고, 평소 회의나 커뮤니케이션 간에 주위를 환기시킨 후 대화해보는 습관도 가지면 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  피츠 멘토님의 마지막 한 마디&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;ldquo;자유롭게, 내 생각을 공유하세요. 꼭 정답일 필요는 없어요. &lt;b&gt;표현하고 나누는 것 자체가 성장의 시작&lt;/b&gt;입니다.&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알고리즘 스터디, 진짜 도움 될까?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 네! 심지어 &lt;b&gt;참여자도 많지 않아서, 깊은 교류와 집중 학습이 가능합니다.&lt;/b&gt; 알고리즘 스터디를 주도하고 계신 f-lab 멘토님 제이슨님과도 가까워질 수 있고요. 좋은 사람들과의 연결은 또 다른 기회로 이어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마무리하며&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번 세션을 통해 많은 분들이 위로와 자극을 동시에 받았던 것 같아요. 불확실한 시대에 개발자로 살아남는 건 쉽지 않지만, &lt;b&gt;꾸준한 학습과 열린 태도, 그리고 나를 어필할 수 있는 전략&lt;/b&gt;이 있다면 길은 분명히 있다고 생각해요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저도 오늘 얻은 인사이트들을 바탕으로 다시 한번 방향을 정리해보려 합니다. 이 글이 여러분의 커리어에도 작은 나침반이 되길 바랍니다!  &lt;/span&gt;&lt;/p&gt;</description>
      <category>일상 팁</category>
      <category>f lab 멘토링</category>
      <category>f-lab 강의</category>
      <category>f-lab 멘토링</category>
      <category>에프랩 강의</category>
      <category>에프랩 멘토링</category>
      <category>에프랩 행사</category>
      <author>applebuddy</author>
      <guid isPermaLink="true">https://0urtrees.tistory.com/441</guid>
      <comments>https://0urtrees.tistory.com/441#entry441comment</comments>
      <pubDate>Fri, 13 Jun 2025 01:05:17 +0900</pubDate>
    </item>
  </channel>
</rss>