<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>어쩌다보니 iOS 개발자</title>
    <link>https://dongmindevloper.tistory.com/</link>
    <description>안녕하세요. iOS 개발자입니다..
</description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 20:58:39 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>엔디엘(no Dream no Life)</managingEditor>
    <item>
      <title>클로저와 렉시컬 스코프란?</title>
      <link>https://dongmindevloper.tistory.com/79</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1) 스코프와 &amp;ldquo;외부 스코프&amp;rdquo;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;스코프(scope)&lt;/b&gt;&lt;/span&gt;: 변수를 &amp;ldquo;어디서 접근할 수 있는지&amp;rdquo;의 범위&lt;/li&gt;
&lt;li&gt;&lt;b&gt;외부 스코프(outer scope)&lt;/b&gt;&lt;span&gt;: 지금 함수 기준으로 &lt;/span&gt;&lt;b&gt;바깥에 있는 스코프&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function outer() {
  let x = 10;
  function inner() {
    console.log(x); // inner 입장에선 x가 &quot;외부 스코프 변수&quot;
  }
}&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2) 렉시컬 스코프(Lexical Scope)란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 줄로:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;함수의 스코프(외부 변수 참조 기준)는 &amp;ldquo;호출 위치&amp;rdquo;가 아니라 &amp;ldquo;작성 위치&amp;rdquo;로 결정된다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let a = &quot;global&quot;;

function test() {
  console.log(a);
}

function run() {
  let a = &quot;run&quot;;
  test();
}

run(); // &quot;global&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜 &lt;/span&gt;&quot;run&quot;&lt;span&gt;이 아니라 &lt;/span&gt;&quot;global&quot;&lt;span&gt;?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;b&gt;전역에서 작성&lt;/b&gt;&lt;span&gt;됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;그래서 &lt;span&gt;test&lt;/span&gt;가 변수를 찾을 때 기준이 되는 바깥은 &lt;span&gt;&lt;b&gt;전역 스코프&lt;/b&gt;&lt;/span&gt;로 &amp;ldquo;고정&amp;rdquo;&lt;/li&gt;
&lt;li&gt;호출을 run에서 했든 어디서 했든 상관 없음&lt;/li&gt;
&lt;li&gt;&amp;rarr; 이 규칙이 &lt;span&gt;&lt;b&gt;렉시컬 스코프&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3) 클로저(Closure)란?&lt;/b&gt;&lt;/h2&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;ldquo;특별한 문법&amp;rdquo;이 아니라 &lt;span&gt;&lt;b&gt;현상/특성&lt;/b&gt;&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;한 줄 정의:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;함수가 자신이 작성된 위치의 &amp;ldquo;외부 스코프(렉시컬 환경)&amp;rdquo;를 기억(참조 유지)해서, 나중에도 그 변수에 접근할 수 있는 것.&lt;/b&gt;&lt;/blockquote&gt;
&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&gt;핵심은 &lt;/span&gt;&lt;b&gt;함수 자체를 기억한다&lt;/b&gt;&lt;span&gt;가 아니라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;✅ &lt;/span&gt;&lt;b&gt;그 함수가 만들어질 당시의 &amp;ldquo;변수 환경(렉시컬 환경)&amp;rdquo;을 참조한다&lt;/b&gt;&lt;span&gt;는 점.&lt;/span&gt;&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4) 클로저 원리(왜 outer가 끝났는데 변수는 살아있나)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표 예:&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function outer() {
  let x = 10;

  return function inner() {
    console.log(x);
  };
}

const f = outer();
f(); // 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 일어나는 일:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;outer()&lt;/span&gt; 실행 &amp;rarr; &lt;span&gt;x=10&lt;/span&gt;이 들어있는 &amp;ldquo;환경(렉시컬 환경)&amp;rdquo; 생성&lt;/li&gt;
&lt;li&gt;&lt;span&gt;inner&lt;/span&gt; 함수 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이때 &lt;span&gt;inner&lt;/span&gt;는 내부적으로 &lt;span&gt;&lt;b&gt;[[Environment]]&lt;/b&gt;&lt;/span&gt; 같은 슬롯에&lt;/li&gt;
&lt;li&gt;&amp;ldquo;내가 작성된 위치의 바깥 환경(outer의 환경)&amp;rdquo;을 &lt;span&gt;&lt;b&gt;참조로 저장&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;outer&lt;/span&gt; 실행이 끝나도
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;inner&lt;/span&gt;가 그 환경을 계속 참조하고 있으니&lt;/li&gt;
&lt;li&gt;GC가 지우지 못함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;그래서 &lt;span&gt;f()&lt;/span&gt; (= inner 호출) 시에도 &lt;span&gt;x&lt;/span&gt;를 찾을 수 있음&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&amp;ldquo;함수(inner)가 외부 환경을 참조하고 있어서 그 환경이 살아남는 것&amp;rdquo;&lt;/b&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;(outer 함수를 붙잡는 게 아님)&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5) f1 / f2 예시가 말해주는 핵심&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function outer() {
  let x = 0;
  return function () {
    x++;
    console.log(x);
  };
}

const f1 = outer();
const f2 = outer();

f1(); // 1
f1(); // 2
f2(); // 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 f2는 1부터 시작해?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;outer()&lt;/span&gt;는 호출될 때마다 &lt;span&gt;&lt;b&gt;새 렉시컬 환경&lt;/b&gt;&lt;/span&gt;을 만든다&lt;/li&gt;
&lt;li&gt;f1은 환경 A의 x를, f2는 환경 B의 x를 잡고 있음&lt;/li&gt;
&lt;li&gt;&amp;rarr; 값이 같아 보여도 &amp;ldquo;서로 다른 변수 공간&amp;rdquo;을 잡고 있는 거야&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6) 왜 클로저를 사용하는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 상태 유지 (state 유지)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function makeCounter() {
  let c = 0;
  return () =&amp;gt; ++c;
}
const counter = makeCounter();
counter(); // 1
counter(); // 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 호출이 끝나도 &lt;span&gt;c&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 은닉(캡슐화, private 변수)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function createUser() {
  let password = &quot;secret&quot;;
  return {
    check(p) { return p === password; }
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에서 password 직접 접근 불가.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 함수 팩토리(설정값 고정한 함수 만들기)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const multiply = x =&amp;gt; y =&amp;gt; x * y;
const double = multiply(2);
double(5); // 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(4) 콜백/비동기에서 값 보존&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 핸들러, setTimeout, Promise 콜백 등에서 &amp;ldquo;그때의 문맥&amp;rdquo;을 유지.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7) 렉시컬 스코프 &amp;harr; 클로저 관계 한 문장&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;렉시컬 스코프는 &amp;ldquo;바깥이 누구인지(작성 위치 기준)&amp;rdquo;를 고정하는 규칙이고,&lt;/b&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;그 고정된 바깥 환경을 함수가 계속 참조해서 살아남는 현상이 클로저다.&lt;/b&gt;&lt;/blockquote&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;렉시컬 스코프(규칙) 때문에&lt;/li&gt;
&lt;li&gt;함수는 &amp;ldquo;작성된 위치의 외부 환경&amp;rdquo;을 기준으로 변수를 찾고&lt;/li&gt;
&lt;li&gt;그 환경 참조가 남아 있으면&lt;/li&gt;
&lt;li&gt;&amp;rarr; 클로저가 된다&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8) React Native/React에서 특히 중요한 이유(짧게)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RN은 JS Thread가 바쁘면 UI도 영향을 받음&lt;/li&gt;
&lt;li&gt;클로저는 많이 쓰이지만 &lt;span&gt;&lt;b&gt;stale closure(오래된 상태를 캡처)&lt;/b&gt;&lt;/span&gt; 같은 버그가 생기기 쉬움&lt;/li&gt;
&lt;li&gt;(예: useEffect, setTimeout 콜백에서 과거 state를 보는 문제)&lt;/li&gt;
&lt;/ul&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;</description>
      <category>React Native 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/79</guid>
      <comments>https://dongmindevloper.tistory.com/79#entry79comment</comments>
      <pubDate>Fri, 13 Feb 2026 12:26:09 +0900</pubDate>
    </item>
    <item>
      <title>Event Loop(이벤트 루프) 완전 정리</title>
      <link>https://dongmindevloper.tistory.com/78</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;✅ 결론부터&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;자바스크립트는 싱글 스레드이며,&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span&gt;이벤트 루프는 &lt;/span&gt;&lt;b&gt;Call Stack이 비었을 때 대기 중인 작업을 실행하도록 조정하는 반복 제어 메커니즘&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span&gt;비동기 작업은 JS 밖에서 병렬로 수행될 수 있지만, &lt;/span&gt;&lt;b&gt;JS 코드 실행은 항상 단일 스레드에서 순차적으로 이루어진다.&lt;/b&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  그렇다면 왜 이벤트 루프를 알아야 할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비동기 실행 순서를 예측하고, 실제 버그를 해결하기 위해서다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1️⃣ 실행 순서를 정확히 예측하기 위해&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;setTimeout(() =&amp;gt; console.log(&quot;A&quot;), 0);
Promise.resolve().then(() =&amp;gt; console.log(&quot;B&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 &lt;span&gt;B&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;ldquo;그냥 그렇다&amp;rdquo;가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 루프를 이해하면:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;Microtask &amp;rarr; Task 순서 때문이라고 설명할 수 있다.&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2️⃣ UI 멈춤(블로킹)을 이해하기 위해&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;while (true) {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드 한 줄이면:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버튼 클릭 안 됨&lt;/li&gt;
&lt;li&gt;애니메이션 멈춤&lt;/li&gt;
&lt;li&gt;Promise 실행 안 됨&lt;/li&gt;
&lt;li&gt;setTimeout 실행 안 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;Call Stack이 비지 않으면 이벤트 루프가 돌지 못하기 때문이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native에서도 JS Thread가 막히면 UI가 끊긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 이해하려면 이벤트 루프를 알아야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3️⃣ async / await를 제대로 이해하기 위해&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;await something();
console.log(&quot;done&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;await&lt;/span&gt;는 코드를 멈추는 것이 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나머지를 Microtask로 넘기는 것&lt;/b&gt;&lt;span&gt;이다.&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;이걸 이해하면:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왜 await 이후 코드가 나중에 실행되는지&lt;/li&gt;
&lt;li&gt;왜 병렬 처리를 위해 Promise.all이 필요한지&lt;/li&gt;
&lt;li&gt;왜 루프 안에서 await를 쓰면 느려지는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 설명할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4️⃣ React / React Native 동작을 이해하기 위해&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 왜 바로 반영되지 않는가?&lt;/li&gt;
&lt;li&gt;왜 setTimeout(0)이 완전히 즉시 실행되지 않는가?&lt;/li&gt;
&lt;li&gt;왜 JS 연산이 길어지면 화면이 끊기는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모든 질문의 근본에는 이벤트 루프가 있다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  최종 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 루프를 이해한다는 것은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자바스크립트의 실행 모델을 이해하는 것&lt;/b&gt;&lt;span&gt;이다.&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;그 결과:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 순서를 예측할 수 있고&lt;/li&gt;
&lt;li&gt;비동기 버그를 줄일 수 있고&lt;/li&gt;
&lt;li&gt;UI 블로킹을 방지할 수 있으며&lt;/li&gt;
&lt;li&gt;프레임워크 동작을 이해할 수 있다&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;원하면 글 전체를 더 다듬어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &amp;ldquo;입문자용 부드러운 설명 스타일&amp;rdquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &amp;ldquo;기술 블로그 느낌의 구조적 설명 스타일&amp;rdquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &amp;ldquo;면접 대비용 압축형 글&amp;rdquo;&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;중 하나로 톤을 맞춰서 완성본 만들어줄까요?&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;h1&gt;&lt;b&gt;1. 자바스크립트는 싱글 스레드다&lt;/b&gt;&lt;/h1&gt;
&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&gt;&lt;b&gt;Call Stack 하나&lt;/b&gt;&lt;/span&gt;만 가진다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(&quot;A&quot;);
console.log(&quot;B&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 절대 동시에 실행될 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항상 A &amp;rarr; B 순서로 실행된다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;2. 그런데 어떻게 비동기가 가능한가?&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 이것이다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;JS 코드 실행은 싱글 스레드지만,&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;비동기 작업은 JS 밖에서 처리된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;setTimeout&lt;/span&gt; &amp;rarr; 브라우저/네이티브 타이머&lt;/li&gt;
&lt;li&gt;&lt;span&gt;fetch&lt;/span&gt; &amp;rarr; 네트워크 스택&lt;/li&gt;
&lt;li&gt;파일 I/O &amp;rarr; OS 레벨 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 작업들은 JS 스레드가 아니라 **런타임 환경(브라우저/네이티브)**에서 병렬로 처리된다.&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;작업이 끝나면:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;콜백이 Queue에 등록됨&lt;/li&gt;
&lt;li&gt;이벤트 루프가 Call Stack이 비었을 때 실행&lt;/li&gt;
&lt;/ol&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;3. 이벤트 루프란 무엇인가?&lt;/b&gt;&lt;/h1&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;ldquo;공간&amp;rdquo;이 아니라 &lt;span&gt;&lt;b&gt;로직&lt;/b&gt;&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;개념적으로는 다음과 같다:&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;while (프로그램이 살아있는 동안) {
  if (CallStack이 비어있으면) {
    Microtask 전부 실행
    Task 하나 실행
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;4. Call Stack / Microtask / Task 차이&lt;/b&gt;&lt;/h1&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  Call Stack&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 실행 중인 코드&lt;/li&gt;
&lt;li&gt;JS는 한 번에 하나만 실행&lt;/li&gt;
&lt;/ul&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  Microtask Queue&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Promise.then&lt;/li&gt;
&lt;li&gt;async/await 이후 코드&lt;/li&gt;
&lt;li&gt;queueMicrotask&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Call Stack이 비면 &lt;span&gt;&lt;b&gt;전부 실행&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  Task Queue (Macrotask)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;setTimeout&lt;/li&gt;
&lt;li&gt;setInterval&lt;/li&gt;
&lt;li&gt;I/O&lt;/li&gt;
&lt;li&gt;이벤트 핸들러&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 번에 하나만 실행&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;5. 실행 순서의 핵심 규칙&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 루프의 핵심 규칙:&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;동기 코드 실행
&amp;rarr; Microtask 전부 실행
&amp;rarr; Task 하나 실행
&amp;rarr; 반복&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;console.log(&quot;1&quot;);

setTimeout(() =&amp;gt; console.log(&quot;2&quot;), 0);

Promise.resolve().then(() =&amp;gt; console.log(&quot;3&quot;));

console.log(&quot;4&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
4
3
2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기: 1, 4&lt;/li&gt;
&lt;li&gt;Microtask: 3&lt;/li&gt;
&lt;li&gt;Task: 2&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;6. async / await는 무엇을 하는가?&lt;/b&gt;&lt;/h1&gt;
&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&gt;await&lt;/span&gt;는 실행을 멈추는 것이 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;나머지 코드를 Microtask로 넘기는 문법적 설탕(syntax sugar)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;async function test() {
  console.log(&quot;1&quot;);
  await Promise.resolve();
  console.log(&quot;2&quot;);
}

test();
console.log(&quot;3&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3
2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;await&lt;/span&gt; 뒤는 항상 Microtask에서 실행된다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;7. 그렇다면 비동기는 진짜 비동기인가?&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 표현은 이렇다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;작업 수행은 병렬일 수 있다.&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;JS 코드 실행은 절대 병렬이 아니다.&lt;/blockquote&gt;
&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&gt;fetch&lt;/span&gt;는 병렬로 네트워크 요청을 수행하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜백 실행은 JS 스레드에서 순차적으로 이루어진다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;8. React Native 기준으로 보면&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native도 기본적으로 &lt;span&gt;&lt;b&gt;JS Thread 하나&lt;/b&gt;&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;구조는 다음과 같다:&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;JS Thread
&amp;uarr;
이벤트 루프
&amp;uarr;
Native Modules / OS / Network&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 요청 &amp;rarr; 네이티브에서 병렬 처리&lt;/li&gt;
&lt;li&gt;완료 &amp;rarr; JS Queue에 등록&lt;/li&gt;
&lt;li&gt;JS Thread가 순차 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JS에서 무거운 연산을 하면 UI가 멈춘다&lt;/li&gt;
&lt;li&gt;타이머도 지연된다&lt;/li&gt;
&lt;li&gt;Promise도 대기한다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐하면 JS Thread는 하나뿐이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React Native 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/78</guid>
      <comments>https://dongmindevloper.tistory.com/78#entry78comment</comments>
      <pubDate>Fri, 13 Feb 2026 11:49:31 +0900</pubDate>
    </item>
    <item>
      <title>호이스팅을 알아야 하는 이유는??</title>
      <link>https://dongmindevloper.tistory.com/77</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;  최종 결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;실무에서는 호이스팅에 절대 의존하지 마세요!
- ❌ var, function 선언식 사용 금지
- ✅ const/let + 함수 표현식/화살표함수 + &quot;위 선언, 아래 사용&quot;

ESLint로 방지

{
  &quot;extends&quot;: [&quot;eslint:recommended&quot;, &quot;plugin:react/recommended&quot;],
  rules: {
      // 호이스팅 방지 규칙
      &quot;@typescript-eslint/no-use-before-define&quot;: [
        &quot;error&quot;,
        {
          functions: true,
          classes: true,
          variables: false,
          typedefs: true,
        },
      ],
      &quot;no-var&quot;: &quot;error&quot;, // var 키워드 사용 금지
      &quot;prefer-const&quot;: &quot;error&quot;, // 재할당하지 않는 변수는 const 사용 강제
      &quot;func-style&quot;: [&quot;error&quot;, &quot;expression&quot;, { allowArrowFunctions: true }], // arrow function 사용 강제
    },
}&lt;/code&gt;&lt;/pre&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 왜 이런 결론인가? &amp;rarr; var의 치명적 문제&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// 조용한 런타임 버그의 시작
console.log(user.name);  // undefined.name &amp;rarr; TypeError (프로덕션!)
var user = await fetchUser();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;var는 선언 전에 undefined를 줘서 에러 없이 잘못된 로직이 진행됨&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉 런타임 에러!!&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. let/const는 안전장치지만 여전히 문제&lt;/h2&gt;
&lt;pre class=&quot;gml&quot;&gt;&lt;code&gt;console.log(x);  // ReferenceError (개발중 잡힘)
let x = 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;호이스팅에 의존하려 하면 TDZ 에러 &amp;rarr; 결국 순서 지켜야 함&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 함수 선언식도 혼란만 줌&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;sayHello();  // 어디서 정의됐지? 언제 덮어쓰였지?
function sayHello() { console.log('hello'); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;호이스팅 때문에 코드 순서가 뒤죽박죽 &amp;rarr; 가독성 최악&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 그래서 나온 실무 표준&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;❌ 피할 것&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;✅ 권장 패턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;var x = 0&lt;/td&gt;
&lt;td&gt;const x = 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;function foo() {}&lt;/td&gt;
&lt;td&gt;const foo = () =&amp;gt; {}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;아래 선언 위 사용&lt;/td&gt;
&lt;td&gt;TOP 선언 BOTTOM 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. React Native 실제 동작&lt;/h2&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;// Metro bundler가 전체 파일 분석 (호이스팅 아님!)
const styles = StyleSheet.create({...});  // TOP 선언
&amp;lt;View style={styles.container} /&amp;gt;         // 안전 사용
&lt;/code&gt;&lt;/pre&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;h2 data-ke-size=&quot;size26&quot;&gt;  한 줄 비유&lt;/h2&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;호이스팅 = 호이스팅을 이해하여 의도하지 않는 버그가 발생되는 걸 막자
       &amp;ne; &quot;개발 편의를 위한 기능&quot;&lt;/code&gt;&lt;/pre&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;실무에서의 한계점(리스크)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lint에서 variables를 false로 설정을 했는데 사실 이것도 true로 해야지 호이스팅으로 생기는 버그를 미연에 방지할 수 있을 것이다. 하지만 실제로 나는 스크린 컴포넌트 기준으로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수선언, useState, hook, 상수선언 등&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이프사이클 커스텀 hook&lt;br /&gt;함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI&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; 여기서 variables가 true가 되면 생기는 문제는 라이플사이클 커스텀 hook인데, 스크린 컴포넌트에서는 나는 라이프 싸이클 공통화 할 수 있는 커스텀 훅을 항상 필수로 사용하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772600658480&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 2. 라이프사이클 관리
  useScreenLifecycle({
    firstFocus: () =&amp;gt; {
      // 컴포넌트 마운트 시 탭 인증 값 체크 (한 번만 실행)
    },
    focus: () =&amp;gt; {
      // 화면 재포커스 시 로직 (필요시)
    },
    blur: () =&amp;gt; {
      // 화면 포커스 잃을 때 로직 (필요시)
    },
    unmount: () =&amp;gt; {
      // 컴포넌트 언마운트 시 정리 작업
    },
  });&lt;/code&gt;&lt;/pre&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;</description>
      <category>React Native 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/77</guid>
      <comments>https://dongmindevloper.tistory.com/77#entry77comment</comments>
      <pubDate>Fri, 13 Feb 2026 10:25:36 +0900</pubDate>
    </item>
    <item>
      <title>React-Native 프로젝트 그린필드 리팩토링 시작 - 기존 앱 분석</title>
      <link>https://dongmindevloper.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&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;갑자기 왜 iOS -&amp;gt; Android로 작업하다가 이걸 하나 ㅎㅎ 궁금해 하실분은 아무도 안계시겠지만..&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;현재 직장 대표님에게 사실대로 말씀드리고 육아휴직을 신청하여 이직을 준비하고 있었지만... 사실 육아휴직 비용으로&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;저희 가족이 생활하기에는 너무 부족하더라구요. 그래서 육아휴직중에도 월 150만원 이상만 넘지 않는다면 괜찮다고 하여.. 우연한 계기로.. 프리랜서를 하게되었습니다.!!&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;어떤 앱인지는 말씀드리지 못하겠지만 기존에 많은 인도 개발자들이 손을 건너왔다고합니다..&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;듣기로는 빌드도 안되고 배포한건 안드로이드 최소버전 조건이 안맞아서 안되고.. 현재 출시된 버전은 이것저것 할때마다 앱은 죽고.. 다른 개발자가 맡다가 그냥.... 안한다고 하셨다고 하더라구요..&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;일단 제가 눈으로 하나하나 파악하는것 보다는 Cluade에게 분석 요청을 했습니다.&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  ~~~~~~ 프로젝트 분석 결과&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ️ 기본 정보&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;앱명&lt;/b&gt;: ~~~~~&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버전&lt;/b&gt;: ~~~&lt;/li&gt;
&lt;li&gt;&lt;b&gt;React Native 버전&lt;/b&gt;: 0.70.9&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TypeScript&lt;/b&gt;: 부분 적용 (4.3.2)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  프로젝트 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클린 아키텍처 패턴 적용&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;nsis&quot;&gt;&lt;code&gt;src/
├── components/     # 재사용 가능한 UI 컴포넌트
├── screens/       # 화면별 컴포넌트
├── containers/    # 비즈니스 로직이 포함된 컴포넌트
├── navigation/    # 네비게이션 설정
├── reduxs/        # 상태관리 (Redux + Redux-Saga)
├── services/      # API 통신
├── utils/         # 유틸리티 함수
├── assets/        # 이미지, 폰트 등 정적 자원
├── i18n/          # 다국어 지원
├── configs/       # 환경설정
└── constants/     # 상수 정의

&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;b&gt;  주요 기술 스택&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;상태 관리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Redux&lt;/b&gt; + &lt;b&gt;Redux-Saga&lt;/b&gt; + &lt;b&gt;Redux-Persist&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ReduxSauce&lt;/b&gt; (액션/리듀서 생성 헬퍼)&lt;/li&gt;
&lt;li&gt;AsyncStorage &amp;amp; Keychain을 통한 데이터 영속화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;네비게이션&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;React Navigation 6&lt;/b&gt; (최신 버전)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stack Navigator (메인 네비게이션)&lt;/li&gt;
&lt;li&gt;Bottom Tab Navigator (하단 탭)&lt;/li&gt;
&lt;li&gt;Material Top Tabs (상단 탭)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;UI/스타일링&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Styled Components&lt;/b&gt; (CSS-in-JS)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;React Native Size Matters&lt;/b&gt; (반응형 디자인)&lt;/li&gt;
&lt;li&gt;커스텀 컴포넌트 시스템 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개발 도구&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Reactotron&lt;/b&gt; (디버깅 도구)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CodePush&lt;/b&gt; (OTA 업데이트)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flipper&lt;/b&gt; 호환 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  주요 기능 및 특징&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. ~~~~~ 플랫폼&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;~~~~~~&lt;/li&gt;
&lt;li&gt;프로필 및 예약 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 멀티플랫폼 빌드 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;json
// 환경별 빌드 스크립트
&quot;android:dev&quot;: &quot;development 환경&quot;
&quot;android:stg&quot;: &quot;staging 환경&quot;
&quot;android:prod&quot;: &quot;production 환경&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 소셜 로그인&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Google Sign-In&lt;/li&gt;
&lt;li&gt;Apple Authentication&lt;/li&gt;
&lt;li&gt;Facebook SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 결제 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Stripe&lt;/b&gt; 결제 연동&lt;/li&gt;
&lt;li&gt;쿠폰 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 미디어 처리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카메라/이미지 피커&lt;/li&gt;
&lt;li&gt;비디오 재생 (react-native-video)&lt;/li&gt;
&lt;li&gt;이미지 리사이징 및 썸네일 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 실시간 기능&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Firebase&lt;/b&gt; (푸시 알림, 실시간 DB)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;~~~~~~&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS S3&lt;/b&gt; 파일 업로드&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. 다국어 지원&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;i18next&lt;/b&gt; + &lt;b&gt;react-i18next&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;한국어, 영어, 일본어 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  보안 &amp;amp; 인증&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;JWT 토큰&lt;/b&gt; 기반 인증&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Keychain&lt;/b&gt; 보안 저장소&lt;/li&gt;
&lt;li&gt;이메일 인증 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  성능 최적화&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Redux-Persist&lt;/b&gt; (상태 영속화)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Patch-Package&lt;/b&gt; (라이브러리 패치)&lt;/li&gt;
&lt;li&gt;이미지 최적화 및 캐싱&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  아키텍처 특징&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;체계적인 폴더 구조&lt;/b&gt; - 확장성과 유지보수성 우수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;검증된 기술 스택&lt;/b&gt; - 안정적인 라이브러리 조합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;다국어/다환경 지원&lt;/b&gt; - 글로벌 서비스 준비&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;실시간 기능&lt;/b&gt; - 의료 상담에 필수적인 기능들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;포괄적인 인증 시스템&lt;/b&gt; - 다양한 로그인 옵션&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개선 포인트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ &lt;b&gt;React Native 버전&lt;/b&gt; - 0.70.9 (최신 0.74+로 업그레이드 권장)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ &lt;b&gt;TypeScript 완전 도입&lt;/b&gt; - 부분적 적용으로 타입 안정성 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ &lt;b&gt;New Architecture 미적용&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;b&gt;  도메인별 특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;~~~ 앱&lt;/b&gt;으로서 HIPAA 준수를 위한 보안 기능들과 실시간 상담을 위한 채팅/비디오 기능이 잘 구현되어 있는 &lt;b&gt;성숙한 프로덕션 앱&lt;/b&gt; 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전반적으로 &lt;b&gt;잘 설계된 엔터프라이즈급 React Native 앱&lt;/b&gt;이며, 의료 도메인의 복잡한 요구사항들을 체계적으로 해결한 아키텍처입니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 전체적은 구조는.. 나쁘지않아 보이지만.. 시작은 좋았던거 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흠.. 일단 자바스크립트로 많이 개발되어있고 가끔씩 타입스크립트로 개발된 부분도 있네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 iOS, 안드로이드 네이티브 모듈도 있고 각각 네이티브 화면으로 개발되어있습니다. 디바이스 연동이 되어있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RN버전도 낮고 일관되지 않은 코드 컨벤션, 정리되지 않은 컴포넌트, assets 이미지는 다 깨져있는걸 사용하고 있네요.. 왜이렇게 작은지 ㅠ&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;일단 상황을 말씀드렸고 제안을 드렸습니다.&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;메인 기능까지는 새로운 프로젝트를 만들어서 출시까지 하는게 어떻겠습니까 ㅠㅠㅠ?&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;만약 유저가 있다면 이런 결정은 절대할 수 없었을것이고, AI가 없었다면 저는 한달이라는 말도안되는 일정을 말씀도 못드렸을 것 같습니다.&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;그래서 그렇게 시작을 하게되었습니다.&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;새로운 프로젝트를 이렇게 구성하기로 했습니다.&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-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h1&gt;  &lt;b&gt;프로젝트 최종 확정 사항&lt;/b&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;프로젝트 기본 설정&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;생성 방식&lt;/b&gt;: React Native CLI&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로젝트명&lt;/b&gt;: ~~~~~~&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Bundle ID&lt;/b&gt;: 기존과 동일&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TypeScript&lt;/b&gt;: Strict 모드 활성화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;환경 변수&lt;/b&gt;: react-native-config (.env.development, .env.staging, .env.production)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ &lt;b&gt;아키텍처 &amp;amp; 핵심 기술&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;아키텍처&lt;/b&gt;: Feature-Sliced Design (FSD)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상태 관리&lt;/b&gt;: Zustand + TanStack Query&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로컬 저장소&lt;/b&gt;: React Native MMKV&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UI 프레임워크&lt;/b&gt;: NativeWind (기본) + React Native Paper (선택적)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네비게이션&lt;/b&gt;: React Navigation 6&lt;/li&gt;
&lt;li&gt;&lt;b&gt;애니메이션&lt;/b&gt;: React Native Reanimated 3&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;테스트 &amp;amp; 문서화&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;단위/통합 테스트&lt;/b&gt;: Jest + React Native Testing Library&lt;/li&gt;
&lt;li&gt;&lt;b&gt;E2E 테스트&lt;/b&gt;: Maestro&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;모니터링 도구&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;크래시 리포팅&lt;/b&gt;: Sentry ✨&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용자 분석&lt;/b&gt;: Firebase Analytics&lt;/li&gt;
&lt;li&gt;&lt;b&gt;성능 모니터링&lt;/b&gt;: Firebase Performance&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ &lt;b&gt;개발 도구&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;통합 개발 환경&lt;/b&gt;: VS Code(확장: ES7+ React/Redux/React-Native snippets, TypeScript Importer, Tailwind CSS IntelliSense, TypeScript Importer, ESLint, Prettier)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상태 디버깅&lt;/b&gt;: React Native Debugger&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시스템 디버깅&lt;/b&gt;: Flipper&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상태 관리 디버깅&lt;/b&gt;: Zustand devtools&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;코드 컨벤션&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;파일 네이밍&lt;/b&gt;: kebab-case&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Export 방식&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pages: default export&lt;/li&gt;
&lt;li&gt;Features/Widgets/Shared: named export&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;폴더 구조&lt;/b&gt;: 각 폴더마다 index.ts 파일로 export 정리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;절대 경로&lt;/b&gt;: @ 별칭 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포맷팅&lt;/b&gt;: VS Code 자동 저장시 포맷팅 (ESLint/Prettier)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ &lt;b&gt;FSD 폴더 구조&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;src/
├── app/           # 앱 레벨 설정 (providers, navigation, store)
├── pages/         # 화면 컴포넌트 (라우팅 단위)
├── widgets/       # 복합 위젯 (여러 features 조합)
├── features/      # 독립적 비즈니스 기능
├── entities/      # 비즈니스 엔티티 (user, ~~, ~~)
└── shared/        # 공통 리소스 (UI, API, utils)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네이티브 모듈을 만들어야 하기 때문에 expo 보다는 CLI를 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new Archtecture는 아직 도입이 이르다고 판단하였습니다. 아직 모든 라이브러리가 대응한 상태가 아니기 때문입니다.&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;Styled-Component/native은 이제 지원을 하지 않기 때문에&amp;nbsp; NativeWind로 변경하기로 했고, 상태관리는 redux toolkit, zustand중에 고민했지만 아무래도 개발자 인력도 없고, 빠르기 개발 가능해야하고, 보일러 플레이트코드가 적은 zustand로 결정했습니다.&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;br /&gt;&lt;br /&gt;감사합니다.&lt;/p&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/76</guid>
      <comments>https://dongmindevloper.tistory.com/76#entry76comment</comments>
      <pubDate>Wed, 25 Jun 2025 15:14:39 +0900</pubDate>
    </item>
    <item>
      <title>Cursor로 React Native 개발을 해보자 (1) - 세팅</title>
      <link>https://dongmindevloper.tistory.com/75</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 Cursor IDE로 RN 개발을 해보려고 합니다.&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;iOS를 개발할때는 워낙 자동완성, 스닙펫 등이 잘 되어 있어서 편한지 몰랐는데 VScode로 RN개발을 시작하고 나니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;그래서 어쩔 수 없이 개인적으로 해당 프로젝트에 맞는 스닙펫을 추가하였고 코드를 치는 시간을 단축하면서 개발을 해왔었습니다.&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;근데 이제 그걸 Cursor가 기똥차게 지원을 해준다고 하니.. 안해볼 수 없겠죠.. 사실 늦은감이었지만.. 지금이라도 무료 기간 2주동안 사용하면서 정말 필요할지 아니면 Vscode로 그대로 개발해도 문제없을지 경험을 해보겠습니다.&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;IDE만 변경하는거라서 세팅할건 따로 많이 없을 것 같네요.&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;이제부터 Claude, Perplexity에게 물어보면서 세팅을 진행해볼게요~&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;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&amp;nbsp;VSCode&amp;nbsp;확장&amp;nbsp;프로그램(Extensions)&amp;nbsp;이식&lt;/b&gt;&lt;br /&gt;&amp;bull; Cursor&amp;nbsp;설치&amp;nbsp;시,&amp;nbsp;VSCode에서&amp;nbsp;사용하던&amp;nbsp;확장&amp;nbsp;프로그램과&amp;nbsp;설정을&amp;nbsp;&amp;ldquo;원클릭&amp;rdquo;으로&amp;nbsp;가져올&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;설치&amp;nbsp;후&amp;nbsp;첫&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;Import&amp;nbsp;옵션을&amp;nbsp;선택하세요.&lt;br /&gt;&amp;bull; 만약 건너뛰었다면, Cursor의 Extension Marketplace에서 필요한 확장을 직접 설치할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native, ESLint, Prettier, GitLens, CodePush 등 기존에 쓰던 확장 대부분이 호환됩니다.&lt;br /&gt;&lt;b&gt;2.&amp;nbsp;빌드&amp;nbsp;및&amp;nbsp;실행&amp;nbsp;환경&lt;/b&gt;&lt;br /&gt;&amp;bull; React&amp;nbsp;Native의&amp;nbsp;Metro,&amp;nbsp;esbuild&amp;nbsp;등&amp;nbsp;기존&amp;nbsp;빌드&amp;nbsp;도구는&amp;nbsp;터미널에서&amp;nbsp;그대로&amp;nbsp;사용하면&amp;nbsp;됩니다.&amp;nbsp;Cursor의&amp;nbsp;터미널은&amp;nbsp;VSCode처럼&amp;nbsp;프로젝트&amp;nbsp;루트에서&amp;nbsp;열리고,&amp;nbsp;`npm&amp;nbsp;run&amp;nbsp;android`,&amp;nbsp;`npx&amp;nbsp;expo&amp;nbsp;start`&amp;nbsp;등&amp;nbsp;명령어를&amp;nbsp;그대로&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&amp;bull; 별도의&amp;nbsp;빌드&amp;nbsp;세팅은&amp;nbsp;필요하지&amp;nbsp;않습니다.&amp;nbsp;단,&amp;nbsp;Radon&amp;nbsp;IDE와&amp;nbsp;같은&amp;nbsp;React&amp;nbsp;Native&amp;nbsp;통합&amp;nbsp;개발&amp;nbsp;확장을&amp;nbsp;쓰고&amp;nbsp;싶다면,&amp;nbsp;Cursor의&amp;nbsp;Extension&amp;nbsp;Marketplace에서&amp;nbsp;Radon&amp;nbsp;IDE를&amp;nbsp;설치하면&amp;nbsp;VSCode와&amp;nbsp;동일하게&amp;nbsp;통합&amp;nbsp;시뮬레이터,&amp;nbsp;디버거,&amp;nbsp;인스펙터&amp;nbsp;등을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;b&gt;3.&amp;nbsp;AI&amp;nbsp;기능&amp;nbsp;및&amp;nbsp;문서화(옵션)&lt;/b&gt;&lt;br /&gt;&amp;bull; Cursor만의&amp;nbsp;AI&amp;nbsp;코드&amp;nbsp;생성,&amp;nbsp;자동&amp;nbsp;리팩토링,&amp;nbsp;문서화&amp;nbsp;기능을&amp;nbsp;활용하려면,&amp;nbsp;추가로&amp;nbsp;&amp;ldquo;Cursor&amp;nbsp;Rules&amp;rdquo;&amp;nbsp;확장이나&amp;nbsp;`.cursor/rules`&amp;nbsp;디렉터리를&amp;nbsp;프로젝트에&amp;nbsp;추가해&amp;nbsp;팀&amp;nbsp;규칙을&amp;nbsp;정의할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&amp;bull; 필요시,&amp;nbsp;프로젝트별로&amp;nbsp;커스텀&amp;nbsp;문서(예:&amp;nbsp;Expo,&amp;nbsp;React&amp;nbsp;Native&amp;nbsp;공식&amp;nbsp;문서)를&amp;nbsp;Cursor에&amp;nbsp;추가해&amp;nbsp;AI가&amp;nbsp;더&amp;nbsp;정확하게&amp;nbsp;코드를&amp;nbsp;생성하도록&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;b&gt;4.&amp;nbsp;기타&amp;nbsp;확인&amp;nbsp;사항&lt;/b&gt;&lt;br /&gt;&amp;bull; 기존&amp;nbsp;VSCode&amp;nbsp;설정(테마,&amp;nbsp;키&amp;nbsp;바인딩&amp;nbsp;등)도&amp;nbsp;대부분&amp;nbsp;이식됩니다.&amp;nbsp;일부&amp;nbsp;커스텀&amp;nbsp;단축키나&amp;nbsp;UI는&amp;nbsp;다를&amp;nbsp;수&amp;nbsp;있으니,&amp;nbsp;Cursor&amp;nbsp;Settings에서&amp;nbsp;재설정&amp;nbsp;가능.&lt;br /&gt;&amp;bull; CodePush,&amp;nbsp;자산&amp;nbsp;관리,&amp;nbsp;타입스크립트&amp;nbsp;등&amp;nbsp;기존&amp;nbsp;워크플로우는&amp;nbsp;그대로&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;&lt;b&gt;별도의 빌드 세팅은 필요 없고, 확장 프로그램만 기존처럼 설치/이식하면 바로 개발을 시작할 수 있습다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Radon IDE 등 React Native 특화 확장도 Cursor에서 지원하니 필요에 따라 설치해 활용하면 됩니다.&lt;/b&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;style5&quot; /&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Cursor 다운로드하고 실행하고 로그인하니 바로 아래와 같이 세팅하고 확장기능 그대로 가져올건지 물어보네요.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-25 오전 9.00.40.png&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dN3C6E/btsOPaz8yCh/FZixKPE0fakdKasdNJRGEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dN3C6E/btsOPaz8yCh/FZixKPE0fakdKasdNJRGEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dN3C6E/btsOPaz8yCh/FZixKPE0fakdKasdNJRGEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdN3C6E%2FbtsOPaz8yCh%2FFZixKPE0fakdKasdNJRGEK%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;418&quot; height=&quot;245&quot; data-filename=&quot;스크린샷 2025-06-25 오전 9.00.40.png&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&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 data-ke-size=&quot;size16&quot;&gt;멈칫했습니다. Cursor에서 RN 개발할때 필수 확장이 다를 수 있으니? 물어보니까.. 비슷하네요. ㅎㅎ import 고고&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-06-25 오전 9.03.45.png&quot; data-origin-width=&quot;1542&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBmfsg/btsOPWOY0Hh/mRrKq2VEKVhJlC3kC8KzDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBmfsg/btsOPWOY0Hh/mRrKq2VEKVhJlC3kC8KzDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBmfsg/btsOPWOY0Hh/mRrKq2VEKVhJlC3kC8KzDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBmfsg%2FbtsOPWOY0Hh%2FmRrKq2VEKVhJlC3kC8KzDk%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;1542&quot; height=&quot;920&quot; data-filename=&quot;스크린샷 2025-06-25 오전 9.03.45.png&quot; data-origin-width=&quot;1542&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&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;그 다음은 테마.. 요즘은 어둡고 글자가 쨍쨍한게 눈이 확 뛰어서 좋더라구요.. 점점 늙어가서 그런가.. ㅠㅠ&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;다음에는 이것저것 Next 누르다가 끝났네요.&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;open proejct를 하고 시작해보겠습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React Native 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/75</guid>
      <comments>https://dongmindevloper.tistory.com/75#entry75comment</comments>
      <pubDate>Wed, 25 Jun 2025 09:09:44 +0900</pubDate>
    </item>
    <item>
      <title>iOS 앱을 Android 앱으로 포팅해보자 - (2) 포팅 과정 - 실패 (끝)</title>
      <link>https://dongmindevloper.tistory.com/57</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요. 엔디엘입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네.. 제목에서 이미 예상하셨겠지만 처참하게 실패하였습니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 포팅 과정의 흐름은 이렇게 진행했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Claude에게 iOS 프로젝트 분석을 요청한다.&lt;/li&gt;
&lt;li&gt;Android 프로젝트를 생성한다.&lt;/li&gt;
&lt;li&gt;Claude에게 분석한 iOS 프로젝트 기반으로 Android 앱 개발을 요청한다.&lt;/li&gt;
&lt;li&gt;????? 막 개발하다가 멈춰버렸습니다.. 보통 많은 양의 작업을 시작하면 중간에 &quot;계속&quot;이라는 버튼이 나오는데 이번에는 그냥 갑자기 멈추더라고요.. 그래서 &quot;왜 멈췄어? 계속 진행해줘&quot;라고 요청하니 계속 진행합니다.&lt;/li&gt;
&lt;li&gt;일단 완료 메시지 &amp;rarr; 빌드했더니... 오류가 뜹니다. 확인 요청하니 JAVA 버전에 문제가 있더라고요. 아하!! 그래서 해결하고 다시 빌드..&lt;/li&gt;
&lt;li&gt;엄청난 라이브러리 의존성 오류들이 줄줄이~~~ 서로 충돌하고 난리나더라고요..  &lt;/li&gt;
&lt;li&gt;오류 복붙해서 계속 수정요청 &amp;rarr; 빌드 &amp;rarr; 복붙 이렇게 한 10번은 반복한 것 같아요..&lt;/li&gt;
&lt;li&gt;그래서 결국 빌드가 됐습니다. 화면을 보니 ??????? 으잉? 이건 뭐지.. 로그인 화면도 아니고 갑자기 이미 메인으로 들어와 있고.. 기능은 전혀 없고.. 그냥 탭이랑 각 흰 화면만 있더라고요.. 그리고 추가 개발을 요청해도 계속 UI를 똑같이 그리지도 않고... ㅠㅠ&lt;/li&gt;
&lt;li&gt;이때부터 하.. 한숨이 나오더니 하늘을 보기 시작하고.. 하기 싫어지고.. 그래도 여차여차 로그인, 회원가입, 메인, 설정까지 개발을 완료했습니다. 하지만 이걸 계속 이대로 진행하는 것이 가능할 것 같지 않았습니다. 그래서 일단 멈추기로 했습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지가.. 어제 진행했던 내용인데 사실 실망스러우면서도 안도가 된다고 해야 하나요 ㅎㅎ 이렇게 쉽게 되어버리면 누구나 다 할 수 있는 개발자가 되어버리는 거잖아요~~  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/li&gt;
&lt;li&gt;스텝 바이 스텝으로 개발 요청을 진행하지 않았다.&lt;/li&gt;
&lt;li&gt;커밋을 하지 않았다.&lt;/li&gt;
&lt;li&gt;사용량 소진에 대해서 고려하지 못했다.&lt;/li&gt;
&lt;li&gt;계속되는 채팅 만료 상황도 고려하지 못했다.&lt;/li&gt;
&lt;li&gt;하루 만에 될 것이라고 생각했다.&lt;/li&gt;
&lt;li&gt;너무 AI에게 의존도가 높았다.&lt;/li&gt;
&lt;li&gt;Claude의 프로젝트를 생성하지 않았다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 인생은 무한 실수와 실패를 반복하는 거 아니겠습니까~! 다시 시작해보면 되죠!  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/li&gt;
&lt;li&gt;앱 체크리스트 기반으로 Claude Project를 생성한다. 그 프로젝트에서 채팅을 항상 시작하자.&lt;/li&gt;
&lt;li&gt;안드로이드 프로젝트를 생성하여, 이미지와 필요한 파일들은 직접 iOS에서 옮긴다. Claude MCP Filesystem이 파일을 생성, 수정하는 건 가능하지만 복사, 이동 또는 삭제는 하지 못하더라고요.&lt;/li&gt;
&lt;li&gt;필요한 라이브러리들을 먼저 세팅해서 빌드를 진행해본다!! 이때 사용하는 AI가 알고 있는 라이브러리의 최신 버전이 얼마인지 체크하는 게 좋습니다. 내가 사용하려는 것보다 낮다면 Claude 프로젝트에 그 라이브러리 버전에 맞는 설명을 넣어두는 것도 하나의 방법입니다.&lt;/li&gt;
&lt;li&gt;API부터 모두 개발 요청한다. 이때 모델도 모두 요청&lt;/li&gt;
&lt;li&gt;유틸이나 컬러, config 등등 화면 개발 이외의 것들을 먼저 개발 요청한다.&lt;/li&gt;
&lt;li&gt;나머지 준비가 된다면 이제 한 화면씩 개발을 요청한다.&lt;/li&gt;
&lt;li&gt;중간중간 빌드를 해보고 스텝마다 커밋을 잊지 말고 진행한다.&lt;/li&gt;
&lt;li&gt;한 화면마다 새로운 채팅으로 시작한다.&lt;/li&gt;
&lt;li&gt;새로운 채팅 시작 전 현재 개발된 상황을 분석하여, Claude 프롬프트에 최신 개발 상황을 업데이트한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 이제 이렇게 개발을 진행하면 괜찮지 않을까 생각하는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번 직접 진행을 해봐야 알 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 함부로 AI를 믿고 성급하게 판단하지 않겠습니다.. 적어도 이렇게 하면 중간에 포기할 일은 없지 않을까 싶습니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 진행 상황에 대해서 중간중간 작성하여 글 올리겠습니다. 감사합니다.  &lt;/p&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/57</guid>
      <comments>https://dongmindevloper.tistory.com/57#entry57comment</comments>
      <pubDate>Wed, 4 Jun 2025 10:54:52 +0900</pubDate>
    </item>
    <item>
      <title>iOS 앱을 Android 앱으로 포팅해보자 - (1) 프로젝트 세팅</title>
      <link>https://dongmindevloper.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&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;이번 시간에는 안드로이드 앱 프로젝트를 세팅해볼 시간을 가질 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그전에 우선 기존 iOS가 어떤 기능이 있고, 어떤 구조로 개발되어 있는지부터 파악해야겠지요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 당연히 제가 개발했으니까 어느 정도는 알고 있지만, 제가 그걸 작성할 생각은 전혀 없습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네.. Claude Desktop - MCP FileSystem을 이용하여 분석을 맡길 예정입니다.&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;darr;&amp;darr;&amp;darr;&amp;darr;&amp;darr;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;iOS 프로젝트 분석 결과&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 &lt;b&gt;DriveMaker&lt;/b&gt; 프로젝트는 운전 경로를 생성하고 관리하는 iOS 앱입니다. 상당히 체계적으로 구성된 Swift 프로젝트네요!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ &lt;b&gt;프로젝트 구조 및 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 아키텍처 패턴&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;TCA (The Composable Architecture)&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;Redux 스타일의 단방향 데이터 플로우&lt;/li&gt;
&lt;li&gt;State, Action, Reducer 패턴으로 상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 주요 기술 스택&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;언어&lt;/b&gt;: Swift 5.0&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프레임워크&lt;/b&gt;: SwiftUI, MapKit, CoreLocation&lt;/li&gt;
&lt;li&gt;&lt;b&gt;외부 라이브러리&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Composable Architecture (상태 관리)&lt;/li&gt;
&lt;li&gt;Alamofire (네트워킹)&lt;/li&gt;
&lt;li&gt;KeychainSwift (보안 저장)&lt;/li&gt;
&lt;li&gt;KakaoSDK (카카오맵 연동)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 프로젝트 구조&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;DriveMaker/
├── App/                    # 앱 메인 구조
├── Assets.xcassets/        # 리소스 파일들
├── Common/                 # 공통 모듈
├── Components/             # 재사용 컴포넌트
├── Core/                   # 핵심 비즈니스 로직
│   ├── Clients/           # API, 인증 클라이언트
│   └── AppState/          # 앱 상태 관리
├── Features/              # 주요 기능들
├── Models/                # 데이터 모델
├── Screens/               # 화면별 구성
│   ├── SplashScreen/
│   ├── LoginScreen/
│   ├── MainTabScreen/
│   ├── RouteMapTab/
│   ├── RouteListTab/
│   ├── NavigationScreen/
│   └── SettingsTab/
└── Utils/                 # 유틸리티 함수들&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;주요 기능&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 인증 시스템&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Apple 로그인 지원 (AppleAuthClient.swift)&lt;/li&gt;
&lt;li&gt;OAuth 기반 인증 (OAuthLoginRequest.swift)&lt;/li&gt;
&lt;li&gt;JWT 토큰 관리 (TokenManager.swift)&lt;/li&gt;
&lt;li&gt;Keychain을 통한 보안 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 경로 관리 시스템&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경로 생성 및 편집&lt;/li&gt;
&lt;li&gt;웨이포인트 관리 (RoutePointDTO)&lt;/li&gt;
&lt;li&gt;폴리라인 세그먼트 처리 (PolylineSegmentDTO)&lt;/li&gt;
&lt;li&gt;거리 및 예상 시간 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 지도 및 네비게이션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MapKit 기반 지도 표시&lt;/li&gt;
&lt;li&gt;앱 내 네비게이션 기능&lt;/li&gt;
&lt;li&gt;음성 안내 (TTS)&lt;/li&gt;
&lt;li&gt;카카오네비 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 탭 기반 UI&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;홈&lt;/b&gt;: 메인 대시보드&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경로 목록&lt;/b&gt;: 저장된 경로들&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경로 생성&lt;/b&gt;: 새로운 경로 만들기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;설정&lt;/b&gt;: 사용자 설정 및 계정 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;기술적 특징&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 상태 관리&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;swift&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;swift&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;@Reducer
struct AppFeature {
    struct State: Equatable {
        var appStatus: AppStatus = .splash
        var splashState = SplashFeature.State()
        var loginState = LoginScreenFeature.State()
        var mainTabState = MainTabFeature.State()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. API 클라이언트&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;완전한 RESTful API 지원&lt;/li&gt;
&lt;li&gt;토큰 기반 인증&lt;/li&gt;
&lt;li&gt;에러 핸들링 및 로깅&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api.worlddriveroute.store&quot;&gt;https://api.xxxx.xxxx&lt;/a&gt; 서버 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 경로 데이터 모델&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;swift&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;gauss&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;struct DriveRouteResponse: Codable, Identifiable {
    let id: Int
    let title: String
    let totalDistance: Double  // 미터 단위
    let estimatedTime: Int     // 초 단위
    let points: [RoutePointResponseDTO]
    let polylineSegments: [PolylineSegmentResponseDTO]?
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;앱 플로우&lt;/b&gt;&lt;/h3&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; &amp;rarr; 로그인 상태 확인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로그인/회원가입&lt;/b&gt; &amp;rarr; Apple 계정 연동&lt;/li&gt;
&lt;li&gt;&lt;b&gt;튜토리얼&lt;/b&gt; &amp;rarr; 첫 사용자 안내&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메인 탭&lt;/b&gt; &amp;rarr; 경로 관리 기능들&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경로 생성&lt;/b&gt; &amp;rarr; 지도에서 경로 선택&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네비게이션&lt;/b&gt; &amp;rarr; 실제 길안내 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;UI/UX 특징&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;다크 모드&lt;/b&gt; 기본 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네이티브 SwiftUI&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;탭 기반 네비게이션&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모달 및 네비게이션 스택&lt;/b&gt; 조합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;반응형 디자인&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;배포 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Bundle ID&lt;/b&gt;: com.xxxx.xxxxxx&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최소 지원 버전&lt;/b&gt;: iOS 17.5+&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타겟 디바이스&lt;/b&gt;: iPhone 전용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버전&lt;/b&gt;: 1.0.0&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;프로젝트의 강점&lt;/b&gt;&lt;/h3&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;: TCA를 통한 예측 가능한 상태 관리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모듈화된 구조&lt;/b&gt;: 기능별로 잘 분리된 코드&lt;/li&gt;
&lt;li&gt;&lt;b&gt;완전한 API 연동&lt;/b&gt;: 백엔드와의 완전한 연동&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용자 경험&lt;/b&gt;: 직관적인 UI/UX&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;: 새로운 기능 추가가 용이한 구조&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 실제 출시 가능한 수준의 완성도를 가진 드라이브 경로 관리 앱으로 보입니다! 혹시 특정 부분에 대해 더 자세히 알고 싶으시거나, 개선점이나 문제점에 대해 논의하고 싶으시다면 말씀해 주세요.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;그럼 이제 안드로이드 프로젝트를 생성하고 세팅해보겠습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;우선 안드로이드 앱 기본 프로젝트를 생성했습니다.&lt;/li&gt;
&lt;li&gt;iOS 앱 프로젝트 기반으로 안드로이드 앱 개발을 하려고 하는데, 앱 개발 체크리스트를 정해달라고 Claude에게 요청하기.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 앞서 글을 작성할 때 모든 플랫폼을 개발하기 전에 앱 개발 체크리스트를 보고 개발 정책을 정해놓고 개발을 진행하면 된다고 말씀드렸습니다. 그래서 저는 기존 iOS 프로젝트를 안드로이드로 그대로 포팅이 문제없이 잘 되는 안드로이드 앱 개발 체크리스트를 작성해달라고 요청했습니다.&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;darr;&amp;darr;&amp;darr;&amp;darr;&amp;darr;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;DriveMaker Android 포팅 체크리스트 (확정)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.   &lt;b&gt;프로젝트 정의 및 기획&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;프로젝트 목표 설정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iOS 기출시 앱의 안드로이드 버전 개발&lt;/li&gt;
&lt;li&gt;기존 사용자 데이터 호환성 유지 (동일 API 서버)&lt;/li&gt;
&lt;li&gt;안드로이드 사용자층 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;비즈니스 모델&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iOS와 동일한 무료 모델&lt;/li&gt;
&lt;li&gt;Google Play 정책 준수&lt;/li&gt;
&lt;li&gt;기존 사용자 계정 연동 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.  ️ &lt;b&gt;기술 스택 및 플랫폼 선정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;플랫폼 전략&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;네이티브 안드로이드&lt;/b&gt; (Kotlin + Jetpack Compose)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최소 지원 버전: Android 7.0 (API 24)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타겟 SDK: Android 14 (API 34)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;개발 환경&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Android Studio Hedgehog 이상&lt;/li&gt;
&lt;li&gt;Gradle Kotlin DSL&lt;/li&gt;
&lt;li&gt;ktlint + detekt&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.  ️ &lt;b&gt;아키텍처 및 설계 패턴&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;아키텍처 선정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MVIKotlin + Clean Architecture&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;멀티모듈 구조&lt;/b&gt; (iOS Feature 구조 대응)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;gauss&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;app/
├── app/                    # 메인 앱 모듈
├── core/
│   ├── common/            # 공통 유틸
│   ├── network/           # 네트워크 모듈
│   ├── database/          # 데이터베이스
│   └── design-system/     # 디자인 시스템
├── feature/
│   ├── auth/              # 인증 (로그인/회원가입)
│   ├── route-map/         # 경로 생성
│   ├── route-list/        # 경로 목록
│   ├── route-detail/      # 경로 상세
│   ├── navigation/        # 네비게이션
│   └── settings/          # 설정
└── shared/                # 공유 모델&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;의존성 주입&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Hilt&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.   &lt;b&gt;상태 관리 및 데이터 흐름&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;상태 관리&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MVIKotlin&lt;/b&gt; (TCA 스타일 구현)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Kotlin Flow + StateFlow&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단방향 데이터 플로우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.   &lt;b&gt;네비게이션 및 라우팅&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;네비게이션&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Navigation Component with Compose&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Bottom Navigation&lt;/b&gt; (메인 탭)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;딥링킹&lt;/b&gt; 지원 (xxxx:// 스키마)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.   &lt;b&gt;데이터 저장 및 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;로컬 저장소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Room Database&lt;/b&gt; (경로 데이터)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EncryptedSharedPreferences&lt;/b&gt; (토큰 저장)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Preferences DataStore&lt;/b&gt; (설정값)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7.   &lt;b&gt;네트워크 통신 및 API&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;API 통신&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Retrofit + OkHttp&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동일한 서버 엔드포인트&lt;/b&gt; (&lt;a href=&quot;https://api.worlddriveroute.store&quot;&gt;https://api.xxxx.xxxx&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JWT 토큰 인증&lt;/b&gt; (iOS와 동일)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8. ⚡ &lt;b&gt;비동기 처리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;비동기 처리&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Kotlin Coroutines&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;WorkManager&lt;/b&gt; (백그라운드 작업)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9.   &lt;b&gt;UI/UX 설계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;디자인 시스템&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Material Design 3&lt;/b&gt; 적용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;라이트 모드 전용&lt;/b&gt; (다크모드 미지원)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;iOS 디자인 참고한 커스텀 컴포넌트&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;10.  ️ &lt;b&gt;지도 및 네비게이션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;지도 서비스&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Google Maps SDK for Android&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Google Directions API&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Google Places API&lt;/b&gt; (주소 검색)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;11.   &lt;b&gt;인증 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;인증 방식 (둘 다 지원)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Google Sign-In&lt;/b&gt; (주요 인증)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Kakao Login SDK&lt;/b&gt; (iOS와 동일)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;12.   &lt;b&gt;테스트 전략&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;테스트 도구&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;JUnit 5&lt;/b&gt; + &lt;b&gt;Truth&lt;/b&gt; (단위 테스트)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Espresso&lt;/b&gt; + &lt;b&gt;Compose Testing&lt;/b&gt; (UI 테스트)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mockk&lt;/b&gt; (모킹)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;13.   &lt;b&gt;배포 및 DevOps&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;배포 전략&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Google Play Console&lt;/b&gt; 배포&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기존 GitHub Actions&lt;/b&gt; 확장 (iOS + Android)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fastlane&lt;/b&gt; 안드로이드 버전&lt;/li&gt;
&lt;li&gt;&lt;b&gt;iOS 출시 후 안드로이드 순차 출시&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;14.   &lt;b&gt;모니터링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;분석 도구&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Firebase Analytics&lt;/b&gt; (iOS와 동일)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Firebase Crashlytics&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Play Console 분석&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS와 비슷한 MVI라는 아키텍처를 사용한다고 하는군요;;; 잘 모르지만 이렇게 결과가 나왔습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 시간에는 바로!! Claude에게 포팅을 요청해보도록 하겠습니다.&lt;/p&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/56</guid>
      <comments>https://dongmindevloper.tistory.com/56#entry56comment</comments>
      <pubDate>Wed, 4 Jun 2025 08:00:05 +0900</pubDate>
    </item>
    <item>
      <title>iOS 앱을 Android 앱으로 포팅해보자 - 시작</title>
      <link>https://dongmindevloper.tistory.com/55</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요. 엔디엘입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 시간에 AI를 이용한 앱 개발을 진행하면 플랫폼과 상관없이 개발이 가능하다고 포부 있게 말씀드렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이것이 정말 가능한지 저도 직접 해보면서 그 과정을 기록으로 남기려고 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기존 iOS 앱 소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저에게는 얼마 전에 AI 앱 개발로 출시한 iOS 앱이 하나 있습니다. 최신(저에게만) iOS 인기있는 아키텍쳐(TCA)를 적용하여 만든 앱인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나만의 드라이브 코스 경로를 저장해두는 앱으로 &lt;b&gt;드라이브메이커&lt;/b&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;&lt;a href=&quot;https://apps.apple.com/us/app/drivemaker/id6746174534&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://apps.apple.com/us/app/drivemaker/id6746174534&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748989264140&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;&amp;lrm;DriveMaker&quot; data-og-description=&quot;&amp;lrm;DriveMAKER is a tool and app that helps you continuously experience your precious driving moments. From beautiful coastal roads to hidden mountain paths, every drive becomes a special memory. - Save quiet neighborhood drives that help put your precious &quot; data-og-host=&quot;apps.apple.com&quot; data-og-source-url=&quot;https://apps.apple.com/us/app/drivemaker/id6746174534&quot; data-og-url=&quot;https://apps.apple.com/us/app/drivemaker/id6746174534&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oAx12/hyY4an3T8b/J5llbGzB0DTF0T4YSbbhE1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cc4kp3/hyY45thojf/5LG84RzcuiGAXVJusZlDsK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://apps.apple.com/us/app/drivemaker/id6746174534&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://apps.apple.com/us/app/drivemaker/id6746174534&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oAx12/hyY4an3T8b/J5llbGzB0DTF0T4YSbbhE1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cc4kp3/hyY45thojf/5LG84RzcuiGAXVJusZlDsK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;&amp;lrm;DriveMaker&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lrm;DriveMAKER is a tool and app that helps you continuously experience your precious driving moments. From beautiful coastal roads to hidden mountain paths, every drive becomes a special memory. - Save quiet neighborhood drives that help put your precious&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;apps.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표: iOS &amp;rarr; Android 포팅&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 앱을 이제 안드로이드 앱으로 포팅을 진행하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼마나 걸릴지 감히 예상해보자면... 간단한 앱이니까 길어야 하루가 걸리지 않을까? 라고 생각하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 글은 3개로 나누려고 합니다.&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;&lt;b&gt;1편) 프로젝트 세팅&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2편) 포팅 과정&lt;/b&gt;&lt;br /&gt;&lt;b&gt;3편) 이슈 &amp;amp; 해결 과정 &amp;amp; 후기&lt;/b&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;&lt;b&gt;시작 시각: 2025년 6월 4일 오전 7시 25분&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 언제 완성될지... 한번 시작해보죠!  &lt;/p&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/55</guid>
      <comments>https://dongmindevloper.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 4 Jun 2025 07:31:57 +0900</pubDate>
    </item>
    <item>
      <title>앱 개발 체크리스트</title>
      <link>https://dongmindevloper.tistory.com/53</link>
      <description>&lt;h1&gt;✅ 앱 개발 완전 체크리스트 - 플랫폼 무관 핵심 결정사항&lt;/h1&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;b&gt;iOS, Android, React Native, Flutter&lt;/b&gt; 등 어떤 플랫폼을 사용하든 공통으로 적용할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.   &lt;b&gt;프로젝트 정의 및 기획 (개발자라면 2번으로!!)&lt;/b&gt;&lt;/h2&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;[ ] 앱의 핵심 가치 제안 및 목적 명확화&lt;/li&gt;
&lt;li&gt;[ ] 타겟 사용자 페르소나 정의&lt;/li&gt;
&lt;li&gt;[ ] 주요 기능 및 MVP 범위 설정&lt;/li&gt;
&lt;li&gt;[ ] 경쟁사 분석 및 차별화 포인트 도출&lt;/li&gt;
&lt;/ul&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;[ ] 수익 모델 (무료/유료/구독/광고/인앱결제) 선택&lt;/li&gt;
&lt;li&gt;[ ] 법적 요구사항 및 규제 검토 (GDPR, 개인정보보호법 등)&lt;/li&gt;
&lt;li&gt;[ ] 지적재산권 및 라이선스 정책 수립&lt;/li&gt;
&lt;/ul&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;[ ] 개발 일정 및 마일스톤 설정&lt;/li&gt;
&lt;li&gt;[ ] 예산 및 리소스 할당&lt;/li&gt;
&lt;li&gt;[ ] 위험 요소 분석 및 대응 계획&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.  ️ &lt;b&gt;기술 스택 및 플랫폼 선정&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;네이티브&lt;/b&gt; vs &lt;b&gt;크로스플랫폼&lt;/b&gt; vs &lt;b&gt;하이브리드&lt;/b&gt; 선택&lt;/li&gt;
&lt;li&gt;[ ] 개발 프레임워크 결정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iOS: UIKit vs SwiftUI&lt;/li&gt;
&lt;li&gt;Android: Java/Kotlin, Jetpack Compose&lt;/li&gt;
&lt;li&gt;Cross-platform: React Native vs Flutter vs Xamarin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] 최소 지원 OS 버전 설정&lt;/li&gt;
&lt;/ul&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;[ ] IDE 및 개발 도구 표준화&lt;/li&gt;
&lt;li&gt;[ ] 패키지 매니저 및 의존성 관리 방식&lt;/li&gt;
&lt;li&gt;[ ] 코드 스타일 가이드 및 린터 설정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ESLint/Prettier (React Native)&lt;/li&gt;
&lt;li&gt;SwiftLint (iOS)&lt;/li&gt;
&lt;li&gt;ktlint/detekt (Android)&lt;/li&gt;
&lt;li&gt;dart analyze (Flutter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;[ ] 백엔드 기술 스택 선정&lt;/li&gt;
&lt;li&gt;[ ] 클라우드 서비스 선택 (AWS, GCP, Azure, Firebase)&lt;/li&gt;
&lt;li&gt;[ ] CDN 및 파일 저장소 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.  ️ &lt;b&gt;아키텍처 및 설계 패턴&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;MVC&lt;/b&gt; / &lt;b&gt;MVVM&lt;/b&gt; / &lt;b&gt;MVP&lt;/b&gt; / &lt;b&gt;Clean Architecture&lt;/b&gt; / &lt;b&gt;Hexagonal&lt;/b&gt; 선택&lt;/li&gt;
&lt;li&gt;[ ] 레이어 구조 설계 (Presentation - Domain - Data)&lt;/li&gt;
&lt;li&gt;[ ] 의존성 역전 원칙 적용 여부&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;기능 중심(Feature-based)&lt;/b&gt; vs &lt;b&gt;계층적 구조(Layer-based)&lt;/b&gt; 선택&lt;/li&gt;
&lt;li&gt;[ ] 모듈화 전략 (Core, Feature, Shared 등)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;모놀리식&lt;/b&gt; vs &lt;b&gt;멀티모듈&lt;/b&gt; 구조 결정&lt;/li&gt;
&lt;/ul&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;[ ] DI 컨테이너 사용 여부 및 선택&lt;/li&gt;
&lt;li&gt;[ ] 생명주기 관리 (Singleton, Transient, Scoped)&lt;/li&gt;
&lt;li&gt;[ ] 테스트를 위한 Mock 객체 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.   &lt;b&gt;상태 관리 및 데이터 흐름&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;로컬 상태&lt;/b&gt; vs &lt;b&gt;전역 상태&lt;/b&gt; 구분 및 관리 전략&lt;/li&gt;
&lt;li&gt;[ ] 상태 관리 라이브러리 선정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;React Native&lt;/b&gt;: Redux, MobX, Zustand, Context API, Recoil&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flutter&lt;/b&gt;: Provider, Bloc, Riverpod, GetX, Cubit&lt;/li&gt;
&lt;li&gt;&lt;b&gt;iOS&lt;/b&gt;: RxSwift, Combine, MVVM 패턴&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Android&lt;/b&gt;: LiveData, ViewModel, RxJava, Hilt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;단방향 데이터 흐름&lt;/b&gt; 적용 여부 (Flux, Redux 패턴)&lt;/li&gt;
&lt;li&gt;[ ] 이벤트 처리 방식 (Event Bus, Command Pattern, NotificationCenter)&lt;/li&gt;
&lt;li&gt;[ ] 상태 불변성(Immutable) 정책 설정&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;React Query&lt;/b&gt;, &lt;b&gt;SWR&lt;/b&gt;, &lt;b&gt;Apollo Client&lt;/b&gt; 등 서버 상태 라이브러리&lt;/li&gt;
&lt;li&gt;[ ] 캐싱 전략 및 무효화 정책&lt;/li&gt;
&lt;li&gt;[ ] Optimistic Updates 적용 여부&lt;/li&gt;
&lt;li&gt;[ ] Background Sync 및 오프라인 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5.   &lt;b&gt;네비게이션 및 라우팅&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;Stack Navigation&lt;/b&gt; (화면 스택 관리)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Tab Navigation&lt;/b&gt; (하단/상단 탭)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Drawer Navigation&lt;/b&gt; (사이드 메뉴)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Modal Navigation&lt;/b&gt; (팝업, 바텀시트)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;Named Routing&lt;/b&gt; vs &lt;b&gt;Direct Component Navigation&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;[ ] 정적 라우팅 vs 동적 라우팅&lt;/li&gt;
&lt;li&gt;[ ] 중첩 라우팅 구조 설계&lt;/li&gt;
&lt;li&gt;[ ] 조건부 라우팅 (로그인 상태, 권한 기반)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;Deep Linking&lt;/b&gt; 설계 및 구현&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Universal Links&lt;/b&gt; (iOS) / &lt;b&gt;App Links&lt;/b&gt; (Android)&lt;/li&gt;
&lt;li&gt;[ ] 네비게이션 스택 관리 및 백버튼 처리&lt;/li&gt;
&lt;li&gt;[ ] 탭 간 상태 유지 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6.   &lt;b&gt;데이터 저장 및 관리&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;Key-Value 저장소&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iOS: UserDefaults, Keychain&lt;/li&gt;
&lt;li&gt;Android: SharedPreferences, EncryptedSharedPreferences&lt;/li&gt;
&lt;li&gt;Cross-platform: AsyncStorage, MMKV&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;관계형 데이터베이스&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQLite, Room (Android), Core Data (iOS), Realm&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;파일 시스템&lt;/b&gt; 저장 전략&lt;/li&gt;
&lt;/ul&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;[ ] 민감 정보 암호화 방식 결정&lt;/li&gt;
&lt;li&gt;[ ] 생체 인증 연동 (TouchID, FaceID, Fingerprint)&lt;/li&gt;
&lt;li&gt;[ ] 보안 저장소 사용 (Keychain, Android Keystore)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;오프라인 우선&lt;/b&gt; vs &lt;b&gt;온라인 우선&lt;/b&gt; 아키텍처&lt;/li&gt;
&lt;li&gt;[ ] 서버-클라이언트 동기화 전략&lt;/li&gt;
&lt;li&gt;[ ] 충돌 해결 메커니즘 (Last Write Wins, Operational Transform)&lt;/li&gt;
&lt;li&gt;[ ] 배치 동기화 및 실시간 동기화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7.   &lt;b&gt;네트워크 통신 및 API&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✔ API 통신 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[ ] &lt;b&gt;REST API&lt;/b&gt; vs &lt;b&gt;GraphQL&lt;/b&gt; vs &lt;b&gt;gRPC&lt;/b&gt; 선택&lt;/li&gt;
&lt;li&gt;[ ] HTTP 클라이언트 라이브러리 선정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Axios, Fetch (JavaScript)&lt;/li&gt;
&lt;li&gt;Retrofit, OkHttp (Android)&lt;/li&gt;
&lt;li&gt;Alamofire, URLSession (iOS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;[ ] 인증 방식 (OAuth, JWT, API Key, Session)&lt;/li&gt;
&lt;li&gt;[ ] SSL Pinning 및 Certificate Transparency&lt;/li&gt;
&lt;li&gt;[ ] API 보안 정책 (Rate Limiting, CORS)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;통일된 에러 객체&lt;/b&gt; 정의 및 처리 위치&lt;/li&gt;
&lt;li&gt;[ ] 네트워크 상태 감지 및 재시도 정책&lt;/li&gt;
&lt;li&gt;[ ] 타임아웃 설정 및 Circuit Breaker 패턴&lt;/li&gt;
&lt;li&gt;[ ] 요청/응답 인터셉터 및 로깅&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. ⚡ &lt;b&gt;비동기 처리 및 백그라운드 작업&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;Callback&lt;/b&gt; vs &lt;b&gt;Promise&lt;/b&gt; vs &lt;b&gt;Async/Await&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Observable/Stream&lt;/b&gt; 기반 처리 (RxJS, RxSwift, RxDart)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Coroutines&lt;/b&gt; (Kotlin) / &lt;b&gt;Future/Task&lt;/b&gt; 패턴&lt;/li&gt;
&lt;/ul&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;[ ] 백그라운드 태스크 처리 (파일 업로드/다운로드, 동기화)&lt;/li&gt;
&lt;li&gt;[ ] 주기적 작업 스케줄링 (WorkManager, Background App Refresh)&lt;/li&gt;
&lt;li&gt;[ ] 푸시 알림 백그라운드 처리&lt;/li&gt;
&lt;/ul&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;[ ] Race Condition 방지 및 동시성 제어&lt;/li&gt;
&lt;li&gt;[ ] 취소 가능한 비동기 작업 구현&lt;/li&gt;
&lt;li&gt;[ ] 메모리 및 스레드 안전성 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9.   &lt;b&gt;UI/UX 설계 및 디자인 시스템&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;디자인 가이드라인&lt;/b&gt; 채택
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Material Design (Android)&lt;/li&gt;
&lt;li&gt;Human Interface Guidelines (iOS)&lt;/li&gt;
&lt;li&gt;커스텀 디자인 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;컬러 팔레트&lt;/b&gt; 및 브랜딩 정의&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;타이포그래피&lt;/b&gt; 시스템 (폰트, 크기, 가중치)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;공통 컴포넌트 라이브러리&lt;/b&gt; (버튼, 입력 필드, 카드 등)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;다크 모드&lt;/b&gt; / &lt;b&gt;라이트 모드&lt;/b&gt; 지원&lt;/li&gt;
&lt;li&gt;[ ] 동적 테마 변경 및 시스템 설정 연동&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;반응형/적응형&lt;/b&gt; UI 설계&lt;/li&gt;
&lt;li&gt;[ ] 다양한 화면 크기 및 해상도 대응 (폴더블, 태블릿)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;화면 전환 애니메이션&lt;/b&gt; 정의&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;마이크로 인터랙션&lt;/b&gt; 및 피드백 효과&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;로딩 상태 UI&lt;/b&gt; (Skeleton, Shimmer, Progress)&lt;/li&gt;
&lt;li&gt;[ ] 제스처 및 터치 인터랙션&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;10. ♿ &lt;b&gt;접근성(Accessibility) 및 사용성&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;의미있는 레이블&lt;/b&gt; 및 설명 제공&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;포커스 관리&lt;/b&gt; 및 키보드 네비게이션&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;콘텐츠 구조화&lt;/b&gt; (Heading, Landmark)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;색상 대비&lt;/b&gt; 및 색맹 사용자 고려&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;폰트 크기 조절&lt;/b&gt; 지원 (Dynamic Type)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;고대비 모드&lt;/b&gt; 및 시각적 보조 기능&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;적절한 터치 영역&lt;/b&gt; 크기 (최소 44pt/48dp)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;제스처 대안&lt;/b&gt; 제공 (음성 제어, 스위치 제어)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;시간 제한&lt;/b&gt; 및 자동 재생 콘텐츠 제어&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;접근성 테스트&lt;/b&gt; 및 검증 프로세스&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;11.   &lt;b&gt;국제화(i18n) 및 지역화(l10n)&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;문자열 리소스&lt;/b&gt; 관리 및 번역 시스템&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;동적 언어 변경&lt;/b&gt; 지원&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;복수형 처리&lt;/b&gt; 및 성별 구분&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;번역 관리 프로세스&lt;/b&gt; 및 도구 선정&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;RTL (Right-to-Left)&lt;/b&gt; 언어 지원&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;날짜/시간/통화&lt;/b&gt; 형식 로컬라이제이션&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;문화적 차이&lt;/b&gt; 및 색상 의미 고려&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;로컬 법규&lt;/b&gt; 및 규제 준수&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;12.   &lt;b&gt;성능 최적화&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;가상화&lt;/b&gt; (Virtual Scrolling, RecyclerView)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;메모이제이션&lt;/b&gt; 및 불필요한 리렌더링 방지&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;이미지 최적화&lt;/b&gt; (Lazy Loading, WebP, 리사이징)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;애니메이션 성능&lt;/b&gt; 최적화 (60fps 유지)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;메모리 누수 방지&lt;/b&gt; 및 프로파일링&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;대용량 데이터&lt;/b&gt; 처리 전략&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;이미지 메모리&lt;/b&gt; 관리 및 캐싱&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;가비지 컬렉션&lt;/b&gt; 최적화&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;코드 스플리팅&lt;/b&gt; 및 지연 로딩&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Tree Shaking&lt;/b&gt; 및 Dead Code Elimination&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;번들 크기 분석&lt;/b&gt; 및 최적화&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;앱 시작 시간&lt;/b&gt; 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;13.  ️ &lt;b&gt;보안 및 개인정보 보호&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;저장 데이터 암호화&lt;/b&gt; (AES, RSA)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;전송 데이터 보안&lt;/b&gt; (TLS/SSL, Certificate Pinning)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;민감 정보 관리&lt;/b&gt; (API 키, 토큰, 비밀번호)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;코드 난독화&lt;/b&gt; 및 안티 디버깅&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;루팅/탈옥 탐지&lt;/b&gt; 및 대응&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;앱 변조 방지&lt;/b&gt; 및 무결성 검사&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;스크린샷 및 녹화 방지&lt;/b&gt; (민감 화면)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;다중 인증&lt;/b&gt; (2FA/MFA) 지원&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;생체 인증&lt;/b&gt; 연동 및 폴백 처리&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;개인정보 처리방침&lt;/b&gt; 및 GDPR/CCPA 준수&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;사용자 동의 관리&lt;/b&gt; 및 옵트아웃 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;14.   &lt;b&gt;오프라인 지원 및 동기화&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;오프라인 우선&lt;/b&gt; 아키텍처 설계&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;오프라인 상태 감지&lt;/b&gt; 및 UI 표시&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;오프라인 기능&lt;/b&gt; 범위 정의&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;로컬 데이터&lt;/b&gt; 우선 표시 전략&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;자동 동기화&lt;/b&gt; vs &lt;b&gt;수동 동기화&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;충돌 해결&lt;/b&gt; 메커니즘 (Merge, Overwrite, User Choice)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;배치 동기화&lt;/b&gt; 및 백그라운드 업데이트&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;스토리지 할당량&lt;/b&gt; 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;15.   &lt;b&gt;테스트 전략 및 품질 보증&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;단위 테스트&lt;/b&gt; (Unit Test) - 비즈니스 로직&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;통합 테스트&lt;/b&gt; (Integration Test) - API, 데이터베이스&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;UI 테스트&lt;/b&gt; (E2E Test) - 사용자 시나리오&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;스냅샷 테스트&lt;/b&gt; - UI 컴포넌트 회귀 방지&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;테스트 프레임워크&lt;/b&gt; 선정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Jest, React Testing Library (React Native)&lt;/li&gt;
&lt;li&gt;XCTest, Quick/Nimble (iOS)&lt;/li&gt;
&lt;li&gt;JUnit, Espresso, Robolectric (Android)&lt;/li&gt;
&lt;li&gt;Flutter Test (Flutter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;CI/CD 파이프라인&lt;/b&gt; 테스트 자동화&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;코드 커버리지&lt;/b&gt; 목표 설정 (80% 이상 권장)&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;정적 분석&lt;/b&gt; 도구 (SonarQube, CodeClimate)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;코드 리뷰&lt;/b&gt; 프로세스 및 체크리스트&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;다양한 디바이스/OS&lt;/b&gt; 호환성 테스트&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;성능 테스트&lt;/b&gt; 및 부하 테스트&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;16.   &lt;b&gt;에러 처리 및 로깅&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;에러 분류 체계&lt;/b&gt; 정의
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 에러, 비즈니스 로직 에러, 시스템 에러&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;글로벌 에러 핸들러&lt;/b&gt; 구현&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;에러 바운더리&lt;/b&gt; 및 복구 메커니즘&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;사용자 친화적 에러 메시지&lt;/b&gt; 작성&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;로깅 레벨&lt;/b&gt; 정의 (Error, Warning, Info, Debug)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;크래시 리포팅&lt;/b&gt; 시스템 (Crashlytics, Sentry, Bugsnag)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;실시간 모니터링&lt;/b&gt; 및 알림 시스템&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;로그 보안&lt;/b&gt; 및 개인정보 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;17.   &lt;b&gt;푸시 알림 및 백그라운드 서비스&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;로컬 알림&lt;/b&gt; vs &lt;b&gt;원격 알림&lt;/b&gt; 구분&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;알림 권한&lt;/b&gt; 요청 타이밍 및 UX&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;알림 카테고리&lt;/b&gt; 및 중요도 설정&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;조용한 알림&lt;/b&gt; 및 배지 관리&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;FCM&lt;/b&gt; (Firebase Cloud Messaging) 연동&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;APNs&lt;/b&gt; (Apple Push Notification service) 연동&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;알림 딥링크&lt;/b&gt; 및 데이터 페이로드 처리&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;포그라운드/백그라운드&lt;/b&gt; 알림 처리 차별화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;18.   &lt;b&gt;배포 및 DevOps&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;환경별 설정&lt;/b&gt; 관리 (Development, Staging, Production)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;빌드 자동화&lt;/b&gt; 및 스크립트 작성&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;코드 사이닝&lt;/b&gt; 및 인증서 관리&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;앱 번들&lt;/b&gt; 최적화 (Android App Bundle, iOS App Thinning)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✔ CI/CD 파이프라인&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[ ] &lt;b&gt;지속적 통합&lt;/b&gt; 도구 선정 (GitHub Actions, GitLab CI, Bitrise)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;자동화된 테스트&lt;/b&gt; 실행&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;빌드 및 배포&lt;/b&gt; 자동화&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;Fastlane&lt;/b&gt; 등 배포 도구 활용&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;앱스토어 등록&lt;/b&gt; 정보 및 메타데이터 관리&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;심사 가이드라인&lt;/b&gt; 준수 체크&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;점진적 배포&lt;/b&gt; (Phased Rollout) 전략&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;A/B 테스트&lt;/b&gt; 및 실험 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;19.   &lt;b&gt;모니터링 및 분석&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;앱 성능 지표&lt;/b&gt; 추적 (CPU, 메모리, 배터리)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;네트워크 성능&lt;/b&gt; 모니터링&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;크래시 및 ANR&lt;/b&gt; 추적&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;앱 시작 시간&lt;/b&gt; 및 응답성 측정&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;이벤트 추적&lt;/b&gt; 시스템 구축&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;사용자 여정&lt;/b&gt; 및 퍼널 분석&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;리텐션&lt;/b&gt; 및 이탈률 분석&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;사용자 세그멘테이션&lt;/b&gt; 및 코호트 분석&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;매출 및 전환율&lt;/b&gt; 추적&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;사용자 생애 가치&lt;/b&gt; (LTV) 계산&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;실시간 대시보드&lt;/b&gt; 구축&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;데이터 개인정보 보호&lt;/b&gt; 준수&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;20.   &lt;b&gt;팀 협업 및 프로젝트 관리&lt;/b&gt;&lt;/h2&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;[ ] &lt;b&gt;Git 브랜치 전략&lt;/b&gt; (Git Flow, GitHub Flow)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;코드 리뷰&lt;/b&gt; 정책 및 PR 템플릿&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;컨벤션&lt;/b&gt; 및 &lt;b&gt;스타일 가이드&lt;/b&gt; 문서화&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;라이브러리 업데이트&lt;/b&gt; 정책&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;API 문서화&lt;/b&gt; (Swagger, GraphQL Playground)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;아키텍처 결정 기록&lt;/b&gt; (ADR) 작성&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;온보딩 가이드&lt;/b&gt; 및 개발 환경 설정&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;릴리즈 노트&lt;/b&gt; 및 변경 이력 관리&lt;/li&gt;
&lt;/ul&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;[ ] &lt;b&gt;이슈 및 작업 관리&lt;/b&gt; (Jira, Linear, GitHub Issues)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;스프린트 계획&lt;/b&gt; 및 애자일 프로세스&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;커뮤니케이션 도구&lt;/b&gt; (Slack, Discord, Teams)&lt;/li&gt;
&lt;li&gt;[ ] &lt;b&gt;지식 공유&lt;/b&gt; 및 회고 프로세스&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;핵심 체크리스트 요약표&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대분류 핵심 결정사항 주요 선택지/도구&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  프로젝트 정의&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;목표, 요구사항, 일정&lt;/td&gt;
&lt;td&gt;MVP 범위, 비즈니스 모델, 법적 검토&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; ️ 기술 스택&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;플랫폼 및 프레임워크&lt;/td&gt;
&lt;td&gt;Native/Cross-platform, 최소 지원 버전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; ️ 아키텍처&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;설계 패턴, 구조&lt;/td&gt;
&lt;td&gt;MVC/MVVM/Clean, Feature-based, DI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  상태 관리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;로컬/글로벌 상태&lt;/td&gt;
&lt;td&gt;Redux/Bloc/Provider, 서버 상태, 캐싱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  네비게이션&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;화면 이동 구조&lt;/td&gt;
&lt;td&gt;Stack/Tab/Drawer, 딥링크, 라우팅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  데이터 저장&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;저장소 전략&lt;/td&gt;
&lt;td&gt;SQLite/Realm, 암호화, 동기화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  네트워크/API&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;통신 방식&lt;/td&gt;
&lt;td&gt;REST/GraphQL, 인증, 에러 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;⚡ 비동기 처리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;비동기 패턴&lt;/td&gt;
&lt;td&gt;Promise/RxJS, 백그라운드 작업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  UI/UX&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;/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;/b&gt;&lt;/td&gt;
&lt;td&gt;다국어/지역화&lt;/td&gt;
&lt;td&gt;문자열 관리, RTL, 로컬 형식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&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;/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;/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;/b&gt;&lt;/td&gt;
&lt;td&gt;테스트 전략&lt;/td&gt;
&lt;td&gt;Unit/Integration/E2E, 자동화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&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;/b&gt;&lt;/td&gt;
&lt;td&gt;알림 전략&lt;/td&gt;
&lt;td&gt;FCM/APNs, 딥링크, 권한 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;  배포/DevOps&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;배포 전략&lt;/td&gt;
&lt;td&gt;CI/CD, 환경 관리, 앱스토어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&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;/b&gt;&lt;/td&gt;
&lt;td&gt;팀 협업&lt;/td&gt;
&lt;td&gt;Git 전략, 문서화, 프로젝트 관리&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;b&gt;활용 팁&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;실무 활용 방법&lt;/b&gt;&lt;/h3&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;: 이 체크리스트를 Notion, Confluence 또는 GitHub 템플릿으로 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로젝트별 체크&lt;/b&gt;: 새 프로젝트 시작 전 체크박스 형태로 활용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;팀 공유&lt;/b&gt;: 체크 완료된 항목들을 팀원들과 공유하고 문서화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정기 리뷰&lt;/b&gt;: 프로젝트 진행 중 중요 결정사항 재검토&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;우선순위 가이드&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;  최우선&lt;/b&gt;: 1-3, 6-8번 (아키텍처, 상태관리, 데이터, 네트워크)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;⚡ 중요&lt;/b&gt;: 4-5, 9-10, 15번 (네비게이션, UI/UX, 접근성, 테스트)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;  점진적&lt;/b&gt;: 11-14, 16-20번 (국제화, 성능, 보안, 모니터링 등)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/53</guid>
      <comments>https://dongmindevloper.tistory.com/53#entry53comment</comments>
      <pubDate>Fri, 30 May 2025 08:27:47 +0900</pubDate>
    </item>
    <item>
      <title>어플리케이션 플랫폼을 넘나드는 체계적 접근법</title>
      <link>https://dongmindevloper.tistory.com/54</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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글은 앱을 개발할때 일반적으로 체크해야될 사항에 대해서 말씀드리고자 합니다. ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 AI 에이전트 개발을 진행하다가 왜 갑자기 이런 내용의 글을 쓰게 됐는지 의아해 할 수도 있을 것 같습니다. 이것은 제가 글을 쓰는 목적과도 연관이 있습니다. 저는 더 이상 앱 개발을 진행할때 플랫폼은 그렇게 중요하다고 생각하지 않기 떄문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요하다고 생각하지 않는다는 말을 풀어서 설명드리면 &lt;u&gt;&lt;b&gt;하나의 플랫폼에 대해서 깊게 공부하고 개발 경험이 있는 개발자라면&lt;/b&gt;&lt;/u&gt; AI 에이전트 개발을 이용해서 어떤 플랫폼이든 개발하는데 문제가 없다는게 제 생각이자 최종 목표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;본질적으로 해결해야 할 문제들은 놀랍도록 유사&lt;/b&gt;합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 공통 영역&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 내비게이션 시스템&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;화면 간 이동 로직&lt;/li&gt;
&lt;li&gt;사용자 경험 흐름 설계&lt;/li&gt;
&lt;li&gt;히스토리 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 데이터 저장 방식&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬 저장소 관리&lt;/li&gt;
&lt;li&gt;원격 데이터 동기화&lt;/li&gt;
&lt;li&gt;캐싱 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 아키텍처 패턴&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MVVM, MVP, Clean Architecture 등&lt;/li&gt;
&lt;li&gt;의존성 주입&lt;/li&gt;
&lt;li&gt;상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. UI 개발 방식&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트 기반 설계&lt;/li&gt;
&lt;li&gt;반응형 레이아웃&lt;/li&gt;
&lt;li&gt;테마 및 스타일링&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 네트워킹&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API 통신&lt;/li&gt;
&lt;li&gt;에러 핸들링&lt;/li&gt;
&lt;li&gt;보안 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 공통 요소들을 체계적으로 정리하고, AI 에이전트에게 명확한 가이드라인을 제공하면 &lt;b&gt;플랫폼과 상관없이 일관된 품질의 개발&lt;/b&gt;이 가능하다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실전 체크리스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 시작하거나 기존 앱을 점검할 때 활용할 수 있는 포괄적인 체크리스트를 별도로 정리했습니다. 이 체크리스트는 AI 에이전트와의 협업 시 매우 유용한 가이드라인이 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;상세 체크리스트 확인하기:&lt;/b&gt; &lt;a href=&quot;https://dongmindevloper.tistory.com/53&quot;&gt;https://dongmindevloper.tistory.com/53&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 시대의 개발자는 특정 플랫폼에 종속되기보다는, &lt;b&gt;문제 해결 능력과 체계적 사고&lt;/b&gt;에 집중해야 합니다. 플랫폼의 세부사항은 AI 에이전트가 도와줄 수 있지만, 전체적인 설계와 방향성은 여전히 개발자의 몫입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 접근법을 통해 더 효율적이고 확장 가능한 개발이 가능할 것이라 믿습니다. 여러분도 이런 방식으로 개발해보시길 추천드립니다.&lt;/p&gt;</description>
      <category>AI로 앱 개발</category>
      <author>엔디엘(no Dream no Life)</author>
      <guid isPermaLink="true">https://dongmindevloper.tistory.com/54</guid>
      <comments>https://dongmindevloper.tistory.com/54#entry54comment</comments>
      <pubDate>Fri, 30 May 2025 08:15:31 +0900</pubDate>
    </item>
  </channel>
</rss>