<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>codeflow</title>
    <link>https://codeflow.tistory.com/</link>
    <description>IT 지식을 다룹니다</description>
    <language>ko</language>
    <pubDate>Thu, 11 Jun 2026 10:45:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>codeflow</managingEditor>
    <image>
      <title>codeflow</title>
      <url>https://tistory1.daumcdn.net/tistory/5668621/attach/6396adb4d9424581bd0992216f0e7a21</url>
      <link>https://codeflow.tistory.com</link>
    </image>
    <item>
      <title>테스트 자동화: Python으로 Appium 서버를 자동으로 실행하기</title>
      <link>https://codeflow.tistory.com/entry/%08%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-Python%EC%9C%BC%EB%A1%9C-Appium-%EC%84%9C%EB%B2%84%EB%A5%BC-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Appium 서버를 자동으로 실행시키려면?&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬으로 짠 스크립트를 실행시킬 때 appium 서버가 먼저 실행되어 있지 않으면 스크립트가 동작하지 않습니다. appium 서버를 먼저 실행시킬 때 가장 일반적인 방법은 아래와 같이 터미널에서 appium이라는 명령어 를 입력하는 것입니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9jyzb/btsGwMM7mNC/rbrMjxNzpwFLqc8GTBKL8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9jyzb/btsGwMM7mNC/rbrMjxNzpwFLqc8GTBKL8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9jyzb/btsGwMM7mNC/rbrMjxNzpwFLqc8GTBKL8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9jyzb%2FbtsGwMM7mNC%2FrbrMjxNzpwFLqc8GTBKL8k%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;891&quot; height=&quot;312&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 완전한 자동화를 꿈꾼다면 appium 서버를 별도로 실행시키는 게 번거로울 수도 있습니다. 그럴 때는 코드 상에서 appium 서버를 자동으로 실행시키도록 적용하면 되는데요, 파이썬은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;pytest의 autouse 기능을 통해 AppiumService fixture가 항상 실행되도록 설정&lt;/span&gt;하면 간단하게 해결할 수 있습니다. 아래와 같이 fixture에 &lt;b&gt;autouse=True&lt;/b&gt;가 들어가도록 코드를 짜면 됩니다. 해당 코드를 &lt;b&gt;conftest.py&lt;/b&gt; 파일에 추가해주면 됩니다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from appium.webdriver.appium_service import AppiumService

# APPIUM settings
APPIUM_PORT = 4723
APPIUM_HOST = &quot;127.0.0.1&quot;

@pytest.fixture(autouse=True)
def appium_service():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service = AppiumService()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service.start(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args=[&quot;--address&quot;, APPIUM_HOST, &quot;-p&quot;, str(APPIUM_PORT)],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeout_ms=20000,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield service
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service.stop()&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;appium 서버만 실행시켜서는 테스트 스크립트가 동작하지 않습니다. 모바일 기기를 구동시킬 드라이버도 함께 실행해야 하는데요, android의 경우 desired capabilities를 통해 플랫폼 이름, automation 이름, app 설치 경로만 설정해주면 동작하므로, 이렇게 설정된 최소한의 동작 코드는 다음과 같습니다. 여기서도 driver fixture에 autouse를 True로 설정해주었습니다. 그러면 테스트 함수에서는 별도로 driver fixture를 호출하지 않아도 사용이 가능합니다. &lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;@pytest.fixture(autouse=True)
def driver():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;driver = create_android_driver()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield driver
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;driver.quit()


def create_android_driver():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options = UiAutomator2Options()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;caps = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;platformName&quot;: &quot;Android&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;appium:options&quot;: {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;automationName&quot;: &quot;UIAutomator2&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;app&quot;: f&quot;{APPS_PATH}/ApiDemos-debug.apk&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.load_capabilities(caps)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return webdriver.Remote(f&quot;http://{APPIUM_HOST}:{APPIUM_PORT}&quot;, options=options)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;이제 appium 서버와 UIAutomator2 드라이버를 실행할 테스트 코드를 짜볼까요? 아주 간단하게 ApiDemos-debug 테스트 앱을 실행시켜서 30초간 화면만 유지하는 코드는 다음과 같습니다. 임의로 test_main.py 파일에 test_sample이라는 테스트 함수를 추가해서 작성했습니다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import time
def test_sample():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(30)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;이제 터미널에서 pytest만 입력하면 실행시킬 수 있습니다.  &lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBpTr/btsGwilrPQZ/HSbo4yPp1b6YM2G01PxIZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBpTr/btsGwilrPQZ/HSbo4yPp1b6YM2G01PxIZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBpTr/btsGwilrPQZ/HSbo4yPp1b6YM2G01PxIZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtBpTr%2FbtsGwilrPQZ%2FHSbo4yPp1b6YM2G01PxIZ1%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;1416&quot; height=&quot;287&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;아주 간단한 코드지만 appium 설치 후 테스트 앱을 다운로드 받고, 파이썬 패키지를 설치한 후에 제대로 동작하기 때문에 처음 모바일 테스트 자동화를 시작하시는 분들은 이 설정 부분이 더 어려울 수도 있습니다. 그래서 아래와 같이 정리해두었으니 그대로 따라해보시길 바래요 :)&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;사전 조건&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;appium 설치 및 환경 설정: &lt;a href=&quot;https://codeflow.tistory.com/entry/%08Appium%EC%9C%BC%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;2023.11.25 - [Automation] - 테스트 자동화: Appium으로 모바일 테스트 자동화 환경 구축하기&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;테스트 앱 다운로드: &lt;a href=&quot;https://codeflow.tistory.com/entry/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-Appium-Inspector%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EC%95%B1-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;2024.04.07 - [Automation] - 테스트 자동화: Appium Inspector로 모바일 앱 실행하기&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;실행 순서&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;VS Code에서 프로젝트 폴더 생성&lt;/li&gt;&lt;li&gt;프로젝트 폴더에서 터미널을 열고 &lt;b&gt;python -m venv venv; source venv/bin/activate&lt;/b&gt;로 가상환경 설정&lt;/li&gt;&lt;li&gt;터미널에서 &lt;b&gt;touch requirements.txt, conftest.py, test_main.py&lt;/b&gt; 실행해 빈 파일 만들기&lt;/li&gt;&lt;li&gt;아래 코드 붙여넣기&lt;/li&gt;&lt;li&gt;터미널에서 &lt;b&gt;pip install -r requirements.txt&lt;/b&gt;를 입력해 파이썬 패키지 다운로드&lt;/li&gt;&lt;li&gt;파인더 혹은 터미널을 통해 테스트 앱을 &lt;b&gt;~/Downloads/apps&lt;/b&gt; 경로에 복사&lt;/li&gt;&lt;li&gt;터미널에서 &lt;b&gt;pytest&lt;/b&gt;를 입력해 appium 서버와 클라이언트 및 테스트 스크립트 실행&lt;/li&gt;&lt;/ol&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 트리 구조&lt;/h2&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;.
├── conftest.py
├── requirements.txt
├── test_main.py
└── venv&lt;/code&gt;&lt;/pre&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;전체 코드&lt;/h2&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;requirements.txt&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;Appium-Python-Client&amp;gt;=4.0.0
pytest&amp;gt;=8.1.1&lt;/code&gt;&lt;/pre&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;conftest.py&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import os
import pytest
from appium import webdriver
from appium.webdriver.appium_service import AppiumService
from appium.options.android import UiAutomator2Options
from appium.options.ios import XCUITestOptions

APPS_PATH = f&quot;{os.path.expanduser('~')}/Downloads/apps&quot;

# APPIUM settings
APPIUM_PORT = 4723
APPIUM_HOST = &quot;127.0.0.1&quot;


@pytest.fixture(scope=&quot;session&quot;, autouse=True)
def appium_service():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service = AppiumService()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service.start(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args=[&quot;--address&quot;, APPIUM_HOST, &quot;-p&quot;, str(APPIUM_PORT)],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeout_ms=20000,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield service
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;service.stop()


@pytest.fixture(autouse=True)
def driver():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;driver = create_android_driver()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield driver
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;driver.quit()


def create_android_driver():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options = UiAutomator2Options()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;caps = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;platformName&quot;: &quot;Android&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;appium:options&quot;: {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;automationName&quot;: &quot;UIAutomator2&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;app&quot;: f&quot;{APPS_PATH}/ApiDemos-debug.apk&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.load_capabilities(caps)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return webdriver.Remote(f&quot;http://{APPIUM_HOST}:{APPIUM_PORT}&quot;, options=options)


def create_ios_driver():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options = XCUITestOptions()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;caps = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;platformName&quot;: &quot;iOS&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;appium:options&quot;: {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;automationName&quot;: &quot;XCUITest&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;app&quot;: f&quot;{APPS_PATH}/TestApp.app&quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;options.load_capabilities(caps)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return webdriver.Remote(f&quot;http://{APPIUM_HOST}:{APPIUM_PORT}&quot;, options=options)&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;test_main.py&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import time
def test_sample():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(30)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Automation</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/36</guid>
      <comments>https://codeflow.tistory.com/entry/%08%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-Python%EC%9C%BC%EB%A1%9C-Appium-%EC%84%9C%EB%B2%84%EB%A5%BC-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0#entry36comment</comments>
      <pubDate>Wed, 10 Apr 2024 14:01:48 +0900</pubDate>
    </item>
    <item>
      <title>맥에서 파이썬 최신 버전 설치 및 python으로 python3 실행하기</title>
      <link>https://codeflow.tistory.com/entry/%EB%A7%A5%EC%97%90%EC%84%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B5%9C%EC%8B%A0-%EB%B2%84%EC%A0%84-%EC%84%A4%EC%B9%98-%EB%B0%8F-python%EC%9C%BC%EB%A1%9C-python3-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;맥에 파이썬을 설치하는 방법은 아주 간단합니다. &lt;a href=&quot;https://www.python.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.python.org/downloads/&lt;/a&gt; 에 들어가 상단에 보이는 Download Python 버튼을 눌러  패키지 파일을 다운로드 받고 실행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1215&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LSRbx/btsGqMmPNU5/F2P2j5ZxCzvDxE52HkdjIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LSRbx/btsGqMmPNU5/F2P2j5ZxCzvDxE52HkdjIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LSRbx/btsGqMmPNU5/F2P2j5ZxCzvDxE52HkdjIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLSRbx%2FbtsGqMmPNU5%2FF2P2j5ZxCzvDxE52HkdjIK%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;1215&quot; height=&quot;262&quot; data-origin-width=&quot;1215&quot; data-origin-height=&quot;262&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;해당 패키지 파일을 다운로드 받은 후 실행시키면 아래와 같이 Python 설치창이 뜨면서 UI 상에서 파이썬을 설치할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;894&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lmo9y/btsGshMY4PX/BsrKsHKvc7VYbMmzT8zXx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lmo9y/btsGshMY4PX/BsrKsHKvc7VYbMmzT8zXx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lmo9y/btsGshMY4PX/BsrKsHKvc7VYbMmzT8zXx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLmo9y%2FbtsGshMY4PX%2FBsrKsHKvc7VYbMmzT8zXx1%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;1242&quot; height=&quot;894&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;894&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;한 가지 더 확인해야할 사항은 아래 창에서 얘기하는대로 secure network 연결을 위해 SSL 루트 인증서 설치가 필요하다는 점입니다. 파인더 창에서 Install Certificates 아이콘을 더블클릭하면 된다고 하네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlOZHR/btsGqqRUYD3/8kpVtS477qomp4gZIJDtzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlOZHR/btsGqqRUYD3/8kpVtS477qomp4gZIJDtzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlOZHR/btsGqqRUYD3/8kpVtS477qomp4gZIJDtzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlOZHR%2FbtsGqqRUYD3%2F8kpVtS477qomp4gZIJDtzK%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;1232&quot; height=&quot;900&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;900&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; 위에서 Finder Window 링크를 클릭한 뒤 뜨는 파인더 창에서 Install Certificates.command 파일을 더블클릭하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbhLnO/btsGrWCdKo8/PZpNjBbF8urgkAToLGFGt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbhLnO/btsGrWCdKo8/PZpNjBbF8urgkAToLGFGt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbhLnO/btsGrWCdKo8/PZpNjBbF8urgkAToLGFGt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbhLnO%2FbtsGrWCdKo8%2FPZpNjBbF8urgkAToLGFGt0%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;1838&quot; height=&quot;488&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;488&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;그러면 아래와 같이 certifi 패키지가 설치되죠.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1924&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Z5Ie/btsGssOpZFu/JXcgFNe67B7hpVcZ6lAwx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Z5Ie/btsGssOpZFu/JXcgFNe67B7hpVcZ6lAwx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Z5Ie/btsGssOpZFu/JXcgFNe67B7hpVcZ6lAwx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Z5Ie%2FbtsGssOpZFu%2FJXcgFNe67B7hpVcZ6lAwx0%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;1924&quot; height=&quot;750&quot; data-origin-width=&quot;1924&quot; data-origin-height=&quot;750&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;이제 터미널을 새로 열어서 python3 -V를 쳐보면 버전 정보가 최신 버전으로 변경된 걸 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kXHjQ/btsGq1xge92/kIMdqby2lsJe8cSPCy42tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kXHjQ/btsGq1xge92/kIMdqby2lsJe8cSPCy42tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kXHjQ/btsGq1xge92/kIMdqby2lsJe8cSPCy42tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkXHjQ%2FbtsGq1xge92%2FkIMdqby2lsJe8cSPCy42tk%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;1150&quot; height=&quot;178&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;178&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;만약 python3 대신 python 명령어로 파이썬을 실행시키고 싶다면, zprofile(혹은 zshrc) 파일에서 alias로 python3를 python으로 호출할 수 있게 설정할 수 있습니다. 아래와 같이 한 줄을 넣어주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1712494733827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;alias python=python3&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;zprofile에 해당 문구를 넣어준 뒤 python -V 명령어로 적용된 python 버전이 최신 버전으로 업데이트 된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFSq41/btsGqq5sFCN/qqs8IP74us9Nn36qz7JY61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFSq41/btsGqq5sFCN/qqs8IP74us9Nn36qz7JY61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFSq41/btsGqq5sFCN/qqs8IP74us9Nn36qz7JY61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFSq41%2FbtsGqq5sFCN%2Fqqs8IP74us9Nn36qz7JY61%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;1732&quot; height=&quot;330&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Python</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/35</guid>
      <comments>https://codeflow.tistory.com/entry/%EB%A7%A5%EC%97%90%EC%84%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B5%9C%EC%8B%A0-%EB%B2%84%EC%A0%84-%EC%84%A4%EC%B9%98-%EB%B0%8F-python%EC%9C%BC%EB%A1%9C-python3-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0#entry35comment</comments>
      <pubDate>Sun, 7 Apr 2024 22:01:52 +0900</pubDate>
    </item>
    <item>
      <title>테스트 자동화: Appium Inspector로 모바일 앱 실행하기</title>
      <link>https://codeflow.tistory.com/entry/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-Appium-Inspector%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EC%95%B1-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;모바일 테스트 자동화를 목적으로 Appium을 통해 테스트 스크립트를 작성하려면 먼저 Appium Inspector와 친숙해져야 합니다. 테스트 자동화에서는 화면에 있는 특정 요소(element)인 버튼이나 텍스트 인풋박스, 드롭박스를 선택(click)하거나 텍스트를 입력(input)하는 행위를 수행하기 위해서 프로그래밍 언어로 테스트 스크립트를 작성합니다. 이 테스트 스크립트를 작성하기 위해서 화면에서 사용할 요소 정보가 필요한데 이 때 네이티브 앱이라면 Appium Inspector를 사용합니다. 자세한 사용 방법을 알아보기 앞서 이번 편에서는 Appium Insepector를 설치하고, 맥에서 Appium Inspector를 통해 모바일 앱을 실행하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사전 조건&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium Inspector를 실행하기 위한 사전 조건으로는 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Appium 2.0 이상 버전 설치 및 설정, Android Studio 설치 및 Path 설정, iOS 기기에 WDA 설치&lt;/span&gt;가 필요합니다. 이 과정 진행이 필요하다면 이전에 발행한 아래 글을 참고해주세요  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codeflow.tistory.com/entry/%08Appium%EC%9C%BC%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.11.25 - [Automation] - 테스트 자동화: Appium으로 모바일 테스트 자동화 환경 구축하기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Appium Inspector 설치하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sRdBf/btsGpZ1tdhJ/3VQfFvYxdOEbxknAbiItk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sRdBf/btsGpZ1tdhJ/3VQfFvYxdOEbxknAbiItk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sRdBf/btsGpZ1tdhJ/3VQfFvYxdOEbxknAbiItk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsRdBf%2FbtsGpZ1tdhJ%2F3VQfFvYxdOEbxknAbiItk0%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;1683&quot; height=&quot;647&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;647&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium Inspector는 이렇게 생겼습니다. 모바일 앱이 구동되면 각 화면에서 선택한 요소에 대해 Selected Element에서 해당 요소를 선택할 수 있는 Selector를 보여줍니다. 테스트 스크립트에서는 원하는 요소를 선택하기 위해 이 정보를 활용하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium Inspector를 설치하기 위해서는 &lt;a href=&quot;https://github.com/appium/appium-inspector/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/appium/appium-inspector/releases&lt;/a&gt;에 들어가서 최신 버전을 다운로드 받아 설치해주면 됩니다. 그리고 실행 시에는 appium을 먼저 실행해두고, 모바일 기기를 연결해 안드로이드 기준으로 개발자 모드에서 USB 연결을 허용해 둔 상태로 맥과 연결해두면 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Android 앱 실행하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 앱  실행  테스트를 위해 Appium 저장소(&lt;a href=&quot;https://github.com/appium/appium/tree/master/packages/appium/sample-code/apps&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/appium/appium/tree/master/packages/appium/sample-code/apps&lt;/a&gt;)에서 테스트 앱을 다운로드 받아둡니다. 다운로드 폴더에 apk 파일이 저장되어 있다는 가정 하에 Appium Inspector를 실행해 Desired Capabilities에 아래와 같이 작성해줍니다. Desired Capabilities를 통해 플랫폼 버전, 여러 기기 연결 시 기기 선택을 위한 udid, 얼럿에 대한 자동 수락 여부 등 다양한 옵션을 설정할 수 있습니다. 기기가 하나만 연결되어 있다면 apk 경로, platformName, automationName만 작성하면 테스트 앱을 실행해 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기기 연결 여부를 확인하기 위해서는 터미널에서 &lt;b&gt;adb devices&lt;/b&gt;를 입력해 해당 기기의 udid가 목록에 뜨는지 확인해주세요. 또한 Appium 2.0 이상 버전에서는 Remote Path에 /만 작성하면 됩니다. 실행 시에 에러가 난다면 /wd/hub로 설정되어 있을 가능성이 있으므로 한 번 더 확인해주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMHzYL/btsGsheZIzs/WJ3Hvz4npFVmD9Gb2Ids21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMHzYL/btsGsheZIzs/WJ3Hvz4npFVmD9Gb2Ids21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMHzYL/btsGsheZIzs/WJ3Hvz4npFVmD9Gb2Ids21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMHzYL%2FbtsGsheZIzs%2FWJ3Hvz4npFVmD9Gb2Ids21%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;992&quot; height=&quot;786&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;786&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; 또 다른 에러 가능성은 UIAutomator2 드라이버가 설치되어 있지 않는 경우입니다. 이 상황을 확인하려면 터미널에서 &lt;b&gt;appium driver list&lt;/b&gt;를 입력해 설치 여부를 확인해보세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh0cpG/btsGp1x9eHP/WlwGl6H7tWey545srnSA0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh0cpG/btsGp1x9eHP/WlwGl6H7tWey545srnSA0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh0cpG/btsGp1x9eHP/WlwGl6H7tWey545srnSA0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh0cpG%2FbtsGp1x9eHP%2FWlwGl6H7tWey545srnSA0k%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;713&quot; height=&quot;174&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;/figure&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;iOS의 경우 iOS 기기 연결 여부를 확인하는 간단한 방법이 &lt;b&gt;ios-deploy -c&lt;/b&gt;라는 명령어를 입력하는 것입니다. ios-deploy는&lt;b&gt; brew install ios-deploy&lt;/b&gt;로 설치할 수 있고, 설치 완료 후에는 앞선 명령어로 기기 연결 여부를 확인해 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;64&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RwRPS/btsGsiZhPsg/pkFt1hJnQbs3zacV8KXfP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RwRPS/btsGsiZhPsg/pkFt1hJnQbs3zacV8KXfP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RwRPS/btsGsiZhPsg/pkFt1hJnQbs3zacV8KXfP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRwRPS%2FbtsGsiZhPsg%2FpkFt1hJnQbs3zacV8KXfP1%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;1117&quot; height=&quot;64&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;64&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;iOS 실제 기기를 테스트에 이용하기 위해서는 가장 기본적으로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;개발자 계정에 가입된 애플 ID가 있어야 하고, WebDriverAgent(줄여서 WDA)를 먼저 기기에 설치&lt;/span&gt;해주어야 합니다. 만약 아래와 같이 '[DeviceName] is not available because it is unpaired'라고 뜬다면 페어링 과정을 진행해줘야 합니다.  기기를 맥에 연결 후 아이폰에서 맥을 신뢰하도록 설정해 줍니다. 이후 Xcode 기기 선택 창에서 하단의 &lt;b&gt;Manage Run Destinations&lt;/b&gt;을 누른 후 Devices 탭에서 기기 페어링 상태를 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LAXx9/btsGqvyJoOf/ubibMKOCJMtP8mhyZS9bI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LAXx9/btsGqvyJoOf/ubibMKOCJMtP8mhyZS9bI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LAXx9/btsGqvyJoOf/ubibMKOCJMtP8mhyZS9bI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLAXx9%2FbtsGqvyJoOf%2FubibMKOCJMtP8mhyZS9bI0%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;1714&quot; height=&quot;338&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;338&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;페어링 완료 후 WDA가 설치되었다면 Appium Inspector를 실행해 Android와 마찬가지로 테스트 앱 실행경로, 플랫폼 이름, 자동화 이름을 넣어준다음 udid까지 기입해 실행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1044&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQtqye/btsGq99Gb6w/DtV6EINfrAZKmpD0ZFYCd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQtqye/btsGq99Gb6w/DtV6EINfrAZKmpD0ZFYCd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQtqye/btsGq99Gb6w/DtV6EINfrAZKmpD0ZFYCd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQtqye%2FbtsGq99Gb6w%2FDtV6EINfrAZKmpD0ZFYCd1%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;1044&quot; height=&quot;511&quot; data-origin-width=&quot;1044&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Automation</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/34</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-Appium-Inspector%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EC%95%B1-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0#entry34comment</comments>
      <pubDate>Sun, 7 Apr 2024 21:33:03 +0900</pubDate>
    </item>
    <item>
      <title>테스트 자동화: Appium으로 모바일 테스트 자동화 환경 구축하기</title>
      <link>https://codeflow.tistory.com/entry/%08Appium%EC%9C%BC%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;Appium 2.0 서버를 이용해 안드로이드와 iOS 앱 테스트 자동화 환경을 구축하기 위한 환경 설정 방법을 알아보겠습니다. (맥OS, Apple M1, M2칩 기준)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;앱피움은 구조적으로 server, client, driver로 나뉩니다. appium server를 먼저 띄워놓고 자바, 파이썬, 자바스크립트 등 모바일에서 돌아가는 동작들을 특정 언어의 스크립트로 짠 후 실행시키면, appium client에 해당하는 이 코스 수행 요청이 http request로 appium server에 전달됩니다. 그러면 서버에서 이 요청 사항을 해석해 타겟 플랫폼 드라이버로 전달하게 됩니다. 안드로이드라면 UI Automator2나 Espresso를, iOS라면 XCUITest라는 OS측의 드라이버를 통해 실제 모바일 기기에서 동작하게 됩니다. (TMI: appium은 모바일 외에도 TV 등 여러 타겟 디바이스를 지원합니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;기본적으로 모바일 테스트 자동화 환경을 구축하려면 Appium 라이브러리를 다운로드 받은 후 관련된 추가적인 패키지들을 설치하고, 테스트 자동화 스크립트를 짤 프로그래밍 언어를 선택한 뒤 해당 프로그래밍 언어에 맞는 IDE를 준비합니다. 그리고 테스트할 안드로이드나 iOS 기기가 있으면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;Appium 설치하기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Appium 라이브러리는 기본적으로 nodeJS로 작성되어 있기 때문에 노드 패키지로 등록되어 있습니다. 따라서 다음의 npm 명령어로 다운로드 받으면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;npm install -g appium&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 style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;Appium 2.0부터는 타겟 디바이스별로 driver를 설치해주도록 변경되었기 때문에 다음 드라이버들도 같이 설치해줍니다. 각각 Android, iOS, 이미지 기반 클릭을 처리하는 드라이버입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;appium driver install uiautomator2&lt;br /&gt;appium driver install xcuitest&lt;br /&gt;appium plugin install images&lt;/blockquote&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;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;안드로이드 환경 설정하기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;안드로이드 앱을 테스트하기 위해서는 기본적으로 안드로이드 앱 개발 시 사용하는 Android Studio가 깔려있으면 좋습니다. 안드로이드 스튜디오를 통해 Android SDK 특정 버전을 쉽게 설치할 수 있고, 안드로이드 에뮬레이터 를 추가할 수 있으며. adb 설정이 잡혀있기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;안드로이드 스튜디오를 돌리기 전에 JDK를 먼저 설치해봅시다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;brew install openjdk&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 style=&quot;font-family: 'Nanum Gothic';&quot;&gt;심볼릭 링크를 걸어두면 편하기 때문에 아래 설정도 같이 해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk&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 style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;다음으로 &lt;a href=&quot;https://developer.android.com/studio?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;안드로이드 스튜디오를 설치&lt;/a&gt;하고, .zshrc 파일을 열어 다음과 같이 경로를 설정해 줍니다. (TMI: .zshrc 파일을 열 때는 터미널에서 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;open ~/.zshrc&lt;/span&gt;로 여는 게 편합니다.)&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;export JAVA_HOME_21=$(/usr/libexec/java_home -v21)&lt;br /&gt;export JAVA_HOME=$JAVA_HOME_21&lt;br /&gt;export ANDROID_HOME=/Users/bg/Library/Android/sdk&lt;br /&gt;export PATH=$PATH:$ANDROID_HOME/platform-tools&lt;br /&gt;export PATH=$PATH:$ANDROID_HOME/emulator&lt;br /&gt;export PATH=$PATH:$ANDROID_HOME/cmdline-tools&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 style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;JAVA_HOME_21을 분리한 이유는 JDK 버전을 변경할 때 JAVA_HOME 버전을 쉽게 설정하기 위해서입니다. 종종 JDK를 다운그레이드하거나 업그레이드 해야 할 이유가 발생하기 때문이죠. 특정 JDK 파일이 잘 설치되었는지 여부는 아래 명령어로 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;usr/libexec/java_home -V&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;iOS 환경 설정하기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;iOS는 안드로이드보다 환경 설정이 조금 더 까다롭습니다. WebDriverAgent(이하 WDA)라는 프로젝트를 Xcode 상에서 열어서 iOS 앱 등록시 사용한 정보를 넣어 직접 빌드한 후 iOS 기기에 미리 설치해두어야 하기 때문이죠. 기본적으로 테스트 코드를 작성할 담당자가 테스트할 iOS 앱의 개발자로 등록이 되어있어서 Apple App Connect 접속이 자유로워야 설정하기 편합니다. iOS 프로젝트의 빌드도 직접할 수 있는 게 좋습니다. &lt;span style=&quot;color: #555555; text-align: left;&quot;&gt;Apple App Connect에서는 팀 ID와 번들 ID를 확인할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;WDA 프로젝트는 appium 드라이버 명렁어로 다음과 같이 받을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;appium driver run xcuitest open-wda&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 style=&quot;font-family: 'Nanum Gothic';&quot;&gt;iOS 테스트 기기를 맥에 연결한 상태에서 해당 프로젝트를 Xcode에서 연 후, WebDriverAgentLib, WebDriverAgentRunner의 Signing &amp;amp; Capabilities에서 Team ID으로 개발자 계정을 설정하고 필요 시 WDA에 쓸 Bundle ID를 입력해 준 후 WebDriverAgentRunner에 대해 빌드를 돌립니다. 그러면 iOS 기기에 WDA가 설치되게 됩니다. WDA가 설치되면, 앱 스토어로 설치한 앱이 아니기 때문에 테스트 기기에서 최초 1회 개발자 앱 신뢰 설정을 해주어야지만 제대로 동작합니다. 기기 설정에서 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;일반&amp;gt; VPN 및 기기관리&amp;gt; 개발자 앱 신뢰&lt;/span&gt;로 들어가 해당 번들 ID로 신뢰 설정을 해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 외에 iOS 기기에 대한 추가적인 설정을 확인하고 싶다면 아래 appium 공식 문서를 참조해 주세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;더&amp;nbsp;읽어보기&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt; &lt;/span&gt;&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://appium.github.io/appium-xcuitest-driver/5.8/setup/&quot;&gt;https://appium.github.io/appium-xcuitest-driver/5.8/setup/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://appium.github.io/appium-xcuitest-driver/5.8/run-preinstalled-wda/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://appium.github.io/appium-xcuitest-driver/5.8/run-preinstalled-wda/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;마무리&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;이제 모바일 테스트 자동화를 실행하기 위한 사전 환경 설정이 모두 끝났습니다. 다음으로는 appium 서버를 아래 명령어로 실행시킨 뒤, 테스트 자동화 코드를 작성하면서 실행시켜보면 됩니다!&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;appium --use-plugins=images&lt;/blockquote&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;혹시 안드로이드 에뮬레이터와 iOS 시뮬레이터를 추가하고 동작시키는 방법을 알고 싶으시다면 &lt;a href=&quot;https://codeflow.tistory.com/entry/Android-Emulator%EC%99%80-iOS-Simulator-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅&lt;/a&gt;을 참고해주세요 :)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Automation</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/31</guid>
      <comments>https://codeflow.tistory.com/entry/%08Appium%EC%9C%BC%EB%A1%9C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%90%EB%8F%99%ED%99%94-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0#entry31comment</comments>
      <pubDate>Sat, 25 Nov 2023 17:22:49 +0900</pubDate>
    </item>
    <item>
      <title>플러터로 macOS 앱 만들기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0%EB%A1%9C-macOS-%EC%95%B1-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 codelab에서는 macOS 앱 예제로 &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/flutter-github-client#0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github Client&lt;/a&gt; 프로젝트를 다루고 있습니다. 이 프로젝트에서는 Github에서 OAuth2 app을 만들고 이 때 생성된 Client ID와 Client secret을 이용해 로그인에 사용하고 있습니다. 프로젝트를 완성하고 앱을 돌려보면 데스크탑 앱에서 로그인 버튼을 누르고 웹 브라우저로 전환되어 인증을 마친 뒤, 다시 데스크탑 앱으로 전환되는 과정을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서는 2가지 앱을 사용하는데, Github Client가 메인 앱이고, Windows to Front라는 플러그인을 만들어 Github 인증을 마치고 리다이렉트시 다시 데스크탑 앱인 Github Client로 돌아오게 해줍니다. 사용자 경험이 굉장히 좋은 앱이기 때문에 한 번 따라해보시길 추천해드립니다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Github에서 OAuth 설정&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;249&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BzetA/btrPsY0jfKl/xk5O0PokICS2o7GzDEYrJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BzetA/btrPsY0jfKl/xk5O0PokICS2o7GzDEYrJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BzetA/btrPsY0jfKl/xk5O0PokICS2o7GzDEYrJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBzetA%2FbtrPsY0jfKl%2Fxk5O0PokICS2o7GzDEYrJk%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;1102&quot; height=&quot;249&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github에서 OAuth App은 Settings 하위 Developer settings 메뉴에 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-25 오전 9.00.58.png&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKuMPY/btrPwARfBpg/fmmJOEhHMUv685Z2FbLrXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKuMPY/btrPwARfBpg/fmmJOEhHMUv685Z2FbLrXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKuMPY/btrPwARfBpg/fmmJOEhHMUv685Z2FbLrXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKuMPY%2FbtrPwARfBpg%2FfmmJOEhHMUv685Z2FbLrXK%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;792&quot; height=&quot;450&quot; data-filename=&quot;스크린샷 2022-10-25 오전 9.00.58.png&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Generate a new client'를 눌러서 secret을 생성해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-25 오전 9.02.29.png&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcdHYJ/btrPviXzRWJ/IKAaqCEKkhilMS20UAUwvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcdHYJ/btrPviXzRWJ/IKAaqCEKkhilMS20UAUwvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcdHYJ/btrPviXzRWJ/IKAaqCEKkhilMS20UAUwvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcdHYJ%2FbtrPviXzRWJ%2FIKAaqCEKkhilMS20UAUwvK%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;805&quot; height=&quot;292&quot; data-filename=&quot;스크린샷 2022-10-25 오전 9.02.29.png&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client secret이 추가된 걸 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.38.02.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLftqC/btrPycjYPhI/O6n83kpDkVJgLWiv5NrDXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLftqC/btrPycjYPhI/O6n83kpDkVJgLWiv5NrDXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLftqC/btrPycjYPhI/O6n83kpDkVJgLWiv5NrDXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLftqC%2FbtrPycjYPhI%2FO6n83kpDkVJgLWiv5NrDXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;660&quot; height=&quot;168&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.38.02.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 Client ID와 secret은 github_oauth_credentials.dart 파일에 붙여넣어 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요 코드 확인하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데스크탑에서 HTTP redirect server 구현&lt;/b&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/305b97d2b5cef39b61d4a73ee6e0ea3f.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트에서는 HTTP Client를 통해 OAuth2 인증 후에 정보를 받고 이 정보를 Redirect Server에 넘겨서 브라우저에 response로 &quot;Authenticated! You can close this tab.&quot; 문자열을 뿌려주는 과정을 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;github_login.dart&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;b&gt;브라우저 인증 완료 후 데스크탑 앱 활성화시키기&lt;/b&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/4c905cae7a380734a76ac83a106b76f7.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MacOS에서는 Windows to Front에 대한 플러그인을 만드는데 이 플러그인 내부에서 NSApplication의 activate 함수를 호출해 현재 app stack에서 Github Client 앱을 화면 최상단으로 끌어오게 됩니다. Github Client 앱에서는 Windows to Front 플러그인을 호출해 Github 인증이 끝난 브라우저에서 Github Client 앱으로 포커스를 옮겨옵니다. 데스크탑과 웹이 연동된 개발 시에 굉장히 유용하게 사용할 수 있을 것 같네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;완성된 앱 확인하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완성된 앱은 다음과 같습니다. Github 로그인 버튼 클릭을 클릭하면 브라우저로 이동해 OAuth2 흐름을 타고 Github과의 연동을 마친 뒤 다시 데스크탑 앱으로 돌아와 화면에 가져온 목록을 보여주는 모습입니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.09.44.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTXZJV/btrPyG5XeLH/D58QY9jdmGiHwU2CqwWRUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTXZJV/btrPyG5XeLH/D58QY9jdmGiHwU2CqwWRUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTXZJV/btrPyG5XeLH/D58QY9jdmGiHwU2CqwWRUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTXZJV%2FbtrPyG5XeLH%2FD58QY9jdmGiHwU2CqwWRUK%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;1824&quot; height=&quot;1480&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.09.44.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데스크탑 앱에서 Github 연결 시도&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2210&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5WfLJ/btrPti5gzDR/gyYAUeH3XRAGEyi2s1Qbk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5WfLJ/btrPti5gzDR/gyYAUeH3XRAGEyi2s1Qbk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5WfLJ/btrPti5gzDR/gyYAUeH3XRAGEyi2s1Qbk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5WfLJ%2FbtrPti5gzDR%2FgyYAUeH3XRAGEyi2s1Qbk1%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;2210&quot; height=&quot;1122&quot; data-origin-width=&quot;2210&quot; data-origin-height=&quot;1122&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;b&gt;인증 완료 후 github 저장소 목록을 가져오는 화면&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.11.12.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/saOrh/btrPApa1Mfx/m0cxSp6HFfc6HIw6nMwX41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/saOrh/btrPApa1Mfx/m0cxSp6HFfc6HIw6nMwX41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/saOrh/btrPApa1Mfx/m0cxSp6HFfc6HIw6nMwX41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsaOrh%2FbtrPApa1Mfx%2Fm0cxSp6HFfc6HIw6nMwX41%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;1824&quot; height=&quot;1480&quot; data-filename=&quot;스크린샷 2022-10-25 오후 9.11.12.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/27</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0%EB%A1%9C-macOS-%EC%95%B1-%EB%A7%8C%EB%93%A4%EA%B8%B0#entry27comment</comments>
      <pubDate>Tue, 25 Oct 2022 22:11:51 +0900</pubDate>
    </item>
    <item>
      <title>기억해둘 플러터(Flutter) 코드 작성 규칙</title>
      <link>https://codeflow.tistory.com/entry/%EA%B8%B0%EC%96%B5%ED%95%B4%EB%91%98-%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-%EA%B7%9C%EC%B9%99</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍 언어마다 공식적으로 권장하는 코딩 컨벤션이 조금씩 다릅니다. 특정 언어에서 다른 언어로 마이그레이션 할 때는 새로운 언어의 코딩 컨벤션에 맞게 코딩 스타일을 적용해주는 게 좋습니다. Java Script는 Java Script답게, Python은 Python답게, 플러터는 플러터답게 코딩하는 방식을 의미합니다. 그렇다면 플러터다운 코딩 방식은 어떤 걸까요? Dart에서 제공하는 Linter rules에서 주요 사항 몇 가지를 살펴보겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;패키지 임포트할 때 상대 경로 대신 절대 경로 쓰기 (always_use_package_imports)&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 72px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 18px;&quot;&gt;&lt;b&gt;Good&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 18px;&quot;&gt;&lt;b&gt;Bad&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 54px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 54px;&quot;&gt;import&amp;nbsp;'package:firebase_auth/firebase_auth.dart';&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000; background-color: #99cefa;&quot;&gt;import 'package:insta_clone/create_page.dart';&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; background-color: #99cefa;&quot;&gt;import 'package:insta_clone/model/page.dart';&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 54px;&quot;&gt;import&amp;nbsp;'package:firebase_auth/firebase_auth.dart';&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;import 'create_page.dart';&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;import '../model/page.dart';&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 임포트 시에 상대 경로보다는 해당 파일이 속한 패키지의 전체 경로를 써서 import 하길 권장합니다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제품 모드에서 print문 쓰지 않기 (avoid_print)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로덕션 (혹은 상용 혹은 운영) 환경에서 자주 호출되는 API에 print문을 넣었다가 문제가 생기는 경우가 종종 있습니다. 퍼포먼스를 느리게 만드는 주범이죠. 플러터에서도 프로덕션 환경에서 print 문을 쓰지 않길 권고하고 있습니다. 보통 프로덕션 환경에서는 로거를 통해 로그 수준을 제어하기 때문에 print문은 개발 환경에서만 쓰는 게 좋겠죠. 이 때는 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;kDebugMode&lt;/span&gt;인지를 체크하도록 권장하고 있습니다.&lt;/p&gt;
&lt;h4 id=&quot;flutter_style_todos&quot; data-ke-size=&quot;size20&quot;&gt;TODO에 Github 이름 남기기 (flutter_style_todos)&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;// TODO(username): message. &lt;br /&gt;// TODO(username): message, https://URL-to-issue&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 작성하다가 나중에 해야 할 일을 남길 때 코멘트로 TODO를 남기곤 합니다. 플러터에서는 이 TODO 코멘트에 문제를 이해하고 있는 사람의 Github 사용자 이름을 남기길 권장하고 있습니다. 이렇게 관리한다면 아무래도 협업할 때 히스토리를 파악하기 더 쉬워지겠죠?&lt;/p&gt;
&lt;h4 id=&quot;always_declare_return_types&quot; data-ke-size=&quot;size20&quot;&gt;항상 리턴 타입 선언하기 (always_declare_return_types)&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 72px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%;height: 18px;&quot;&gt;&lt;b&gt;Good&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;height: 18px;&quot;&gt;&lt;b&gt;Bad&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 54px;&quot;&gt;
&lt;td style=&quot;width: 50%;height: 54px;&quot;&gt;void&amp;nbsp;main()&amp;nbsp;{&amp;nbsp;}&lt;br /&gt;&amp;nbsp;_Foo _bar() =&amp;gt; _Foo();&lt;br /&gt;class _Foo { int _foo() =&amp;gt; 42; }&lt;br /&gt;typedef predicate = bool Function(Object o);&lt;/td&gt;
&lt;td style=&quot;width: 50%;height: 54px;&quot;&gt;main() { }&lt;br /&gt;_bar() =&amp;gt; _Foo();&lt;br /&gt;class _Foo { _foo() =&amp;gt; 42; }&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;b&gt;더&lt;span&gt;&amp;nbsp;&lt;/span&gt;읽어보기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #555555;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dart.dev/guides/language/effective-dart/style&quot;&gt;https://dart.dev/guides/language/effective-dart/style&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dart.dev/tools/linter-rules&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dart.dev/tools/linter-rules&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/26</guid>
      <comments>https://codeflow.tistory.com/entry/%EA%B8%B0%EC%96%B5%ED%95%B4%EB%91%98-%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-%EA%B7%9C%EC%B9%99#entry26comment</comments>
      <pubDate>Sun, 23 Oct 2022 09:00:54 +0900</pubDate>
    </item>
    <item>
      <title>Flutter Linter를 통해 코딩 스타일 맞추기</title>
      <link>https://codeflow.tistory.com/entry/Flutter-Linter%EB%A5%BC-%ED%86%B5%ED%95%B4-%EC%BD%94%EB%94%A9-%EC%8A%A4%ED%83%80%EC%9D%BC-%EB%A7%9E%EC%B6%94%EA%B8%B0</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Linter를 쓰는 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linter는 정적 분석을 통해 잠재적인 결함을 발견하고 코딩 스타일을 맞춰 가독성을 높일 목적으로 사용하는 툴입니다. 정적 분석(Static Analysis)이란 동적 분석과 반대되는 개념으로, 동적 분석이 소프트웨어를 실행시키면서 결함은 없는지 수행 속도는 괜찮은지 등을 분석하거나 테스트하는 방법이라면 정적 분석은 소프트웨어를 실행시키기 전에 정적 분석 툴로 코드를 체크하는 방법을 가리킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 분석은 동적 분석보다 빠르고 소프트웨어 실행이나 배포 전 결함을 잡아낼 수 있기 때문에 다트와 플러터에서도 해당 기능을 제공하고 있습니다. 현재 제가 사용하고 있는 Fluter 3.3.3 (Dart 2.18.2) 버전에서는 플러터 프로젝트를 생성하면 프로젝트 루트에 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;analysis_options.yaml&lt;/span&gt; 이라는 파일이 생성됩니다. 기본적으로 flutter_lints 플러그인을 포함하고 있기 때문에 여기에 린트 규칙을 추가해나갈 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Dart Analyze: 플러터 프로젝트에 정적 분석 돌려보기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-22 오전 10.50.10.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xIurH/btrPgfOoeEh/9VYAbpoB2UWdZGNg0eI520/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xIurH/btrPgfOoeEh/9VYAbpoB2UWdZGNg0eI520/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xIurH/btrPgfOoeEh/9VYAbpoB2UWdZGNg0eI520/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxIurH%2FbtrPgfOoeEh%2F9VYAbpoB2UWdZGNg0eI520%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;2004&quot; height=&quot;1232&quot; data-filename=&quot;스크린샷 2022-10-22 오전 10.50.10.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pub.dev/packages/flutter_lints&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flutter Lints&lt;/a&gt; 패키지 설명처럼 Flutter 2.3.0 이상에서는 Flutter Lints가 적용되어 있습니다. 이 패키지는 Dart의 lints를 베이스로 하고 있어서 Android Studio와 같은 IDE에서 Dart 플러그인이 적용된 상태로 플러터 코딩을 하면 자동으로 linter가 적용됩니다. 매뉴얼로 린터를 돌리고 싶을 때는 CLI 상 해당 프로젝트에서 dart analyze라고 입력하면 결과를 볼 수 있습니다. 위에서는 prefer_const_constructors 규칙에 따라 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&quot;Prefer const with constant constructors&quot;&lt;/b&gt;&lt;/span&gt;라는 안내가 나오네요. 생성자는 상태가 변하지 않으니 const 키워드를 붙여서 메모리를 절약하고 수행 속도를 빠르게 하라는 권고입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;플러터 프로젝트에 Linter 적용하기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceOwAT/btrPfWO4WMH/K3K8EBx76FzrOLaGXKeYKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceOwAT/btrPfWO4WMH/K3K8EBx76FzrOLaGXKeYKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceOwAT/btrPfWO4WMH/K3K8EBx76FzrOLaGXKeYKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceOwAT%2FbtrPfWO4WMH%2FK3K8EBx76FzrOLaGXKeYKk%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;2356&quot; height=&quot;1420&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 프로젝트에서 프로젝트 루트에 있는 analysis_options.yaml 파일을 처음 열면 linter의 rules에 아무런 내용이 보이지 않습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qqLqC/btrPgFMVH7m/W4ByhxpXp3eR1ZZgsBKRH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qqLqC/btrPgFMVH7m/W4ByhxpXp3eR1ZZgsBKRH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qqLqC/btrPgFMVH7m/W4ByhxpXp3eR1ZZgsBKRH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqqLqC%2FbtrPgFMVH7m%2FW4ByhxpXp3eR1ZZgsBKRH1%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;1698&quot; height=&quot;596&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상태에서 예시로 linter에 camel_case_types규칙을 추가하고 main.dart에는 적용을 제외하도록 anaysis_options.yaml 파일을 작성했습니다. 이제 main.dart가 아닌 다른 파일에서는 변수명이 등이 camel case가 아닐 때 linter가 감지하고 알려주게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EVYs1/btrPhoYlxDU/aHtfevSQkjOQLF8ua8bACk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EVYs1/btrPhoYlxDU/aHtfevSQkjOQLF8ua8bACk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EVYs1/btrPhoYlxDU/aHtfevSQkjOQLF8ua8bACk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEVYs1%2FbtrPhoYlxDU%2FaHtfevSQkjOQLF8ua8bACk%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;2080&quot; height=&quot;794&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장하고 test_variable이라는 파일 이름을 main.dart 파일과 main.dart가 아닌 파일을 열어 동시에 확인해보면, 설정한대로 main.dart가 아닌 파일에서만 경고 메시지가 뜨는 걸 확인할 수 있습니다. 이런 식으로 팀 내에서 공동의 코딩 규칙을 linter에서 설정해서 사용할 수 있습니다.&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;span&gt;&amp;nbsp;&lt;/span&gt;읽어보기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #555555;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://dart.dev/tools/dart-analyze&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dart.dev/tools/dart-analyze&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rydmike.com/blog_flutter_linting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://rydmike.com/blog_flutter_linting.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/25</guid>
      <comments>https://codeflow.tistory.com/entry/Flutter-Linter%EB%A5%BC-%ED%86%B5%ED%95%B4-%EC%BD%94%EB%94%A9-%EC%8A%A4%ED%83%80%EC%9D%BC-%EB%A7%9E%EC%B6%94%EA%B8%B0#entry25comment</comments>
      <pubDate>Sat, 22 Oct 2022 15:03:10 +0900</pubDate>
    </item>
    <item>
      <title>Dart 문법 1 - 함수에서 =&amp;gt;와 (_)와 .. 의미 이해하기</title>
      <link>https://codeflow.tistory.com/entry/Dart-%EB%AC%B8%EB%B2%95-1-%EC%99%80-%EC%99%80-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 코드랩에서 제공하는 &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/flutter-cupertino#0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Cupertino App&lt;/a&gt;을 살펴보다가 이 프로젝트의 main.dart에서 사용하는 dart 문법이 흥미로워 소개해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/80c62a13e567b6e119541e6dcb6eff75.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 코드의 핵심은 provider 라이브러리에서 제공하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider-class.html&quot;&gt;ChangeNotifierProvider&lt;/a&gt;&amp;nbsp;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;클래스를 통해 서로 다른 탭에서 동일한 리스트 아이템을 보여주는 것입니다.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;함수의 리턴을 의미하는 =&amp;gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;=&amp;gt;는 arrow syntax라고 부릅니다. 이 arrow syntax 왼쪽에는 함수명이, 오른쪽에는 리턴값이 위치합니다. Javascript 계열 언어에서 자주 등장하는 문법입니다. 위 예제의 main()함수에서는 =&amp;gt;를 통해 새로운 ChangeNotifier로 AppStateModel 클래스의 loadProudctions()를 리턴하고 있네요.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;파라미터 무시를 의미하는 (_)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;create 파라미터에 쓰인 (_)는 파라미터를 무시할 때 사용합니다. create는 required로 BuildContext 타입을 받게 정의되어 있지만, 위의 예제에서는 BuildContext를 사용하지 않아서 파라미터를 무시하고 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;객체의 멤버 변수나 함수에 접근하는 ..&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;..은 임시 변수의 사용 없이 이미 선언된 특정 객체의 멤버 변수나 멤버 함수에 접근할 때 사용합니다. 위 예시에서는 AppStateModel 객체의 loadProducts() 함수에 접근할 때, &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;model = new AppStateModel(); model.loadProducts()&lt;/span&gt; &lt;/b&gt;대신 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;AppStateModel()..loadProducts()&lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;더&lt;span&gt;&amp;nbsp;&lt;/span&gt;읽어보기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #555555;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dart.dev/guides/language/language-tour#cascade-notation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dart.dev/guides/language/language-tour#cascade-notation&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dart.dev/guides/language/language-tour#functions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dart.dev/guides/language/language-tour#functions&lt;/a&gt;&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>DART</category>
      <category>다트</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/24</guid>
      <comments>https://codeflow.tistory.com/entry/Dart-%EB%AC%B8%EB%B2%95-1-%EC%99%80-%EC%99%80-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0#entry24comment</comments>
      <pubDate>Fri, 21 Oct 2022 23:56:04 +0900</pubDate>
    </item>
    <item>
      <title>Android Emulator와 iOS Simulator 생성하기</title>
      <link>https://codeflow.tistory.com/entry/Android-Emulator%EC%99%80-iOS-Simulator-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</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;안드로이드와 iOS의 가상 디바이스를 생성해봅시다. 가상 디바이스는 기본적으로 해당 OS에서 제공하는 IDE를 통해 생성하게 됩니다. 안드로이드 에뮬레이터는 안드로이드 스튜디오(Android Studio)를, iOS 시뮬레이터는 Xcode를 통해 생성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안드로이드 에뮬레이터 (Android Emulator) 생성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오를 설치하고 Android SDK 환경 변수를 설정하는 방법은 &lt;a href=&quot;https://codeflow.tistory.com/entry/플러터-개발-환경-구축&quot;&gt;2022.10.03 - [Flutter] - Flutter 개발 환경 구축 1 - SDK 설치와 환경변수 설정&lt;/a&gt; 에서 다룬 적이 있습니다. 안드로이드 스튜디오 설치가 되어 있다면 Virtual Device Manager를 통해 에뮬레이터를 새로 생성할 수 있습니다. 안드로이드 스튜디오를 띄운 후 케밥 메뉴 버튼을 눌러 Virtual Device Manager를 실행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRsrX5/btrO5s7yU4C/Z19NjRcYrJDZB9dUXBveA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRsrX5/btrO5s7yU4C/Z19NjRcYrJDZB9dUXBveA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRsrX5/btrO5s7yU4C/Z19NjRcYrJDZB9dUXBveA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRsrX5%2FbtrO5s7yU4C%2FZ19NjRcYrJDZB9dUXBveA1%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;2032&quot; height=&quot;400&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Device Manager가 열리면 Create device 버튼을 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.42.16.png&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOldJa/btrO36dhCIY/6Eo85oSBR3ge5KAneLwUD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOldJa/btrO36dhCIY/6Eo85oSBR3ge5KAneLwUD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOldJa/btrO36dhCIY/6Eo85oSBR3ge5KAneLwUD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOldJa%2FbtrO36dhCIY%2F6Eo85oSBR3ge5KAneLwUD1%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;1736&quot; height=&quot;470&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.42.16.png&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 가상 디바이스를 설정하는 단계가 되었습니다. 먼저 하드웨어 사양을 정해줍니다. 여기서는 Play Store가 지원되는 Pixel 3를 선택해 보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.46.00.png&quot; data-origin-width=&quot;2136&quot; data-origin-height=&quot;1736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bym0nt/btrO6OCgO2f/332oIFuNefygXgQKc4K1Lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bym0nt/btrO6OCgO2f/332oIFuNefygXgQKc4K1Lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bym0nt/btrO6OCgO2f/332oIFuNefygXgQKc4K1Lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbym0nt%2FbtrO6OCgO2f%2F332oIFuNefygXgQKc4K1Lk%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;2136&quot; height=&quot;1736&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.46.00.png&quot; data-origin-width=&quot;2136&quot; data-origin-height=&quot;1736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next 버튼을 누르면 다음 단계로 소프트웨어 플랫폼 (SDK) 사양을 설정합니다. 여기서는 현재 최신 사양인 API 33을 선택해 보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.47.18.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deyg0q/btrO4hlosTu/Y4jmSu4OkmwfZVNKGPOYq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deyg0q/btrO4hlosTu/Y4jmSu4OkmwfZVNKGPOYq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deyg0q/btrO4hlosTu/Y4jmSu4OkmwfZVNKGPOYq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdeyg0q%2FbtrO4hlosTu%2FY4jmSu4OkmwfZVNKGPOYq1%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;2224&quot; height=&quot;1824&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.47.18.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 우측 하단의 API level distribution chart을 클릭하면 아래 그림과 같이 플랫폼 버전별 API 레벨과 지원 스펙을 확인할 수 있습니다. 버전이 올라갈수록 최신 기능을 지원하지만 그만큼 기기 커버리지가 줄어든다는 사실을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.49.30.png&quot; data-origin-width=&quot;2424&quot; data-origin-height=&quot;1724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ymFi4/btrOEpLmtgm/aRr5A5wUAKNbi5Y8KMhFJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ymFi4/btrOEpLmtgm/aRr5A5wUAKNbi5Y8KMhFJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ymFi4/btrOEpLmtgm/aRr5A5wUAKNbi5Y8KMhFJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FymFi4%2FbtrOEpLmtgm%2FaRr5A5wUAKNbi5Y8KMhFJK%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;2424&quot; height=&quot;1724&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.49.30.png&quot; data-origin-width=&quot;2424&quot; data-origin-height=&quot;1724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 메인 화면으로 돌아와 API 33의 Download를 누르면 API 33 버전의 SDK를 설치하게 됩니다. 참고로 이 화면에서 SDK 경로도 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.54.23.png&quot; data-origin-width=&quot;1936&quot; data-origin-height=&quot;1484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYelJR/btrOQwJEyJd/9YRry4sfx85tfhH0Smc7kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYelJR/btrOQwJEyJd/9YRry4sfx85tfhH0Smc7kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYelJR/btrOQwJEyJd/9YRry4sfx85tfhH0Smc7kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYelJR%2FbtrOQwJEyJd%2F9YRry4sfx85tfhH0Smc7kk%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;1936&quot; height=&quot;1484&quot; data-filename=&quot;스크린샷 2022-10-19 오후 9.54.23.png&quot; data-origin-width=&quot;1936&quot; data-origin-height=&quot;1484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 다 되면 최종 사양을 한 번 더 점검할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.10.28.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TggS6/btrO5tFo7df/gHKQIAYO4FpOkxIBGOa9EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TggS6/btrO5tFo7df/gHKQIAYO4FpOkxIBGOa9EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TggS6/btrO5tFo7df/gHKQIAYO4FpOkxIBGOa9EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTggS6%2FbtrO5tFo7df%2FgHKQIAYO4FpOkxIBGOa9EK%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;2224&quot; height=&quot;1824&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.10.28.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 설정된 저장 용량 2048MB가 적어 보여서 4GB(4096MB)로 늘려주었습니다. 컴퓨터 키보드를 쓸 수 있도록 'Enable keyboard input'이 체크되어 있는지도 확인한 후 Finish 버튼을 눌러줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.13.04.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/conR7d/btrODQimbKF/pJHUSx1PrGfKyZhXlSCDfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/conR7d/btrODQimbKF/pJHUSx1PrGfKyZhXlSCDfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/conR7d/btrODQimbKF/pJHUSx1PrGfKyZhXlSCDfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FconR7d%2FbtrODQimbKF%2FpJHUSx1PrGfKyZhXlSCDfk%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;2224&quot; height=&quot;1824&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.13.04.png&quot; data-origin-width=&quot;2224&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 디바이스가 생성된 다음 Actions에서 실행 버튼을 누르면 새로 생성한 안드로이드 에뮬레이터가 실행됩니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c373AK/btrOQEnnhjQ/uYnKrypkvLyL9IPdaHOg8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c373AK/btrOQEnnhjQ/uYnKrypkvLyL9IPdaHOg8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c373AK/btrOQEnnhjQ/uYnKrypkvLyL9IPdaHOg8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc373AK%2FbtrOQEnnhjQ%2FuYnKrypkvLyL9IPdaHOg8K%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;1600&quot; height=&quot;830&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;830&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 디바이스가 잘 인식되어 있는지 보려면 터미널에서 adb devices를 쳐보면 됩니다. 아래 화면에서는 emulator-5554라는 이름의 가상 디바이스를 인식하고 있는 걸 확인할 수 있습니다. 만약 adb 명령어가 안된다면 환경 변수 파일을 열어서 Android SDK 경로에 대한 platform-tools 경로가 잘 잡혀있는지 확인해보면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.22.48.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCbzoV/btrO313uGrH/hGh0iqjL2Vb7uY9BXtAZH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCbzoV/btrO313uGrH/hGh0iqjL2Vb7uY9BXtAZH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCbzoV/btrO313uGrH/hGh0iqjL2Vb7uY9BXtAZH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCbzoV%2FbtrO313uGrH%2FhGh0iqjL2Vb7uY9BXtAZH1%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;2004&quot; height=&quot;1232&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.22.48.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;iOS 시뮬레이터 (iOS Simulator) 생성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS 시뮬레이터의 경우, IDE로 Xcode를 설치해야 합니다. Xcode는 앱 스토어에서 최신 버전을 설치하면 됩니다. Xcode 설치 후에는 Xcode의 Open Developer Tool &amp;gt; Simulator 메뉴를 통해 시뮬레이터를 실행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오전 8.11.09.png&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DKTuZ/btrOZ8928bQ/JXer0cCxKvtv2xc9eYhAOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DKTuZ/btrOZ8928bQ/JXer0cCxKvtv2xc9eYhAOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DKTuZ/btrOZ8928bQ/JXer0cCxKvtv2xc9eYhAOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDKTuZ%2FbtrOZ8928bQ%2FJXer0cCxKvtv2xc9eYhAOK%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;1856&quot; height=&quot;718&quot; data-filename=&quot;스크린샷 2022-10-19 오전 8.11.09.png&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 기기를 추가할 때는 독 바의 Xcode 아이콘을 클릭해 기기 타입을 선택하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.38.25.png&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;1560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNrABU/btrO36xKVyc/BoNj8dSAHk8tXDQYdTAh31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNrABU/btrO36xKVyc/BoNj8dSAHk8tXDQYdTAh31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNrABU/btrO36xKVyc/BoNj8dSAHk8tXDQYdTAh31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNrABU%2FbtrO36xKVyc%2FBoNj8dSAHk8tXDQYdTAh31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1696&quot; height=&quot;1560&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.38.25.png&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;1560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS에서는 기기의 UDID를 활용하는 경우가 많으므로 필요한 경우&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt; xcrun simctl getenv booted SIMULATOR_UDID&lt;/span&gt;&lt;/b&gt; 커맨드를 입력해 UDID를 확인합니다. 이렇게 확인한 UDID는 터미널에서 바로 해당 UDID를 가진 기기를 실행시킬 때도 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.43.39.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyi5FL/btrO5fNH2iR/0pBxEUw9aKfG1sKaDPLAM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyi5FL/btrO5fNH2iR/0pBxEUw9aKfG1sKaDPLAM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyi5FL/btrO5fNH2iR/0pBxEUw9aKfG1sKaDPLAM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcyi5FL%2FbtrO5fNH2iR%2F0pBxEUw9aKfG1sKaDPLAM0%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;2004&quot; height=&quot;476&quot; data-filename=&quot;스크린샷 2022-10-19 오후 10.43.39.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>ProTips</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/23</guid>
      <comments>https://codeflow.tistory.com/entry/Android-Emulator%EC%99%80-iOS-Simulator-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0#entry23comment</comments>
      <pubDate>Wed, 19 Oct 2022 23:21:45 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - Firebase에 올린 파일 보여주기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Firebase%EC%97%90-%EC%98%AC%EB%A6%B0-%ED%8C%8C%EC%9D%BC-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase의 Cloud Storage에 올린 이미지나 동영상 파일을 앱을 통해 사용자에게 보여주려면 DB 서비스인 Firestore 서비스를 이용하면 됩니다. (Firebase에서는 JSON 형식의 실시간 데이터베이스도 지원하는데 나중에 살펴보겠습니다.)&amp;nbsp; Cloud Storage가 파일 서버라면 Cloud Firestore는 NoSQL형 DB 서버로 Storage에 올린 파일의 URL 주소나 메타데이터 등 텍스트 정보를 ID가 있는 DB 형식으로 저장할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span data-token-index=&quot;0&quot; data-reactroot=&quot;&quot;&gt;Firebase 콘솔에서 Cloud Firestore 생성하기&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2242&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUMqgS/btrOZ9ANUVi/kN0J2Le0zCl6EMnqqh7W1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUMqgS/btrOZ9ANUVi/kN0J2Le0zCl6EMnqqh7W1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUMqgS/btrOZ9ANUVi/kN0J2Le0zCl6EMnqqh7W1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUMqgS%2FbtrOZ9ANUVi%2FkN0J2Le0zCl6EMnqqh7W1k%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;2242&quot; height=&quot;778&quot; data-origin-width=&quot;2242&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase 콘솔에서 Clode Firestore는 '시작하기' 버튼으로 쉽게 추가할 수 있습니다. Firestore Database를 추가하면, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;컬렉션, 문서, 필드로 이루어진 구조&lt;/span&gt;를 볼 수 있습니다. 특정 데이터의 집합을 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'컬렉션'&lt;/span&gt;&lt;/b&gt;이라고 부르고, 이 컬렉션에 특정 필드들을 추가할 때마다 하나의 문서로 생성되어 컬렉션에 저장되게 됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Cloud Firestore &lt;span data-token-index=&quot;1&quot; data-reactroot=&quot;&quot;&gt;플러그인 추가하기&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;dependencies: &lt;br /&gt;&amp;nbsp; image_picker: ^0.8.6&lt;br /&gt;&amp;nbsp; google_sign_in: ^5.4.2&lt;br /&gt;&amp;nbsp; firebase_core : ^1.24.0&lt;br /&gt;&amp;nbsp; firebase_auth: ^3.11.2&lt;br /&gt;&amp;nbsp; cloud_firestore: ^3.5.1&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pubspec.yaml 파일에 Cloud Firestore 플러그인 사용을 위한 버전을 추가해줍니다. 위 예제에서는 현재 최신 버전인 3.5.1을 적용했습니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;플러터 프로젝트에서 코드 작성하기&lt;/h4&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/3fbe3c16cbccc1617ca72f5d9e484c7e.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_uploadPost() 메서드는 이전 포스트에서 다룬 Cloud Storage에 파일을 저장한 뒤 이 Task의 레퍼런스를 통해 파일 저장 위치에 대한 URL을 얻고, Firestore의 post라는 컬렉션에 id, photo url, contents, email, display name, user photo url을 필드로 포함하는 새로운 문서를 생성하고 있습니다. _uploadPost() 메서도의 실행 결과 문서는 앞서 살펴본 Firebase 콘솔의 Cloud Firestore DB에 저장되어 Cloud Storage에 저장된 파일 참조 및 Firebase에 로그인한 유저 정보 등을 담게 됩니다.&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;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://firebase.google.com/docs/database/rtdb-vs-firestore?authuser=0&amp;amp;hl=ko&quot;&gt;https://firebase.google.com/docs/database/rtdb-vs-firestore?authuser=0&amp;amp;hl=ko&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://firebase.google.com/docs/firestore/data-model?hl=ko&quot;&gt;https://firebase.google.com/docs/firestore/data-model?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/22</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Firebase%EC%97%90-%EC%98%AC%EB%A6%B0-%ED%8C%8C%EC%9D%BC-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0#entry22comment</comments>
      <pubDate>Tue, 18 Oct 2022 23:43:48 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - Firebase Cloud Storage에 파일 올리기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Firebase-Cloud-Storage%EC%97%90-%ED%8C%8C%EC%9D%BC-%EC%98%AC%EB%A6%AC%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase에 이미지나 동영상 파일을 올리려면 어떻게 해야할까요? Firebase에서는 파일 저장용으로 Storage라는 서비스를 제공합니다. 이 서비스를 이용하기 위해서는 먼저 Firebase 콘솔에서 생성한 프로젝트에 Storage 버킷을 생성합니다. 그 다음 플러터 프로젝트에서 firebase_storage 플러그인을 추가해주고 이 플러그인에서 제공하는 FirebaseStorage 인스턴스를 만듭니다. 이 인스턴스를 통해 Storage 버킷에 올라갈 파일의 경로를 정하고, putFile() 메서드를 통해 파일을 Storage 버킷에 올리면 됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span data-token-index=&quot;0&quot; data-reactroot=&quot;&quot;&gt;Firebase 콘솔에서 Cloud Storage 버킷 만들기&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase Storage 버킷을 만드는 방법은 상당히 간단합니다. 먼저 Firebase 콘솔에서 Storage에 대해 &amp;lsquo;시작하기&amp;rsquo; 버튼 눌러주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DMmCY/btrOFkhCAnk/hopFT7LsBVWKKmv3cJgHQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DMmCY/btrOFkhCAnk/hopFT7LsBVWKKmv3cJgHQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DMmCY/btrOFkhCAnk/hopFT7LsBVWKKmv3cJgHQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDMmCY%2FbtrOFkhCAnk%2FhopFT7LsBVWKKmv3cJgHQ1%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;809&quot; height=&quot;311&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 규칙 설정은 테스트 모드에서 시작으로 설정합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qerV0/btrOCzngXGo/qnEcK1Ig8BK8aiuVNuNCd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qerV0/btrOCzngXGo/qnEcK1Ig8BK8aiuVNuNCd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qerV0/btrOCzngXGo/qnEcK1Ig8BK8aiuVNuNCd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqerV0%2FbtrOCzngXGo%2FqnEcK1Ig8BK8aiuVNuNCd1%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;802&quot; height=&quot;533&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cloud Storage에서 서울의 위치는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;asia-northeast3&lt;/span&gt;&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctqVLX/btrOEpQ0447/Tzui5bknLiwqAQg2YNzFEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctqVLX/btrOEpQ0447/Tzui5bknLiwqAQg2YNzFEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctqVLX/btrOEpQ0447/Tzui5bknLiwqAQg2YNzFEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctqVLX%2FbtrOEpQ0447%2FTzui5bknLiwqAQg2YNzFEk%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;800&quot; height=&quot;431&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;생성 후에는 Files 탭에서 생성된 Storage 버킷과 버킷 주소를 확인할 수 있습니다. Firebase의 Cloud Storage는 최대 5GB까지 무료로 저장할 수 있고, 하루 최대 1GB까지 무료로 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-15 오후 2.37.40.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clncsU/btrOGt6pFAh/KOzKBPFPe1b20nb3F0IZQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clncsU/btrOGt6pFAh/KOzKBPFPe1b20nb3F0IZQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clncsU/btrOGt6pFAh/KOzKBPFPe1b20nb3F0IZQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclncsU%2FbtrOGt6pFAh%2FKOzKBPFPe1b20nb3F0IZQK%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;1474&quot; height=&quot;422&quot; data-filename=&quot;스크린샷 2022-10-15 오후 2.37.40.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Cloud Storage 플러그인 추가하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 프로젝트에서 pubspec.yaml에 최신 버전의 Firebase Storage 플러그인을 추가해주고 IDE 상단에 뜨는 &amp;lsquo;Pub get&amp;rsquo;으로 라이브러리를 현재 플러터 프로젝트로 당겨옵니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;dependencies:&lt;br /&gt;&amp;nbsp; firebase_storage: ^10.3.11&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;플러터 프로젝트에서 코드 작성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image Picker를 통해 앨범에서 선택한 이미지를 Firebase Storage에 올리는 코드를 작성해보겠습니다. 앨범에서 선택한 이미지는 _image에 저장되어 있다고 가정합니다. (앨범에서 이미지를 선택하는 과정은 이전 글을 참조해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codeflow.tistory.com/entry/플러터Flutter-앨범-사진-가져오기-Image-Picker&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.10.15 - [Flutter] - 플러터(Flutter) - 앨범 사진 가져오기 (Image Picker)&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Storage 버킷에 접근할 때는 FirebaseStorage 인스턴스를 가리키는 레퍼런스를 통해 가리키게 됩니다. 이 경우 FirebaseStorage 참조는 버킷의 최상위 루트를 가리키고 있습니다. 여기에 트리 구조로 업로드할 폴더와 파일들을 추가하면 됩니다. 아래 예시에서는 post라는 폴더를 루트 밑에 child로 만들고, post 폴더에 올릴 파일 역시 post 폴더의 child로 이름을 지정해줍니다. 파일 이름은 현재 시각을 Timestamp로 설정했습니다. 마지막으로 이미지 레퍼런스의 putFile 메서드에 이미지 파일 객체를 파라미터로 넘겨주고 호출하면, Firebase Storage에 해당 이미지가 업로드 됩니다.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/9d9405d9d8be6b8c60de6d1e7284ce21.js&quot;&gt;&lt;/script&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Firebase 콘솔에서 업로드 된 이미지 확인하기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-15 오후 4.16.56.png&quot; data-origin-width=&quot;1477&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RGaeF/btrO0IbBTIt/d6upLA8PE0tSBIZR8eWZEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RGaeF/btrO0IbBTIt/d6upLA8PE0tSBIZR8eWZEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RGaeF/btrO0IbBTIt/d6upLA8PE0tSBIZR8eWZEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRGaeF%2FbtrO0IbBTIt%2Fd6upLA8PE0tSBIZR8eWZEK%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;1477&quot; height=&quot;426&quot; data-filename=&quot;스크린샷 2022-10-15 오후 4.16.56.png&quot; data-origin-width=&quot;1477&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Firebase 콘솔에서 Storage를 확인하면 샘플 코드를 통해 이미지가 올라간 걸 확인할 수 있습니다.  &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;a href=&quot;https://firebase.google.com/docs/storage/flutter/upload-files&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://firebase.google.com/docs/storage/flutter/upload-files&lt;/a&gt;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/21</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Firebase-Cloud-Storage%EC%97%90-%ED%8C%8C%EC%9D%BC-%EC%98%AC%EB%A6%AC%EA%B8%B0#entry21comment</comments>
      <pubDate>Tue, 18 Oct 2022 22:45:16 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - 앨범 사진 가져오기 (Image Picker)</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%95%A8%EB%B2%94-%EC%82%AC%EC%A7%84-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-Image-Picker</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터에서 앨범 사진을 불러올 때는 &lt;a href=&quot;https://pub.dev/packages/image_picker&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Image Picker&lt;/a&gt; 플러그인을 사용합니다. pub.dev에서 이 플러그인을 &quot;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a;&quot;&gt;A Flutter plugin for iOS and Android for picking images from the image library, and taking new pictures with the camera.&quot;라고 소개하고 있습니다. Image Picker 플러그인을 통해 앨범에서 사진을 선택하거나 카메라로 사진 촬영을 하는 기능을 모두 제공하고 있다고 하네요. 우리는 그중에서 앨범에서 사진을 선택하는 경우를 먼저 살펴봅시다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a;&quot;&gt;Image Picker 코드 구현&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a;&quot;&gt;먼저 pubspec.yaml 파일에 Image Picker 라이브러리를 의존성으로 추가해줍니다. 그 다음 IDE 메뉴에서 Pub get을 선택해 라이브러리를 실제 프로젝트로 받아옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8vKNJ/btrODPI2quz/MnPk8vNaOkC3e4MIGfplq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8vKNJ/btrODPI2quz/MnPk8vNaOkC3e4MIGfplq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8vKNJ/btrODPI2quz/MnPk8vNaOkC3e4MIGfplq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8vKNJ%2FbtrODPI2quz%2FMnPk8vNaOkC3e4MIGfplq0%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;987&quot; height=&quot;177&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image Picker를 코드에서 호출할 때는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;'package:image_picker/image_picker.dart'&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;;&lt;/span&gt; &lt;/b&gt;구문을 추가해 패키지를 불러옵니다. 이미지를 선택할 때 사용하는 함수는 ImagePicker 클래스의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;pickImage&lt;/span&gt;라는 메서드 입니다. 선언을 따라가 보면 아래와 같이 파라미터로 이미지 출처를 지정하는 ImageSource 타입의 source를 반드시 넣어주어야 하고, Future&amp;lt;XFile?&amp;gt;형 변수를 리턴합니다. 아래 세 줄의 코드만 있다면 앨범 사진 선택 기능을 구현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;import 'package:image_picker/image_picker.dart';&lt;br /&gt;final ImagePicker _picker = ImagePicker();&lt;br /&gt;final XFile? image = await _picker.pickImage(source: ImageSource.gallery);&lt;span style=&quot;background-color: #ffffff; color: #24292f;&quot;&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f;&quot;&gt; pickImage 메서드가 호출되면 Nullable한 XFile형 이미지 파일을 리턴하게 되는데, 메서드가 호출되는 즉시 리턴하지 않고 사용자가 앨범에서 이미지를 선택한 후에 해당 이미지를 리턴합니다. 따라서 비동기 처리를 지원하는 Future&amp;lt;T&amp;gt; 타입으로 리턴되고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rXzSE/btrOCcFNY1g/EJ8sv9pQcuNqxBLmywMdTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rXzSE/btrOCcFNY1g/EJ8sv9pQcuNqxBLmywMdTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rXzSE/btrOCcFNY1g/EJ8sv9pQcuNqxBLmywMdTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrXzSE%2FbtrOCcFNY1g%2FEJ8sv9pQcuNqxBLmywMdTK%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;773&quot; height=&quot;181&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pickImage() 메서드를 호출할 때도 호출하는 함수에서 async 키워드를 붙여서 비동기 함수임을 알려주고 있습니다. 이 함수 안에서 await로 pickImage() 메서드를 호출해, pickImage() 메서드가 실행 결과를 리턴할 때까지 대기하게 됩니다. 아래 예제는 image가 null이 아닐 때 이미지 경로를 내부 변수에 저장할 때 예시를 보여주고 있습니다.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/be765d1143510827a8fb1157eba9bfd3.js&quot;&gt;&lt;/script&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;iOS에서의 주의점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;pub.dev의 &lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://pub.dev/packages/image_picker&quot;&gt;Image Picker&lt;/a&gt;&lt;span&gt;&lt;span&gt; 라이브러리 설명에 따르면, iOS의 경우 앨범에 접근하기 위해 iOS 11 이상 버전에서 requestFullMetadata를 false로 설정하지 않는 한 &lt;span style=&quot;color: #4a4a4a;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;lt;project root&amp;gt;/ios/Runner/Info.plist&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 파일에서 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;NSPhotoLibraryUsageDescription&lt;/span&gt;&lt;/b&gt; 키를 명시적으로 넣어줘야 합니다. 간단하게 아래와 같이 넣어주면 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kW4AW/btrOC6q07kR/DIqMVf6eWX5o3h42X8q3mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kW4AW/btrOC6q07kR/DIqMVf6eWX5o3h42X8q3mK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kW4AW/btrOC6q07kR/DIqMVf6eWX5o3h42X8q3mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkW4AW%2FbtrOC6q07kR%2FDIqMVf6eWX5o3h42X8q3mK%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;682&quot; height=&quot;63&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>async</category>
      <category>Await</category>
      <category>Future</category>
      <category>Image Picker</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/20</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%95%A8%EB%B2%94-%EC%82%AC%EC%A7%84-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-Image-Picker#entry20comment</comments>
      <pubDate>Sat, 15 Oct 2022 09:01:32 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - 유저 프로파일 보여주기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EA%B5%AC%EA%B8%80-%EC%9C%A0%EC%A0%80-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;유저 프로파일 사용하기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-12 오후 11.09.55.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;1632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AU0j0/btrOqFnuyFO/Rm5iBgjOFB5JRSYKKaNDb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AU0j0/btrOqFnuyFO/Rm5iBgjOFB5JRSYKKaNDb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AU0j0/btrOqFnuyFO/Rm5iBgjOFB5JRSYKKaNDb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAU0j0%2FbtrOqFnuyFO%2FRm5iBgjOFB5JRSYKKaNDb1%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;300&quot; height=&quot;1632&quot; data-filename=&quot;스크린샷 2022-10-12 오후 11.09.55.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;1632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase를 이용해 구글 로그인을 하게 되면, Firebase 유저 정보를 이용해 로그인한 구글 계정의 유저 프로파일을 보여줄 수 있게 됩니다. 이전에는 dummy 텍스트와 이미지를 계정 정보로 사용했는데, 이번에는 구글 계정에서 사용 중인 계정 이미지와 이메일 주소, 계정 이름을 불러오도록 변경해보았습니다.&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;이때 핵심은 로그인 버튼 클릭 후 구글 계정으로 로그인 후 얻게 되는 U&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;ser&lt;/span&gt;&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클래스&amp;nbsp;&lt;/span&gt;변수의 정보를 활용하는 데 있습니다. 이 변수는&amp;nbsp; &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;User? user = await Authentication.signInWithGoogle(context: context); &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;앞선 Authentication 클래스의 signInWithGoogle 메서드 실행을 통해 얻게 됩니다.&amp;nbsp;&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;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Firebase에서 제공하는 이 User 클래스 변수를 통해,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 구글 로그인 계정의 이름을 표시할 때는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Text(user.displayName!)&lt;/span&gt;&lt;/b&gt;, &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이메일 주소를 표시할 때는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Text(user.email!),&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;계정 이미지를 표시할 때는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;NetworkImage(user.photoURL!)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&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;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;참고로 displayName!, email!, photoURL!과 같이 !가 붙는 이유는, User 클래스에서 이 메서드들이 모두 nullable 타입인 String?을 리턴하기 때문입니다. 예를 들어 displayName 메서드는 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;String? get displayName { return _delegate.displayName; }&lt;/span&gt;&lt;/b&gt;과 같은 형식을 취하고 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저 프로파일을 다른 페이지로 넘겨주고 싶을 땐?&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/646cc97b807433a60d66585d0a905528.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저 프로파일을 얻은 페이지가 아니라 다른 페이지로 이 정보를 넘겨주고 싶을 때는, 유저 프로파일을 넘겨받을 페이지 파일에서 firebase_auth 라이브러리를 import 한 다음, 페이지 위젯의 생성자에 타입이 User인 변수를 넘겨받아 내부 속성으로 사용하도록 설정하면 됩니다. 위 예제에서는 내부 속성 _user에 저장하고 있습니다. 만약 PageName 위젯에서 선언한 _user 속성을 _PageNameState 클래스와 같이 State 클래스에서 사용하고 싶다면, &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;widget._user&lt;/span&gt;&lt;/b&gt;와 같이 사용하면 됩니다. widget이 PageName이라는 위젯 타입 클래스를 가리키게 됩니다.&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/19</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EA%B5%AC%EA%B8%80-%EC%9C%A0%EC%A0%80-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0#entry19comment</comments>
      <pubDate>Fri, 14 Oct 2022 09:00:56 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - Google 로그인(sign in) 기능 구현하기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EA%B5%AC%EA%B8%80-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Firebase 콘솔에서 Authentication 설정하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 프로젝트 안드로이드 앱에서 구글 로그인 기능을 구현하려면, &lt;a href=&quot;https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Android-%EC%95%B1%EA%B3%BC-Firebase-%EC%97%B0%EB%8F%99&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Firebase와 플러터 프로젝트를 연동&lt;/a&gt;한 후에, Firebase에서 Sign-in method에 Google을 추가해줍니다. Sign-in method 메뉴는 Firebase 프로젝트에 진입해서 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;빌드&amp;gt; Authentication&lt;/span&gt;으로 들어가면 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dibsO1/btrOfbL7z3g/6dgU39wADJKgms3H7OhPQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dibsO1/btrOfbL7z3g/6dgU39wADJKgms3H7OhPQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dibsO1/btrOfbL7z3g/6dgU39wADJKgms3H7OhPQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdibsO1%2FbtrOfbL7z3g%2F6dgU39wADJKgms3H7OhPQ0%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;1379&quot; height=&quot;687&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 프로젝트 지원 이메일만 작성하면 구글 로그인 기능을 사용할 수 있게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWdUVn/btrN9kQBDpl/2QnGpZrqrVzN7VJZnjFE0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWdUVn/btrN9kQBDpl/2QnGpZrqrVzN7VJZnjFE0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWdUVn/btrN9kQBDpl/2QnGpZrqrVzN7VJZnjFE0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWdUVn%2FbtrN9kQBDpl%2F2QnGpZrqrVzN7VJZnjFE0k%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;1010&quot; height=&quot;206&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;의존성 및 구글 로고 이미지 추가하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase 설정을 마친 후에는 플러터 프로젝트 pubspec.yaml 파일에서 Firebase와 구글 sign in 라이브러리를 추가해줍니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;dependencies:&lt;br /&gt;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp; google_sign_in: ^5.4.2&lt;br /&gt;&amp;nbsp; firebase_core : ^1.24.0&lt;br /&gt;&amp;nbsp; firebase_auth: ^3.11.2&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 다음 Pub get을 클릭해서 라이브러리를 받아옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nMR7S/btrN784aV8E/qJOiOvcw9Bu0QedFb71YGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nMR7S/btrN784aV8E/qJOiOvcw9Bu0QedFb71YGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nMR7S/btrN784aV8E/qJOiOvcw9Bu0QedFb71YGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnMR7S%2FbtrN784aV8E%2FqJOiOvcw9Bu0QedFb71YGK%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;1386&quot; height=&quot;572&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 진행 과정 살펴보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.codemagic.io/firebase-authentication-google-sign-in-using-flutter/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;codemagic&lt;/a&gt;에 소개된 구글 로그인/로그아웃, 유저 프로파일 표시 예제에서 로그인 기능만을 가져와 구글 로그인 기능 구현에 사용해보겠습니다. 전체적으로 다음과 같이 총 네 단계를 거치게 됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main.dart에서 LoginPage 위젯 호출&lt;/li&gt;
&lt;li&gt;LoginPage 위젯에서 FutureBuilder 위젯을 이용해 Firebase를 초기화하고 Firebase와 연결되면 SignInButton 위젯 호출&lt;/li&gt;
&lt;li&gt;SignInButton 위젯에서 구글 로그인 버튼을 그려주고 onPressed 속성을 통해 버튼 클릭 시에 Authentication 클래스의 정적 메서드인 signInWithGoogle()을 호출&lt;/li&gt;
&lt;li&gt;Authentication 클래스에서는 initializeFirebase() 메서드를 통해 Firebase 초기화를, signInWithGoogle() 메서드를 통해 실제 구글 로그인 과정 진행&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;authentication.dart 구현하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글 로그인 기능에서 가장 핵심이 되는 authentication.dart 파일을 살펴보겠습니다. &lt;span&gt;Authentication 클래스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;siginInWithGoogle 정적 메서드에서는 구글 계정 정보를 입력받아 Sign In을 시도하고, 성공 시에는 Firebase 인증 절차를 마무리하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Authentication 클래스의 initializeFirebase 정적 메서드는 Firebase 앱을 초기화 한 후, 실제 구글 로그인 동작이 일어날 때까지 대기했다가 현재 유저 정보를 가져옵니다. 유저 정보를 가져왔다면 TabPage에 해당 유저 정보를 넘겨주게 됩니다. 코드는 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/bgtestlab/d2d7c3f4f026cf9cf0de40dcf9836906.js&quot;&gt;&lt;/script&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실행 결과&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Authentication 클래스를 이용하면 아래와 같이 구글 로그인 기능을 이용해 구글 로그인 버튼을 만들고, 버튼을 클릭하면 계정 선택 화면이 나오게 됩니다. 계정 선택을 선택하고 구글 로그인에 성공하면 메인 화면으로 넘어가는 구조를 작성할 수 있게 됩니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;641&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caDm9z/btrOqMfxK2Z/MM51WIm4le23kQ7Ua7qkDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caDm9z/btrOqMfxK2Z/MM51WIm4le23kQ7Ua7qkDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caDm9z/btrOqMfxK2Z/MM51WIm4le23kQ7Ua7qkDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaDm9z%2FbtrOqMfxK2Z%2FMM51WIm4le23kQ7Ua7qkDK%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;767&quot; height=&quot;641&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;641&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/18</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EA%B5%AC%EA%B8%80-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0#entry18comment</comments>
      <pubDate>Thu, 13 Oct 2022 09:00:29 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - Android 앱과 Firebase 연동</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Android-%EC%95%B1%EA%B3%BC-Firebase-%EC%97%B0%EB%8F%99</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Firebase 프로젝트 생성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 프로젝트에서 Android 앱과 Firebase를 연동할 때, 가장 먼저 해야 할 일은 Firebase 프로젝트를 생성하는 일입니다.&amp;nbsp; &lt;a href=&quot;https://console.firebase.google.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Firebase 콘솔 사이트&lt;/a&gt;에서 '프로젝트 추가' 영역을 클릭해 프로젝트 만들기 화면으로 들어갑니다. 아래 화면에서는 프로젝트 만들기 단계를 통해 이미 만들어진 'instagram-clone' 프로젝트를 보여주고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJFQJx/btrN5FujVF0/EkJuTEOlUOD1dKuhmJhbrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJFQJx/btrN5FujVF0/EkJuTEOlUOD1dKuhmJhbrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJFQJx/btrN5FujVF0/EkJuTEOlUOD1dKuhmJhbrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJFQJx%2FbtrN5FujVF0%2FEkJuTEOlUOD1dKuhmJhbrK%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;793&quot; height=&quot;305&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 이름을 지정한 뒤 두 번째 단계에서는 Google 애널리틱스를 구성하게 됩니다. 기존 계정이 있으면 선택하면 되고, 없다면 '새 계정 만들기'를 선택하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baghdE/btrN9r9WANI/zbI7RQglHKqKf2zxBnI5ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baghdE/btrN9r9WANI/zbI7RQglHKqKf2zxBnI5ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baghdE/btrN9r9WANI/zbI7RQglHKqKf2zxBnI5ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaghdE%2FbtrN9r9WANI%2FzbI7RQglHKqKf2zxBnI5ok%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;801&quot; height=&quot;381&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Firebase에서 Android 앱 등록하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 앱 등록하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 생성을 마쳤다면 생성한 프로젝트로 진입한 뒤 Android 버튼을 클릭해 앱 등록 화면에 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1748&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9XHSq/btrN5wxtJUW/ibk3KHWjETPy075Z0uL2U0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9XHSq/btrN5wxtJUW/ibk3KHWjETPy075Z0uL2U0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9XHSq/btrN5wxtJUW/ibk3KHWjETPy075Z0uL2U0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9XHSq%2FbtrN5wxtJUW%2Fibk3KHWjETPy075Z0uL2U0%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;1748&quot; height=&quot;558&quot; data-origin-width=&quot;1748&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 등록 시에 Android 패키지 이름과 디버그 서명 인증서의 SHA-1 해시값을 확인해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4BR7y/btrN5xJQvNr/mtkVpO1VzW1mNX3QSOFL91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4BR7y/btrN5xJQvNr/mtkVpO1VzW1mNX3QSOFL91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4BR7y/btrN5xJQvNr/mtkVpO1VzW1mNX3QSOFL91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4BR7y%2FbtrN5xJQvNr%2FmtkVpO1VzW1mNX3QSOFL91%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;860&quot; height=&quot;465&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 패키지 이름의 경우, 확인할 수 있는 여러 가지 방법 중 하나의 방법으로 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;project_folder/android/app/src/debug/AndroidManifest.xml &lt;/b&gt;&lt;/span&gt;파일에서 패키지명을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDJDb6/btrN6nz8y88/vTZHwIUGUWB2aasxrkmQkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDJDb6/btrN6nz8y88/vTZHwIUGUWB2aasxrkmQkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDJDb6/btrN6nz8y88/vTZHwIUGUWB2aasxrkmQkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDJDb6%2FbtrN6nz8y88%2FvTZHwIUGUWB2aasxrkmQkk%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;2004&quot; height=&quot;340&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 디버그 서명 인증서 SHA-1의 경우, 아래 안내 사항에서 '동적 링크, Google 로그인, 전화번호를 지원'할 때 필요하다고 되어 있습니다. 이 기능들을 쓰기 위해서는 물음표 아이콘을 클릭해 &lt;a href=&quot;https://developers.google.com/android/guides/client-auth&quot;&gt;클라이언트 인증 개발자 가이드&lt;/a&gt;에서 안내하는대로 터미널에서 디버그 서명 인증서의 SHA-1 fingerprint를 확인해 넣어주면 됩니다.&amp;nbsp; (만약 keytool 커맨드를 입력할 때 에러가 발생한다면, 자바(JDK) 설치나 설정에 문제가 있는 경우이기 때문에 &lt;a href=&quot;https://codeflow.tistory.com/entry/keytool-에러-해결하기-JDK-설치-openjdk&quot;&gt;2022.10.11 - [Troubleshoot] - keytool 에러 해결하기 - JDK 설치 (openjdk)&lt;/a&gt;를 참고해 문제를 해결해보세요.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 구성 파일 다운로드 후 추가하기&lt;/b&gt;&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-origin-width=&quot;923&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nITsU/btrN9kCTBel/ew5rSsb0xP9cdO0gK0Yp41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nITsU/btrN9kCTBel/ew5rSsb0xP9cdO0gK0Yp41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nITsU/btrN9kCTBel/ew5rSsb0xP9cdO0gK0Yp41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnITsU%2FbtrN9kCTBel%2Few5rSsb0xP9cdO0gK0Yp41%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;923&quot; height=&quot;455&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 등록을 마친 후에 Firebase SDK의 구글 서비스 설정값인 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;google-services.json&lt;/span&gt;&lt;/b&gt; 파일을 다운로드해 플러터 프로젝트에 넣어줍니다. 플러터 프로젝트에서의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;'모듈(앱 수준) 루트 디렉토리'&lt;/span&gt;는 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;project_folder/android/app&lt;/b&gt;&lt;/span&gt;이기 때문에, 여기에&lt;span style=&quot;color: #000000;&quot;&gt; google-services.json &lt;/span&gt;파일을 넣어주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1650&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGbczl/btrOfbrL9Yj/sNpc3bYUFgDefoW76JMg5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGbczl/btrOfbrL9Yj/sNpc3bYUFgDefoW76JMg5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGbczl/btrOfbrL9Yj/sNpc3bYUFgDefoW76JMg5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGbczl%2FbtrOfbrL9Yj%2FsNpc3bYUFgDefoW76JMg5k%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;1650&quot; height=&quot;496&quot; data-origin-width=&quot;1650&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Firebase SDK 추가하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 마지막 단계인 &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;세 번째 단계에서는 루트 수준과 모듈 수준의 build.gradle 파일 각각에서 안내사항대로 의존성과 플러그인을 추가해줍니다. 먼저 루트 수준 gradle 파일인 &lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;project_folder/android/build.gradle &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일에서 buildscript의 dependencies에 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;classpath&amp;nbsp;'com.google.gms:google-services:4.3.14'&lt;/span&gt;&lt;/b&gt; 등으로 google service 플러그인을 추가합니다. (google-services의 버전이 최신 버전보다 낮다면 최신 버전을 자동으로 추천해주기 때문에, 추천하는 최신 버전을 입력하면 됩니다.)&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1816&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PyP09/btrOcgmSwrn/mSNgX2Ffg3632Xhi2mSrPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PyP09/btrOcgmSwrn/mSNgX2Ffg3632Xhi2mSrPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PyP09/btrOcgmSwrn/mSNgX2Ffg3632Xhi2mSrPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPyP09%2FbtrOcgmSwrn%2FmSNgX2Ffg3632Xhi2mSrPk%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;1816&quot; height=&quot;590&quot; data-origin-width=&quot;1816&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;그런 다음 앱 수준 gradle 파일인 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;project_folder/android/app/build.gradle &lt;/b&gt;&lt;/span&gt;파일에서 다음 이미지와 같이&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;apply&amp;nbsp;plugin:&amp;nbsp;'com.google.gms.google-services'&lt;/span&gt;&lt;/b&gt;를 입력해주고, dependencies에 의존성을 설정해 연동을 마무리해줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1806&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4Au5K/btrOeR7Zrl9/iVwywkMDVuH2Kzq2ECbok0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4Au5K/btrOeR7Zrl9/iVwywkMDVuH2Kzq2ECbok0/img.png&quot; data-alt=&quot;Google Services 플러그인 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4Au5K/btrOeR7Zrl9/iVwywkMDVuH2Kzq2ECbok0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4Au5K%2FbtrOeR7Zrl9%2FiVwywkMDVuH2Kzq2ECbok0%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;1806&quot; height=&quot;314&quot; data-origin-width=&quot;1806&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Google Services 플러그인 적용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/03ICb/btrN5FOKrzH/18uPW88wIldRbykltALhWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/03ICb/btrN5FOKrzH/18uPW88wIldRbykltALhWk/img.png&quot; data-alt=&quot;Firebase Analytics 의존성 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/03ICb/btrN5FOKrzH/18uPW88wIldRbykltALhWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F03ICb%2FbtrN5FOKrzH%2F18uPW88wIldRbykltALhWk%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;1910&quot; height=&quot;696&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Firebase Analytics 의존성 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안드로이드 앱 빌드 시 발생하는 Gradle error와 warning 제거하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;build.gradle 파일에서 SDK 버전 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연동 설정 직후 앱을 다시 빌드해 실행시킬 때 'uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library'와 같은 에러가 발생한다면, 플러터의 SDK 버전을 다시 설정해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Launching lib/main.dart on sdk gphone64 arm64 in debug mode...&lt;br /&gt;Running&amp;nbsp;Gradle&amp;nbsp;task&amp;nbsp;'assembleDebug'...&lt;br /&gt;/Users/codeflow/StudioProjects/insta_clone/android/app/src/debug/AndroidManifest.xml&amp;nbsp;Error:&lt;br /&gt;uses-sdk:minSdkVersion&amp;nbsp;16&amp;nbsp;cannot&amp;nbsp;be&amp;nbsp;smaller&amp;nbsp;than&amp;nbsp;version&amp;nbsp;19&amp;nbsp;declared&amp;nbsp;in&amp;nbsp;library&amp;nbsp;[com.google.firebase:firebase-analytics-ktx:21.1.1]&amp;nbsp;/Users/codeflow/.gradle/caches/transforms-3/bc0ed583922b0396f7d7b6fac4079f02/transformed/jetified-firebase-analytics-ktx-21.1.1/AndroidManifest.xml&amp;nbsp;as&amp;nbsp;the&amp;nbsp;library&amp;nbsp;might&amp;nbsp;be&amp;nbsp;using&amp;nbsp;APIs&amp;nbsp;not&amp;nbsp;available&amp;nbsp;in&amp;nbsp;16&lt;br /&gt;Suggestion:&amp;nbsp;use&amp;nbsp;a&amp;nbsp;compatible&amp;nbsp;library&amp;nbsp;with&amp;nbsp;a&amp;nbsp;minSdk&amp;nbsp;of&amp;nbsp;at&amp;nbsp;most&amp;nbsp;16,&lt;br /&gt;or&amp;nbsp;increase&amp;nbsp;this&amp;nbsp;project's&amp;nbsp;minSdk&amp;nbsp;version&amp;nbsp;to&amp;nbsp;at&amp;nbsp;least&amp;nbsp;19,&lt;br /&gt;or&amp;nbsp;use&amp;nbsp;tools:overrideLibrary=&quot;com.google.firebase.analytics.ktx&quot;&amp;nbsp;to&amp;nbsp;force&amp;nbsp;usage&amp;nbsp;(may&amp;nbsp;lead&amp;nbsp;to&amp;nbsp;runtime&amp;nbsp;failures)&lt;br /&gt;&lt;br /&gt;FAILURE:&amp;nbsp;Build&amp;nbsp;failed&amp;nbsp;with&amp;nbsp;an&amp;nbsp;exception.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 내용을 들여다보니 Firebase Aanaytics 라이브러리를 쓰기 위해 최소한 SDK 버전 19을 써야하는데 16을 써서 문제가 되나 봅니다. &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;project_folder/android/app/build.gradle &lt;/b&gt;&lt;/span&gt;파일의 defaultConfig 단락을 보니 minSdkVersion과 targetSdkVersion이 플러터가 생성해준 기본값을 쓰고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2206&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ejS0yV/btrOe98yEBR/ccXVjC7f3tUc3rKYcKZ6T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ejS0yV/btrOe98yEBR/ccXVjC7f3tUc3rKYcKZ6T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ejS0yV/btrOe98yEBR/ccXVjC7f3tUc3rKYcKZ6T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FejS0yV%2FbtrOe98yEBR%2FccXVjC7f3tUc3rKYcKZ6T0%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;2206&quot; height=&quot;536&quot; data-origin-width=&quot;2206&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;minSdkVersion이 19보다 커야하는데, 19 버전은 dex 설정을 따로 해줘야하므로 dex 설정을 자동으로 해주는 최소 버전인 21로 변경해보겠습니다. targetSDKVersion도 현재 사용중인 에뮬레이터 버전에 맞춰 33으로 변경했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WXiPu/btrN5jLYb5O/cz2QJmsRnL916lK7dXkKkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WXiPu/btrN5jLYb5O/cz2QJmsRnL916lK7dXkKkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WXiPu/btrN5jLYb5O/cz2QJmsRnL916lK7dXkKkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWXiPu%2FbtrN5jLYb5O%2Fcz2QJmsRnL916lK7dXkKkk%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;1978&quot; height=&quot;490&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;490&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;b&gt;Project Structure에서 Android SDK 버전 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 Android SDK 버전을 변경하고 나니 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;Properties()&lt;/b&gt;&lt;/span&gt;와&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt; GradleException()&lt;/b&gt;&lt;/span&gt;을 찾을 수 없는 에러가 발생했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2126&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAj7ne/btrOgR7DDRQ/IaKlJKsH5TB6nuPlrr1KhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAj7ne/btrOgR7DDRQ/IaKlJKsH5TB6nuPlrr1KhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAj7ne/btrOgR7DDRQ/IaKlJKsH5TB6nuPlrr1KhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAj7ne%2FbtrOgR7DDRQ%2FIaKlJKsH5TB6nuPlrr1KhK%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;2126&quot; height=&quot;600&quot; data-origin-width=&quot;2126&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 해결하기 위해 Android Studio의 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;File&amp;gt; Project Structure&lt;/span&gt;&lt;/b&gt;를 클릭해 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg6OGm/btrN9qDk3Fw/bkZzsLfyjR70lg5lCM0Ww0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg6OGm/btrN9qDk3Fw/bkZzsLfyjR70lg5lCM0Ww0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg6OGm/btrN9qDk3Fw/bkZzsLfyjR70lg5lCM0Ww0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg6OGm%2FbtrN9qDk3Fw%2FbkZzsLfyjR70lg5lCM0Ww0%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;1764&quot; height=&quot;450&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Project Settings&amp;gt; Project&lt;/span&gt;&lt;/b&gt;를 확인해보니 Project SDK가 설정되어 있지 않습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1828&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jh7SX/btrN9q4oGWa/S60b2kZaVGROznxeBRkOI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jh7SX/btrN9q4oGWa/S60b2kZaVGROznxeBRkOI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jh7SX/btrN9q4oGWa/S60b2kZaVGROznxeBRkOI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJh7SX%2FbtrN9q4oGWa%2FS60b2kZaVGROznxeBRkOI0%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;1828&quot; height=&quot;346&quot; data-origin-width=&quot;1828&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Project SDK로 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'Android Studio default JDK'&lt;/span&gt;&lt;/b&gt;를 설정해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nS4ON/btrN8BE1S5H/6mfYCkggEcCfcyBthlj7i1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nS4ON/btrN8BE1S5H/6mfYCkggEcCfcyBthlj7i1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nS4ON/btrN8BE1S5H/6mfYCkggEcCfcyBthlj7i1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnS4ON%2FbtrN8BE1S5H%2F6mfYCkggEcCfcyBthlj7i1%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;1652&quot; height=&quot;354&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Project Settings&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Modules&amp;gt; project_folder_android&lt;/span&gt;&lt;/b&gt;를 클릭해보니 역시 Module SDK가 No SDK로 설정되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx0xsh/btrOcidTeCs/ICHK91AJuTdsmFyKDuo9m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx0xsh/btrOcidTeCs/ICHK91AJuTdsmFyKDuo9m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx0xsh/btrOcidTeCs/ICHK91AJuTdsmFyKDuo9m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx0xsh%2FbtrOcidTeCs%2FICHK91AJuTdsmFyKDuo9m1%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;2050&quot; height=&quot;302&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 Module SDK를 &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'Android Studio default JDK'&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로&lt;/span&gt; 설정해주면, Properties() 에러가 사라집니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF8iqu/btrN66yyOXN/2fVfCdUwvL0Q4ph1Ncmya0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF8iqu/btrN66yyOXN/2fVfCdUwvL0Q4ph1Ncmya0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF8iqu/btrN66yyOXN/2fVfCdUwvL0Q4ph1Ncmya0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF8iqu%2FbtrN66yyOXN%2F2fVfCdUwvL0Q4ph1Ncmya0%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;2036&quot; height=&quot;542&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;GradleException&lt;/span&gt;&lt;/b&gt;의 경우, API 업데이트에 따라 이름이 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;FileNotFoundException&lt;/span&gt;&lt;/b&gt;으로 변경되었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beTT7A/btrN783TzCm/tbFAdgsFzMGmAnLRk7jn41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beTT7A/btrN783TzCm/tbFAdgsFzMGmAnLRk7jn41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beTT7A/btrN783TzCm/tbFAdgsFzMGmAnLRk7jn41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeTT7A%2FbtrN783TzCm%2FtbFAdgsFzMGmAnLRk7jn41%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;1492&quot; height=&quot;150&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Exception 이름만 변경해주면 바로 에러가 사라집니다.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2170&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XMSZK/btrOfaGouE2/6SGVC2wdKiJUPlFbRVZYu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XMSZK/btrOfaGouE2/6SGVC2wdKiJUPlFbRVZYu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XMSZK/btrOfaGouE2/6SGVC2wdKiJUPlFbRVZYu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXMSZK%2FbtrOfaGouE2%2F6SGVC2wdKiJUPlFbRVZYu1%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;2170&quot; height=&quot;300&quot; data-origin-width=&quot;2170&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/17</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Android-%EC%95%B1%EA%B3%BC-Firebase-%EC%97%B0%EB%8F%99#entry17comment</comments>
      <pubDate>Wed, 12 Oct 2022 09:00:18 +0900</pubDate>
    </item>
    <item>
      <title>keytool 에러 해결하기 - JDK 설치 (openjdk)</title>
      <link>https://codeflow.tistory.com/entry/keytool-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0-JDK-%EC%84%A4%EC%B9%98-openjdk</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TL;DR&lt;/b&gt; keytool로 인증서 키 값을 생성하려고 할 때 에러가 난다면, JDK 설치 여부를 확인하고 없다면 설치해주자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Keytool 에러&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase에서 Android 앱을 등록할 때 디버그 인증서의 SHA-1 해시값이 필요한 경우가 있습니다. 이때 안내되는 &lt;a href=&quot;https://developers.google.com/android/guides/client-auth&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;클라이언트 인증에 대한 구글 개발자 페이지&lt;/a&gt;를 읽어보니 인증서 SHA-1 fingerprint를 얻기 위해선 Java에서 제공하는 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;keytool&lt;/b&gt;&lt;/span&gt; 유틸리티를 실행하면 된다고 합니다.&amp;nbsp;확인한 keytool 생성 커맨드를 그대로 터미널에 입력해주었더니 &lt;i&gt;&quot;The&amp;nbsp;operation&amp;nbsp;couldn&amp;rsquo;t&amp;nbsp;be&amp;nbsp;completed.&amp;nbsp;Unable&amp;nbsp;to&amp;nbsp;locate&amp;nbsp;a&amp;nbsp;Java&amp;nbsp;Runtime.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Please&amp;nbsp;visit&amp;nbsp;http://www.java.com for information on installing Java.&quot; &lt;/i&gt;라는 에러 메시지가 뜹니다. 에러 메시지 요청사항대로 자바 런타임 환경을 이용하기 위해 JDK를 설치해 줍시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-09 오후 10.54.10.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XOFeb/btrN8A0bzqa/kMnZbVl4nANYAO5IEXpJIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XOFeb/btrN8A0bzqa/kMnZbVl4nANYAO5IEXpJIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XOFeb/btrN8A0bzqa/kMnZbVl4nANYAO5IEXpJIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXOFeb%2FbtrN8A0bzqa%2FkMnZbVl4nANYAO5IEXpJIK%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;2004&quot; height=&quot;512&quot; data-filename=&quot;스크린샷 2022-10-09 오후 10.54.10.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Mac에서 openjdk 설치하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥OS에서 JDK를 설치할 때 가장 간편한 방법은 &lt;a href=&quot;https://brew.sh/index_ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;홈브루(Homebrew)&lt;/a&gt;를 통해 OpenJDK를 설치해주는 방법입니다. 홈브루가 설치되어 있지 않다면 먼저 설치해 준 뒤, 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;brew install openjdk&lt;/span&gt;&lt;/b&gt; 커맨드를 입력해 OpenJDK를 설치합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.56.12.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5zkgf/btrN5agPBuv/bZAqdFhw4nRKph03E7MP40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5zkgf/btrN5agPBuv/bZAqdFhw4nRKph03E7MP40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5zkgf/btrN5agPBuv/bZAqdFhw4nRKph03E7MP40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5zkgf%2FbtrN5agPBuv%2FbZAqdFhw4nRKph03E7MP40%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;2004&quot; height=&quot;692&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.56.12.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 다 되면, openjdk를 PATH에 추가할 수 있게 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;echo 'export PATH=&quot;/opt/homebrew/opt/openjdk/bin:$PATH&quot;' &amp;gt;&amp;gt; ~/.zshrc&lt;/span&gt;&lt;/b&gt; 커맨드를 실행하라는 안내가 나옵니다. 저는 환경 변수 설정을 .zprofile에서 하고 있기 때문에 PATH 설정 파일을 .zprofile로 바꿔주었습니다. (&lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;echo 'export PATH=&quot;/opt/homebrew/opt/openjdk/bin:$PATH&quot;' &amp;gt;&amp;gt; ~/.zprofile&lt;/span&gt;&lt;/b&gt;) 그 다음 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;source ~/.zprofile&lt;/span&gt;&lt;/b&gt; 커맨드로 설정을 적용한 뒤 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;java --version&lt;/span&gt;&lt;/b&gt;으로 확인해보니 java가 잘 설치되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.32.36.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;944&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0KfhW/btrOdidk77M/CYAQAalTPL1j0P0ZVPj8U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0KfhW/btrOdidk77M/CYAQAalTPL1j0P0ZVPj8U1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0KfhW/btrOdidk77M/CYAQAalTPL1j0P0ZVPj8U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0KfhW%2FbtrOdidk77M%2FCYAQAalTPL1j0P0ZVPj8U1%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;2004&quot; height=&quot;944&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.32.36.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;944&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 다시 원래 시도했던 keytool 커맨드인 keytool -list -v \ -alias androiddebugkey -keystore ~/.android/debug.keystore를 입력하면 키 저장소 비밀번호를 입력하라는 메시지가 뜹니다. 구글 개발자 페이지 안내사항대로 android를 입력했더니 원하던 fingerprint가 출력됩니다!  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.42.09.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVVeu6/btrOc9nenEc/KSXycyrw3JBqJMrKdHvj11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVVeu6/btrOc9nenEc/KSXycyrw3JBqJMrKdHvj11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVVeu6/btrOc9nenEc/KSXycyrw3JBqJMrKdHvj11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVVeu6%2FbtrOc9nenEc%2FKSXycyrw3JBqJMrKdHvj11%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;2004&quot; height=&quot;1160&quot; data-filename=&quot;스크린샷 2022-10-09 오후 9.42.09.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;윈도우용 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우의 경우도 순서는 동일합니다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;자바 설치 여부 확인 -&amp;gt;&amp;nbsp; 미설치시 JDK 설치 -&amp;gt; JDK 환경 변수 설정 -&amp;gt; keytool로 debug 인증서 SHA-1 해시값 얻기&lt;/span&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;&lt;b&gt;자바 설치 여부 확인 후 JDK 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 설치 여부는 명령 프롬프트에서 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;java -version&lt;/b&gt;&lt;/span&gt;을 쳐서 버전 정보가 뜨는지 확인해보면 됩니다. (명령 프롬프트는&lt;span style=&quot;color: #666666;&quot;&gt; &lt;b&gt;Windows + r &lt;/b&gt;&lt;/span&gt;키를 입력해 나오는 실행창에 cmd를 쳐서 진입할 수 있습니다.) 버전 정보가 나오지 않는다면, &lt;a href=&quot;https://docs.oracle.com/en/java/javase/16/install/installation-jdk-microsoft-windows-platforms.html#GUID-A7E27B90-A28D-4237-9383-A58B416071CA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;오라클 JDK 윈도우 설치 페이지&lt;/a&gt;에서 JDK 최신 버전을 다운로드 받고 설치하면 됩니다. (여러 버전 중 고르기 어려울 때는 LTS가 붙은 최신 버전을 선택하면 됩니다. LTS는 Long Term Support 약자로 정식 버전을 의미한다고 생각해주세요.) 설치할 때 설정한 JDK 경로를 환경 변수 설정에 사용합니다.&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;JDK 환경 변수 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JDK를 설치 경로 밖에서도 사용하기 위해 환경 변수에 등록해 줍니다. 일반적으로 JDK 설치 경로를 변수로 잡고 재사용하기 위해 JAVA_HOME이라는 변수를 새로 만들고 값으로 JDK 설치 경로를 넣어줍니다. JDK 설치 시 경로를 수정하지 않았다면 보통 &lt;b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;C:\Program Files\Java\jdk[버전명] &lt;/span&gt;&lt;/b&gt;경로에 설치됩니다. JDK 설치 경로를 확인하고 싶다면 명령 프롬프트에서 C 드라이브 기준으로 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;where /R C:\ javac.exe&lt;/b&gt;&lt;/span&gt;이라고 검색해보면 됩니다. 이렇게 확인한 경로를 JAVA_HOME 변수가 값에 넣어준 뒤 Path 변수를 편집해 최상단에 &lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;%JAVA_HOME%₩bin&lt;/b&gt;&lt;/span&gt;을 넣어줍니다. 명령 프롬프트에서 다시&amp;nbsp;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;java -version&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;b&gt;Keytool로 Debug 인증서 SHA-1 해시값 얻기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;keytool이 잘 실행되는 상태이기 때문에 keytool 커맨드로 SHA-1 해시값을 얻을 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;keytool -list -v \ -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore&lt;/blockquote&gt;</description>
      <category>ProTips</category>
      <category>FIrebase Error</category>
      <category>keytool error</category>
      <category>keytool 에러</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/16</guid>
      <comments>https://codeflow.tistory.com/entry/keytool-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0-JDK-%EC%84%A4%EC%B9%98-openjdk#entry16comment</comments>
      <pubDate>Tue, 11 Oct 2022 09:00:47 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - 코드 작성이 쉬워지는 IDE 단축키 알아보기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%9D%B4-%EC%89%AC%EC%9B%8C%EC%A7%80%EB%8A%94-IDE-%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 개발을 위해 Android Studio와 같은 IDE 툴을 쓸 때 가장 자주 사용하는 세 가지 단축키를 소개합니다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Stateless 혹은 Stateful 위젯에 대한 boilerplate 코드를 만들 때, 특정 위젯을 다른 위젯으로 감싸거나 혹은 없앨 때, 줄 간격을 맞출 때&lt;/span&gt; 사용하는 단축키 각각이 무엇인지 예제와 함께 알아보겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Stateless Widget과 Stateful Widget 을 만드는 단축키&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLSZru/btrN4aaai8y/807W4F2RXtUZ0GmqBGErkk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLSZru/btrN4aaai8y/807W4F2RXtUZ0GmqBGErkk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLSZru/btrN4aaai8y/807W4F2RXtUZ0GmqBGErkk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bLSZru/btrN4aaai8y/807W4F2RXtUZ0GmqBGErkk/img.gif&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;600&quot; height=&quot;190&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stateless 위젯에 대한 boilerplate 코드를 만들 때는 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;stless + tab&lt;/span&gt;&lt;/b&gt; 키를 사용합니다. 반대로 Stateful 위젯의 경우에는 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;stful + tab&lt;/b&gt;&lt;/span&gt; 키를 사용해서 만들어 줍니다. 그런 다음 비어있는 class 칸에 이름을 넣어주면 바로 아래에 있는 Key에도 동일하게 적용이 됩니다. 플러터는 새로운 페이지를 만들 때 반드시 Stateless나 Stateful 위젯 중 하나를 상속받아야 하기 때문에, Stateless/Stateful 위젯을 만드는 단축키는 반드시 알아두는 게 좋습니다. &lt;span&gt;Stateless과 Stateful 위젯이 서로 어떤 차이가 있는지 궁금하다면 아래 글을 참고해주세요.  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codeflow.tistory.com/entry/플러터-데모-앱-살펴보기-2-Widget과-외부-패키지-사용법-스크롤-기능&quot;&gt;2022.10.05 - [기본 코딩] - Flutter 데모 앱 살펴보기 2 - Widget과 외부 패키지 사용법, 스크롤 기능&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;특정 Widget으로 감싸거나 없앨 때 쓰는 단축키&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-08 오후 6.38.22.png&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0CfA5/btrN3C52JMM/j37NJEUlnuPw9UStSplGx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0CfA5/btrN3C52JMM/j37NJEUlnuPw9UStSplGx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0CfA5/btrN3C52JMM/j37NJEUlnuPw9UStSplGx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0CfA5%2FbtrN3C52JMM%2Fj37NJEUlnuPw9UStSplGx0%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;1358&quot; height=&quot;552&quot; data-filename=&quot;스크린샷 2022-10-08 오후 6.38.22.png&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;플러터에서는 화면에 보이는 텍스트와 이미지 간격을 조절하다가 Padding, Center, Column, Row 등으로 특정 위젯 혹은 특정 영역을 전부 감싸야할 때가 있습니다. 반대로 적용한 위젯을 제거해야할 경우도 있는데요, 이럴 때 쓰는 단축키가 맥에서는&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;option ⌥&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;+ return &lt;span style=&quot;background-color: #ffffff;&quot;&gt;↩ &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이고,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;윈도우는 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Alt + Enter &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입니다. 화면에 보이는 모든 요소가 위젯으로 이루어진 플러터에서는 손으로 위젯을 추가하거나 뺄 경우 닫는 괄호를 빠뜨리거나 들여쓰기가 안 맞는 등 실수할 가능성이 높은데 단축키를 쓰면 훨씬 수월하게 작업할 수 있습니다!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&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;b&gt;특정 Widget에 대해 다른 Widget으로 감싸거나, 부모 Widget을 제거할 때&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker (1).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/17ylq/btrN39vACwU/dk1t3kkKTyyEHyFsMPY3nK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/17ylq/btrN39vACwU/dk1t3kkKTyyEHyFsMPY3nK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/17ylq/btrN39vACwU/dk1t3kkKTyyEHyFsMPY3nK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/17ylq/btrN39vACwU/dk1t3kkKTyyEHyFsMPY3nK/img.gif&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;600&quot; height=&quot;236&quot; data-filename=&quot;ezgif.com-gif-maker (1).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;option ⌥&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;+ return&lt;span style=&quot;background-color: #ffffff;&quot;&gt;↩ &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혹은 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Alt + Enter &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단축키는 특정 위젯에 대해서만 적용할 수도 있고, 코드 상에서 특정 영역을 지정해 여러 위젯에 적용할 수도 있습니다. 위의 경우에는 특정 Sized Box 위젯에 대해 Center 위젯으로 감싸 가운데 정렬을 적용하는 경우입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&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;b&gt;특정 코드 단락을 지정해 다른 Widget으로 감싸거나, 부모 Widget을 제거할 때&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker (2).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c70KT5/btrN9rHYVqK/Kk2AAZrj23w7ZO9etIloOk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c70KT5/btrN9rHYVqK/Kk2AAZrj23w7ZO9etIloOk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c70KT5/btrN9rHYVqK/Kk2AAZrj23w7ZO9etIloOk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c70KT5/btrN9rHYVqK/Kk2AAZrj23w7ZO9etIloOk/img.gif&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;600&quot; height=&quot;473&quot; data-filename=&quot;ezgif.com-gif-maker (2).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 영역을 어느 한 위젯으로 모두 감싸거나, 특정 영역을 감싸고 있는 위젯을 없앨 때도 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;option ⌥&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;+ return&lt;span style=&quot;background-color: #ffffff;&quot;&gt;↩&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혹은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Alt + Enter&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단축키를 사용합니다. 예시에서는 Sized Box로 구성된 이미지 영역 3개를 단락으로 지정한 뒤 Row 위젯으로 감싸서 이미지들이 한 줄에 보이게 바꾸는 과정을 보여주고 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&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;h4 data-ke-size=&quot;size20&quot;&gt;줄 간격을 맞출 때 (Identation) 쓰는 단축키&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker (3).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J4yCK/btrN6ne2M4O/TN30oJPRxKw8feJ7sRiKb1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J4yCK/btrN6ne2M4O/TN30oJPRxKw8feJ7sRiKb1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J4yCK/btrN6ne2M4O/TN30oJPRxKw8feJ7sRiKb1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/J4yCK/btrN6ne2M4O/TN30oJPRxKw8feJ7sRiKb1/img.gif&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;600&quot; height=&quot;132&quot; data-filename=&quot;ezgif.com-gif-maker (3).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마지막으로 알려드릴 단축키는&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;option ⌥&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;+ command &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;⌘&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span&gt; + l &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(윈도우는&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; Ctrl + Alt + l&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입니다. 깃헙이나 다른 블로그를 보다가 예제 코드를 가져와 붙여넣기하면, 들여쓰기가 전부 어그러지는 경우가 많습니다. 이럴 때는 코드 구조를 맞춰주는 단축키를 적용해 다시 눈에 보기 좋은 코드로 쉽게 바꿔줄 수 있답니다!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/15</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%9D%B4-%EC%89%AC%EC%9B%8C%EC%A7%80%EB%8A%94-IDE-%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0#entry15comment</comments>
      <pubDate>Mon, 10 Oct 2022 09:00:49 +0900</pubDate>
    </item>
    <item>
      <title>플러터(Flutter) - Null Safety 에러 없애기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Null-Safety-%EC%97%90%EB%9F%AC-%EC%97%86%EC%95%A0%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Null Safety 에러 하나를 해결하고, 플러터에서 얘기하는 Null Safety가 무엇이고 왜 적용되었는지 알아본 뒤, 코딩할 때 마주치는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;null safety 관련 연산자 &lt;span style=&quot;color: #000000;&quot;&gt;?와 !, late&lt;/span&gt;&lt;/span&gt;에 대해 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;패키지를 추가한 뒤 마주친 Null Safety 에러 해결하기&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWfTnf/btrN3T0IFFP/ZwX7josKtzit2G6xjMwAH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWfTnf/btrN3T0IFFP/ZwX7josKtzit2G6xjMwAH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWfTnf/btrN3T0IFFP/ZwX7josKtzit2G6xjMwAH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWfTnf%2FbtrN3T0IFFP%2FZwX7josKtzit2G6xjMwAH0%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;1974&quot; height=&quot;520&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 현재 포스트 작성 시점에서 사용 중인 플러터 버전은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;3.3.3&lt;/span&gt;이고, 다트(Dart) 버전은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;2.18.2&lt;/span&gt;입니다. 플러터 프로젝트에서 로그인 페이지를 구현하기 위해 flutter_signin_button 패키지를 추가했더니 dependencies에 있는 flutter_signin_button와 font_awesome_flutter가 null safety를 지원하지 않는다는 에러가 떴습니다. pubspec.yaml 파일을 봤더니 flutter_sigin_button 0.2.5 버전이 깔려있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwua05/btrN77QqvuJ/nkkLnsksW0wQ7MZvJBdaz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwua05/btrN77QqvuJ/nkkLnsksW0wQ7MZvJBdaz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwua05/btrN77QqvuJ/nkkLnsksW0wQ7MZvJBdaz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcwua05%2FbtrN77QqvuJ%2FnkkLnsksW0wQ7MZvJBdaz1%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;1272&quot; height=&quot;230&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pub.dev에서 &lt;a href=&quot;https://pub.dev/packages/flutter_signin_button&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;flutter_signin_button 패키지&lt;/a&gt; 내용을 확인하니,&amp;nbsp; flutter_signin_button의 최신 버전은 2.0.0이고 Null Safety를 지원한다고 합니다. 그래서 pubspec.yaml 파일의 flutter_signin_button 버전을 2.0.0 으로 수정한 뒤 저장하니 에러가 사라지고 앱이 잘 런칭되었습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Null Safety는 무엇이고 왜 적용했을까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TL;DR&amp;nbsp; &lt;/b&gt;Null Safety는 한 마디로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;앱 사용 중에 변수에 값이 없어 예상하지 못한 에러가 발생하는 경우를 방지하겠다&lt;/span&gt;는 Dart 언어의 사용 규칙입니다.&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;다른 말로 하면 'null 상태가 되면 안 되는 변수가 런타임에서 null 상태로 문제를 일으키지 못하도록, 컴파일 타임에 정적 체크를 통해 알려주겠다'라고도 이해할 수 있습니다. 사용자 인터페이스를 담당하는 앱에서, 앱이 실행 중에 런타임 에러가 발생하면 골치 아프니까요.&amp;nbsp; &lt;a href=&quot;https://dart.dev/null-safety/understanding-null-safety&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;dart 페이지&lt;/a&gt; 설명에 따르면, 기존 시스템에서는 Null 타입이 Object와 자식 클래스인 Iterable, num 등 모든 타입에서 null을 허용하기 때문에 null 참조 에러가 발생했습니다. 예시로 설명된 List의 경우, myList라는 List의 값이 할당이 안 된 상태에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;myList[0]&lt;/span&gt;&lt;/b&gt;나 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;myList.add(1)&lt;/span&gt; &lt;/b&gt;등등 myList를 참조하려고 하는 경우는 모두 에러가 발생했겠죠. 이런 상황을 막고자 Dart에서는 Null 클래스를 기존 Object 클래스에서 따로 분리시켰습니다. 즉, Null을 제외한 모든 타입은 반드시 값을 할당해야한다고 못박은거죠.&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;하지만 런타임 에러의 주범 Null은 코딩에서 값이 반드시 할당될 필요가 없을 때 &lt;span&gt;약방의 감초같이&lt;span&gt; 유용하게 쓰이기 때문에, 이 경우에는 타입 옆에 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;?&lt;/span&gt;&lt;/b&gt;를 추가해 null 할당이 예외적으로 가능하게 했습니다. &lt;span style=&quot;color: #000000;&quot;&gt;?&lt;/span&gt;를 붙이면 해당 변수 타입을 Nullable, 즉 'null 값 할당이 가능한 상태'로 만들어 줍니다. &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;String? myString&lt;/span&gt;&lt;/b&gt;으로 String 타입을 선언했다면 myString은 값이 할당되지 않을 수도 있습니다. 단, 이런 경우에 반드시 if (myString == null) 등으로 myString이 null인지 체크하는 구문을 넣어야 안전하게 사용할 수 있습니다.&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;반대로 String 값이 반드시 있어야 한다면, &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;String myString = &quot;Hello, world!&quot;;&lt;/span&gt; &lt;/b&gt;와 같이 String 변수에 대해 선언과 동시에 값을 대입해야 합니다. 다만 에러 체크를 안해도 된다고 판단하는 경우나 다른 코드에서 값을 반드시 대입하기 때문에 그냥 넘어가도 괜찮다고 생각되는 경우에는 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;String! myString;&lt;/span&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;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;?나 !보다&lt;/span&gt;&lt;b&gt; late&lt;/b&gt; &lt;/span&gt;키워드를 쓰면 변수 선언과 값 할당이 서로 떨어져 있는 경우를 좀 더 유연하게 처리할 수 있습니다. &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;late String myString;&lt;/span&gt;&lt;/b&gt; 은 myString 값이 다른 코드에서 값이 할당된다는 걸 개발자에게 명시적으로 알려줍니다. 따라서 null 값이 할당된다고 착각하지 않고 변수를 처리할 수 있겠죠. 실제 현업에서는 개발 담당자가 바뀌며 변수 사용에 대한 히스토리가 없어서 어떤 용도로 사용하는 변수인지 잘 모르는 경우가 종종 발생합니다. 이럴 때 null이 사용되지 않지만 바로 값을 대입하지 않는 변수에 대해, late 키워드를 넣어주면 다른 개발자가 해당 변수에 null을 할당하는 실수를 방지할 수 있습니다.&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>플러터 null safety</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/14</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0Flutter-Null-Safety-%EC%97%90%EB%9F%AC-%EC%97%86%EC%95%A0%EA%B8%B0#entry14comment</comments>
      <pubDate>Sun, 9 Oct 2022 09:00:57 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 데모 앱 살펴보기 3 - interactivity, navigation</title>
      <link>https://codeflow.tistory.com/entry/Flutter-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-3-interactivity-navigation</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 코드랩 예제가 재미있기 때문에,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2#0&quot;&gt;startup_namer, part2&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;도 한 번 살펴보겠습니다. 이 예제에서는 리스트 아이콘을 통해 새로운 페이지로 이동하는 코드가 담겨 있습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-07 오후 11.23.11.png&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/on3sk/btrN5wivFG2/GN4ILGi3So8xoL0EkkhzMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/on3sk/btrN5wivFG2/GN4ILGi3So8xoL0EkkhzMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/on3sk/btrN5wivFG2/GN4ILGi3So8xoL0EkkhzMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fon3sk%2FbtrN5wivFG2%2FGN4ILGi3So8xoL0EkkhzMk%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;1916&quot; height=&quot;1144&quot; data-filename=&quot;스크린샷 2022-10-07 오후 11.23.11.png&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1144&quot;/&gt;&lt;/span&gt;&lt;/figure&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;코드랩에서 안내하는 대로 샘플 프로젝트를 생성해보겠습니다. 터미널을 켜서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter create startup_namer&lt;/span&gt;&lt;/b&gt;로 플러터 프로젝트를 생성해줍니다. (startup_namer part1 프로젝트가 동일한 이름을 쓰고 있었기 때문에 기존 프로젝트 이름을 변경해주었습니다.) 그 다음 startup_namer 프로젝트로 이동해서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter pub add english_words&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;커맨드를 통해 english_words 패키지를 플러터 프로젝트 패키지 관리 파일인 pubspec.yaml에 의존성을 추가하고 라이브러리를 당겨와 설치해 줍니다. 실제 studio . 커맨드로 Android Studio를 실행해서 확인하면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;External Libraries&amp;gt; Dart Packages&amp;gt; english_words-[버전명]&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더 라이브러리가 다운로드되어 있고, pubspec.yaml 파일에 english_words 라이브러리에 대한 의존성이 추가된 상태를 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2024&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BXDe0/btrN4xP13Ka/7tgwOJcKcUiZz7F5Hs7UyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BXDe0/btrN4xP13Ka/7tgwOJcKcUiZz7F5Hs7UyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BXDe0/btrN4xP13Ka/7tgwOJcKcUiZz7F5Hs7UyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBXDe0%2FbtrN4xP13Ka%2F7tgwOJcKcUiZz7F5Hs7UyK%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;2024&quot; height=&quot;542&quot; data-origin-width=&quot;2024&quot; data-origin-height=&quot;542&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;main.dart 파일에서 데모 코드를 지우고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/flutter/codelabs/blob/master/startup_namer/step6_add_interactivity/lib/main.dart&quot;&gt;샘플 코드&lt;/a&gt;를 깃헙에서 복사해 붙여넣습니다.&amp;nbsp; 그런 다음 실행하면 다음과 같이 리스트에 나오는 스타트업 이름 후보인 영어 단어 쌍 옆에 하트 표시가 생기고, 클릭할 때마다 하트에 빨간색이 칠해지고 지워지는 동작을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1984&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjFjha/btrN4ZMafdF/KPafmJ7ApXdV2XY8fKd61K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjFjha/btrN4ZMafdF/KPafmJ7ApXdV2XY8fKd61K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjFjha/btrN4ZMafdF/KPafmJ7ApXdV2XY8fKd61K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjFjha%2FbtrN4ZMafdF%2FKPafmJ7ApXdV2XY8fKd61K%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;1984&quot; height=&quot;848&quot; data-origin-width=&quot;1984&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ListTile 위젯 onTap 속성에 setState() 메서드가 동작했기 때문입니다. ListTile 클릭 시마다 _saved 변수에 _suggestions[index]에 해당하는 스타트업 이름이 추가되거나 삭제되고, 이 때 변화 상태가 alreadySaved 변수에 저장되게 됩니다.&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/13</guid>
      <comments>https://codeflow.tistory.com/entry/Flutter-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-3-interactivity-navigation#entry13comment</comments>
      <pubDate>Sat, 8 Oct 2022 00:11:49 +0900</pubDate>
    </item>
    <item>
      <title>Flutter Material 디자인 - BottomNavigationBar (탭 바)</title>
      <link>https://codeflow.tistory.com/entry/Flutter-Material-%EB%94%94%EC%9E%90%EC%9D%B8-BottomNavigationBar-%ED%83%AD-%EB%B0%94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터의 Material 디자인이 담긴 Material 위젯에서는 탭 바를 BottomNavigationBar 클래스에서 제공하고 있습니다. Material 위젯에서 기본적으로 제공하는 샘플을 통해 동작을 살펴보겠습니다. Bottom Navigation Bar는 클릭한 탭의 정보를 업데이트해서 보여주기 때문에 Stateful 위젯이고, 화면 구성 시에 주로 Scaffold 위젯에서 하단에 Floating Action Button 대신 Bottom Navigation Bar를 보여주는 형식을 따르게 됩니다.&amp;nbsp; &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Bottom Navigation Bar&lt;/span&gt;에서 개별 탭은 BottomNavigationBarItem 위젯을 통해 구성하고 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Bottom Navigation Bar 샘플 프로젝트 생성 후 실행하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-06 오후 9.58.32.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqf8Dr/btrNZL7WDGW/evaGunp8AO2WKbNNtxoiO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqf8Dr/btrNZL7WDGW/evaGunp8AO2WKbNNtxoiO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqf8Dr/btrNZL7WDGW/evaGunp8AO2WKbNNtxoiO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqf8Dr%2FbtrNZL7WDGW%2FevaGunp8AO2WKbNNtxoiO0%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;2004&quot; height=&quot;872&quot; data-filename=&quot;스크린샷 2022-10-06 오후 9.58.32.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플 프로젝트는 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter create --sample=material.BottomNavigationBar.1 mysample &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커맨드를&lt;/span&gt;&lt;/span&gt;&amp;nbsp;통해 생성합니다. (&lt;a href=&quot;https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html&quot;&gt;https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html&lt;/a&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; 참고) 그 다음 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;studio mysample&lt;/span&gt;&lt;/b&gt; 커맨드로 Android Studio에서 프로젝트를 열어줍니다. 프로젝트를 실행하면 다음과 같이 BottomNavigationBar Sample이라는 타이틀을 단 앱이 나타나는데요, 하단에 Home, Business, School이라는 탭이 보이고 각각을 클릭하면 선택된 탭의 색이 주황색(amber)으로 변하고, 화면 중앙에 해당 탭의 인덱스와 탭 이름을 보여주게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;1380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dq4NS8/btrNXM8nlL0/PWh0ruwjkh79kbEBDkM8F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dq4NS8/btrNXM8nlL0/PWh0ruwjkh79kbEBDkM8F1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dq4NS8/btrNXM8nlL0/PWh0ruwjkh79kbEBDkM8F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdq4NS8%2FbtrNXM8nlL0%2FPWh0ruwjkh79kbEBDkM8F1%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;302&quot; height=&quot;615&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;1380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Bottom Navigation Bar 샘플 프로젝트 구조 살펴보기&lt;/h2&gt;
&lt;pre id=&quot;code_1665062344756&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class _MyStatefulWidgetState extends State&amp;lt;MyStatefulWidget&amp;gt; {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static const List&amp;lt;Widget&amp;gt; _widgetOptions = &amp;lt;Widget&amp;gt;[
    Text(
      'Index 0: Home',
      style: optionStyle,
    ),
    Text(
      'Index 1: Business',
      style: optionStyle,
    ),
    Text(
      'Index 2: School',
      style: optionStyle,
    ),
  ];
  
    void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bottom Navigation Bar&lt;span&gt; 각각의 탭에서 보여주는 텍스트는 _widgetOptions라는 위젯 리스트에서 Text 위젯에 담아 보여주고 있습니다. 특정 탭을 클릭하게 되면 _onItemTapped 함수가 불리면서 인자로 선택된 탭의 index가 넘어가고, 이 함수 안에서 내부 변수인 _selectedIndex에 해당 인자를 넣어주고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1665062615970&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Sample'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const &amp;lt;BottomNavigationBarItem&amp;gt;[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Business',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'School',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 화면을 뿌려주는 build 위젯에서는 앱 타이틀, 선택된 탭의 텍스트, Bottom Navigation Bar의 탭들을 어떻게 보여줄지에 대한 정보를 담고 있습니다. 가장 마지막 3줄을 보면, 탭 클릭시 선택된 탭의 인덱스를 _selectedIndex에 넣어주고, 선택된 탭의 컬러는 amber 색상 중 어두운 계열인 800으로, 탭 클릭 시에는 _onItemTapped 함수를 호출하게 되어있습니다.&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;p data-ke-size=&quot;size16&quot;&gt;이 예제의 핵심 요소는 아니지만 selectedItemColor: Colors.amber[800]의 의미가 궁금하실 분들은 &lt;a href=&quot;https://www.materialpalette.com/colors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.materialpalette.com/colors&lt;/a&gt; 에서 Material 디자인의 색상 정보를 확인할 수 있습니다. 숫자가 커질수록 색상이 어두워집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c03Tu2/btrNWqShpCE/OwPAA5KTszJVuGFPP3LTHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c03Tu2/btrNWqShpCE/OwPAA5KTszJVuGFPP3LTHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c03Tu2/btrNWqShpCE/OwPAA5KTszJVuGFPP3LTHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc03Tu2%2FbtrNWqShpCE%2FOwPAA5KTszJVuGFPP3LTHk%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;1060&quot; height=&quot;501&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;501&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;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/11</guid>
      <comments>https://codeflow.tistory.com/entry/Flutter-Material-%EB%94%94%EC%9E%90%EC%9D%B8-BottomNavigationBar-%ED%83%AD-%EB%B0%94#entry11comment</comments>
      <pubDate>Thu, 6 Oct 2022 22:36:46 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 데모 앱 살펴보기 2 - Widget과 외부 패키지 사용법, 스크롤 기능</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-2-Widget%EA%B3%BC-%EC%99%B8%EB%B6%80-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EA%B8%B0%EB%8A%A5</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;플러터 코드랩에서는 &lt;a href=&quot;https://docs.flutter.dev/get-started/codelab#step-1-create-the-starter-flutter-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://docs.flutter.dev/get-started/codelab#step-1-create-the-starter-flutter-app&lt;/span&gt;&lt;/a&gt; 라는 예제를 통해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Widget 다루는 방법, 외부 패키지를 불러들여 사용하는 방법, ListView를 통한 스크롤 기능&lt;/span&gt;을 소개하고 있습니다. 기본적으로 생성되는 데모 앱 다음 단계로 다루기 좋은 내용이라 한 번 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;터미널에서 앱 생성하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1052&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIt9tW/btrNNo0vow2/VAZDXkGAI7zM7IOLdUHUDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIt9tW/btrNNo0vow2/VAZDXkGAI7zM7IOLdUHUDK/img.png&quot; data-alt=&quot; &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIt9tW/btrNNo0vow2/VAZDXkGAI7zM7IOLdUHUDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIt9tW%2FbtrNNo0vow2%2FVAZDXkGAI7zM7IOLdUHUDK%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;2004&quot; height=&quot;1052&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1052&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드랩 예제는 터미널에서 플러터 앱 생성하는 방법으로 시작하고 있어서 저도 터미널에서 해당 프로젝트를 먼저 생성했습니다. 전체적으로는 터미널에서 iOS 시뮬레이터를 띄우고 (&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;open -a Simulator&lt;/span&gt;&lt;/b&gt;), startup_namer라는 플러터 앱을 생성한 후 (&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter create startup_namer&lt;/span&gt;&lt;/b&gt;), startup_namer 프로젝트를 Android Studio에서 열어보는 (&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;studio startup_namer&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt; 순서로 진행했습니다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;startup_namer 앱으로 바꾸기&lt;/h2&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import 'package:flutter/material.dart';

void main() {
&amp;nbsp;&amp;nbsp;runApp(const MyApp());
}

class MyApp extends StatelessWidget {
&amp;nbsp;&amp;nbsp;const MyApp({super.key});

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return MaterialApp(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: 'Welcome to Flutter',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;home: Scaffold(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;appBar: AppBar(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: const Text('Welcome to Flutter'),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body: const Center(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child: Text('Hello World'),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Android Studio에서 startup_namer 프로젝트를 연 후 가장 먼저 할 일은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;lib/main.dart&lt;/span&gt; 파일에서 기존 데모 앱 코드를 지우고 위 코드를 추가해주는 것입니다. 그럼 다음 이미지와 같이 Hello, World가 찍히는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;Stateless Widget&lt;/span&gt; 하나가 덩그러니 보이게 됩니다. Stateless Widget이기 때문에 상태를 변화시키는 함수나 변수는 사용하지 않게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;1456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rsygE/btrNOf24gY5/kkeEpaK3K295wg58DVWEtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rsygE/btrNOf24gY5/kkeEpaK3K295wg58DVWEtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rsygE/btrNOf24gY5/kkeEpaK3K295wg58DVWEtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrsygE%2FbtrNOf24gY5%2FkkeEpaK3K295wg58DVWEtk%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;181&quot; height=&quot;374&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;외부 패키지 설치하기 (pubspec.yaml)&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번 앱에서는 외부 패키지를 적용하는 방법도 다루고 있는데요, english_words라는 패키지에서 WordPair 클래스를 가져다 쓰게 됩니다. WordPair 클래스를 통해 앱 화면에서 출력되는 텍스트를 'Hello World'에서 두 영어 단어의 조합으로 된 텍스트 출력으로 바꿔줍니다. 예를 들면 'AirKey' 같은 단어로 말이죠.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQlJuU/btrNOUK8T4l/Qedv3A9uHvpBQGEwZeY33k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQlJuU/btrNOUK8T4l/Qedv3A9uHvpBQGEwZeY33k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQlJuU/btrNOUK8T4l/Qedv3A9uHvpBQGEwZeY33k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQlJuU%2FbtrNOUK8T4l%2FQedv3A9uHvpBQGEwZeY33k%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;1674&quot; height=&quot;640&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;외부 패키지가 필요한 경우에는 먼저 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;pubspec.yaml&lt;/span&gt; (yaml은 야믈 또는 얘믈로 발음) 파일에서 추가할 패키지 이름과 버전을 적어줍니다. &lt;br /&gt;그러면 상단 Flutter Commands에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Pub get&lt;/span&gt;&lt;/b&gt;이라는 단어가 보이는데 클릭해서 패키지를 설치해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L4mYr/btrNN0dOT98/r4V1ch2g7HyBLIZZmJlt2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L4mYr/btrNN0dOT98/r4V1ch2g7HyBLIZZmJlt2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L4mYr/btrNN0dOT98/r4V1ch2g7HyBLIZZmJlt2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL4mYr%2FbtrNN0dOT98%2Fr4V1ch2g7HyBLIZZmJlt2K%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;1582&quot; height=&quot;198&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;패키지 설치 시 하단에서는 터미널을 통해 진행 상황을 알려줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2186&quot; data-origin-height=&quot;1354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MWTd3/btrNNeX3F9Y/vyn6fDTcawHGjqmsp1tLh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MWTd3/btrNNeX3F9Y/vyn6fDTcawHGjqmsp1tLh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MWTd3/btrNNeX3F9Y/vyn6fDTcawHGjqmsp1tLh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMWTd3%2FbtrNNeX3F9Y%2Fvyn6fDTcawHGjqmsp1tLh0%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;2186&quot; height=&quot;1354&quot; data-origin-width=&quot;2186&quot; data-origin-height=&quot;1354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;패키지 설치 후에는 WordPair.random() 함수를 통해 생성한 랜덤 영단어 페어를 wordPair라는 변수에 저장하고, Text 위젯에 파라미터로 이 변수를 넣어줘서 화면에 출력되게 만들어 줍니다. 기본적인 폰트 크기가 작아서 약간 수정해주었습니다. 오른쪽은 iOS 시뮬레이터에서 보이는 결과 화면입니다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;Stateful Widget&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1318&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Yel6a/btrNM42jSJA/2POrj0jFzXSkGK4BJrsib1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Yel6a/btrNM42jSJA/2POrj0jFzXSkGK4BJrsib1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Yel6a/btrNM42jSJA/2POrj0jFzXSkGK4BJrsib1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYel6a%2FbtrNM42jSJA%2F2POrj0jFzXSkGK4BJrsib1%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;1318&quot; height=&quot;162&quot; data-origin-width=&quot;1318&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 앱에서는 스크롤을 통해 다음 화면으로 넘어갈 때마다 새로운 영단어 페어를 보여주는 기능이 있습니다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;화면의 상태가 변할 때,&lt;/span&gt; 이 기능이 동작하도록 Stateful Widget을 상속하는 RandomWords 클래스를 만들어 줍니다. Stateful Widget을 만들 때는 IDE에 stful이라는 단어를 치고 탭 키를 누르면, 아래 이미지와 같이 기본적인 Stateful Widget 타입 클래스 골격을 만들어 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biDGv3/btrNNzOh7Hh/l7ONNhkpznvEqtrXy3vfCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biDGv3/btrNNzOh7Hh/l7ONNhkpznvEqtrXy3vfCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biDGv3/btrNNzOh7Hh/l7ONNhkpznvEqtrXy3vfCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiDGv3%2FbtrNNzOh7Hh%2Fl7ONNhkpznvEqtrXy3vfCk%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;1306&quot; height=&quot;574&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;텍스트 표시를 담당하는 RaondomWords 클래스를 만들어서 Material App에서도 이 단어를 보여주도록 구성한 코드입니다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';

void main() {
&amp;nbsp;&amp;nbsp;runApp(const MyApp());
}

class MyApp extends StatelessWidget {
&amp;nbsp;&amp;nbsp;const MyApp({super.key});

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final wordPair = WordPair.random();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return MaterialApp(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: 'Welcome to Flutter',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;home: Scaffold(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;appBar: AppBar(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: const Text('Welcome to Flutter'),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body: Center(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child: RandomWords()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}
}

class RandomWords extends StatefulWidget {
&amp;nbsp;&amp;nbsp;const RandomWords({super.key});

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;State&amp;lt;RandomWords&amp;gt; createState() =&amp;gt; _RandomWordsState();
}

class _RandomWordsState extends State&amp;lt;RandomWords&amp;gt; {
&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final wordPair = WordPair.random();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Text(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wordPair.asPascalCase,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;style: TextStyle(fontSize: 30),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div id=&quot;code-excerpt-9&quot;&gt;이전 코드에서의 실행 상태와 다르지는 않지만 이제 RandomWords 클래스에 _suggestions라는 WordPair 리스트 변수를 추가해 여러 개의 WordPair를 담을 수 있게 하고, ListView를 통해 WordPair 리스트를 보여줍니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2156&quot; data-origin-height=&quot;1590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FQMJ1/btrNOe4ccIl/fpRKjQNAWFvYvWLhMP9II0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FQMJ1/btrNOe4ccIl/fpRKjQNAWFvYvWLhMP9II0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FQMJ1/btrNOe4ccIl/fpRKjQNAWFvYvWLhMP9II0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFQMJ1%2FbtrNOe4ccIl%2FfpRKjQNAWFvYvWLhMP9II0%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;2156&quot; height=&quot;1590&quot; data-origin-width=&quot;2156&quot; data-origin-height=&quot;1590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 다음 ListTile을 추가해 Text가 출력되는 형식을 좀 더 다듬어 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2164&quot; data-origin-height=&quot;1250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csup23/btrNMG1xV2x/AI6HLdCBVRJijpXagaB8zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csup23/btrNMG1xV2x/AI6HLdCBVRJijpXagaB8zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csup23/btrNMG1xV2x/AI6HLdCBVRJijpXagaB8zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcsup23%2FbtrNMG1xV2x%2FAI6HLdCBVRJijpXagaB8zk%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;2164&quot; height=&quot;1250&quot; data-origin-width=&quot;2164&quot; data-origin-height=&quot;1250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로는 아래 코드를 통해 startup_namer 앱의 스크롤 가능한 word pair 리스트 출력 기능이 완성되었습니다!&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';

void main() {
&amp;nbsp;&amp;nbsp;runApp(const MyApp());
}

class MyApp extends StatelessWidget {
&amp;nbsp;&amp;nbsp;const MyApp({super.key});

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return MaterialApp(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: 'Startup Name Generator',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;home: RandomWords()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}
}

class RandomWords extends StatefulWidget {
&amp;nbsp;&amp;nbsp;const RandomWords({super.key});

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;State&amp;lt;RandomWords&amp;gt; createState() =&amp;gt; _RandomWordsState();
}

class _RandomWordsState extends State&amp;lt;RandomWords&amp;gt; {
&amp;nbsp;&amp;nbsp;final _suggestions = &amp;lt;WordPair&amp;gt;[];
&amp;nbsp;&amp;nbsp;final _biggerFont = const TextStyle(fontSize: 18);

&amp;nbsp;&amp;nbsp;@override
&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Scaffold(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;appBar: AppBar(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: const Text('Startup Name Generator'),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body: _buildSuggestions(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}


&amp;nbsp;&amp;nbsp;Widget _buildSuggestions() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//final wordPair = WordPair.random();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ListView.builder(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;padding: const EdgeInsets.all(16),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;itemBuilder: /*1*/ (BuildContext context, int i) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (i.isOdd) return const Divider(); /*2*/

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final index = i ~/ 2; /*3*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (index &amp;gt;= _suggestions.length) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_suggestions.addAll(generateWordPairs().take(10)); /*4*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return _buildRow(_suggestions[index]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;Widget _buildRow(WordPair pair) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ListTile(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: Text(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pair.asPascalCase,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;style: _biggerFont,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/10</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-2-Widget%EA%B3%BC-%EC%99%B8%EB%B6%80-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EA%B8%B0%EB%8A%A5#entry10comment</comments>
      <pubDate>Wed, 5 Oct 2022 23:10:46 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 데모 앱 살펴보기 1 - 디버깅 속도를 높여주는 Hot Reload</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-%EB%94%94%EB%B2%84%EA%B9%85-%EC%86%8D%EB%8F%84%EB%A5%BC-%EB%86%92%EC%97%AC%EC%A3%BC%EB%8A%94-Hot-Reload</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 앱에서 기본적으로 생성해주는 데모 앱이 어떻게 구동되는지 살펴봅시다. 'Flutter Demo'라는 이름이 붙은 이 앱은 플러터의 기본 기능 중 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Hot Reload, StatelessWidget과 StatefulWidget의 차이&lt;/span&gt;를 이해할 수 있게 간단한 카운터 기능만 제공하고 있습니다. 데모 앱을 실행하기 전에 터미널에서 Android Studio를 실행시키는 방법을 알아보고, 플러터 프로젝트도 터미널에서 Android Studio를 실행과 동시에 바로 열어보도록 하겠습니다.&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;터미널에서 Android Studio 실행하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-05 오전 8.42.49.png&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/luDhJ/btrNTd5hoPX/wyWZV2ZunsjagIWZGkNFL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/luDhJ/btrNTd5hoPX/wyWZV2ZunsjagIWZGkNFL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/luDhJ/btrNTd5hoPX/wyWZV2ZunsjagIWZGkNFL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FluDhJ%2FbtrNTd5hoPX%2FwyWZV2ZunsjagIWZGkNFL1%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;1916&quot; height=&quot;1108&quot; data-filename=&quot;스크린샷 2022-10-05 오전 8.42.49.png&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 Android Studio를 바로 열기 위해서는 터미널에서 Android Studio 실행파일 경로를 오픈하는 명렁어를 입력해주면 됩니다. 다만 이렇게 하면 매번 실행하기 번거롭기 때문에 더 짧은 단어와 Android Studio 실행을 연결해 봅시다. 이 경우, &lt;span style=&quot;background-color: #9feec3;&quot;&gt;.zprofile&lt;/span&gt; 파일에 alias로 Android Studio.app 경로만 추가시켜주면 됩니다. .zprofile 파일을 열어서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;alias studio='open -a /Applications/Android\ Studio.app'&lt;/span&gt;&lt;/b&gt;라고 한 줄을 추가해주거나, 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;echo 'alias studio=&quot;open -a /Applications/Android\ Studio.app&quot; &amp;gt;&amp;gt; ~/.zprofile&lt;/span&gt;&lt;/b&gt;이라고 치면 바로 .zprofile 파일에 반영됩니다. &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;source ~/.zprofile&lt;/b&gt;&lt;/span&gt;로 .zprofile 변경 사항을 적용한 후에는 alias로 설정한 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;studio&lt;/span&gt;&lt;/b&gt;라는 커맨드로 Android Studio를 실행시킬 수 있게 됩니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-05 오후 10.14.24.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o9xOO/btrNSWQipGi/kegqzjeKnktUIn3FI0f57K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o9xOO/btrNSWQipGi/kegqzjeKnktUIn3FI0f57K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o9xOO/btrNSWQipGi/kegqzjeKnktUIn3FI0f57K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo9xOO%2FbtrNSWQipGi%2FkegqzjeKnktUIn3FI0f57K%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;2004&quot; height=&quot;404&quot; data-filename=&quot;스크린샷 2022-10-05 오후 10.14.24.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;studio라는 커맨드가 Android Studio를 실행하도록 연결되어 있기 때문에, 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;studio my_app&lt;/span&gt;&lt;/b&gt;이라고 입력하면, 이전에 만들어 둔 데모 앱 프로젝트를 Android Studio에서 바로 불러올 수 있습니다. 터미널에서 플러터 데모 앱을 만들고 에뮬레이터나 시뮬레이터를 통해 실행하는 방법은 이전에 작성한 포스팅에 소개되어 있으니 참고하시길 바랄게요  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codeflow.tistory.com/entry/플러터-개발-환경-구축-2-터미널과-Android-Studio에서-데모-앱-돌려보기&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.10.03 - [기본 코딩] - 플러터 개발 환경 구축 2 - 터미널과 Android Studio에서 데모 앱 돌려보기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664975627802&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;플러터 개발 환경 구축 2 - 터미널과 Android Studio에서 데모 앱 돌려보기&quot; data-og-description=&quot;플러터 앱은 터미널과 Android Studio 각각에서 실행할 수 있습니다. 단, 앱을 설치할 Android Emulator와 iOS Simulator 각각이 먼저 실행되고 있어야 합니다. 터미널과 Android Studio에서 안드로이드 에뮬레이.&quot; data-og-host=&quot;codeflow.tistory.com&quot; data-og-source-url=&quot;https://codeflow.tistory.com/entry/플러터-개발-환경-구축-2-터미널과-Android-Studio에서-데모-앱-돌려보기&quot; data-og-url=&quot;https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-2-%ED%84%B0%EB%AF%B8%EB%84%90%EA%B3%BC-Android-Studio%EC%97%90%EC%84%9C-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EB%8F%8C%EB%A0%A4%EB%B3%B4%EA%B8%B0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cRiMoa/hyP2b4gqhu/nxdzEXzYaKN4urSO6fXAM1/img.png?width=800&amp;amp;height=498&amp;amp;face=0_0_800_498,https://scrap.kakaocdn.net/dn/fN6o7/hyP19SUWJl/NKQfsBnXVqekqxnjENXLX1/img.png?width=800&amp;amp;height=498&amp;amp;face=0_0_800_498,https://scrap.kakaocdn.net/dn/IzPT0/hyP2cPDBG0/yLdbyUXBPBkaYyiKCJQ7dk/img.png?width=1670&amp;amp;height=1592&amp;amp;face=0_0_1670_1592&quot;&gt;&lt;a href=&quot;https://codeflow.tistory.com/entry/플러터-개발-환경-구축-2-터미널과-Android-Studio에서-데모-앱-돌려보기&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codeflow.tistory.com/entry/플러터-개발-환경-구축-2-터미널과-Android-Studio에서-데모-앱-돌려보기&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cRiMoa/hyP2b4gqhu/nxdzEXzYaKN4urSO6fXAM1/img.png?width=800&amp;amp;height=498&amp;amp;face=0_0_800_498,https://scrap.kakaocdn.net/dn/fN6o7/hyP19SUWJl/NKQfsBnXVqekqxnjENXLX1/img.png?width=800&amp;amp;height=498&amp;amp;face=0_0_800_498,https://scrap.kakaocdn.net/dn/IzPT0/hyP2cPDBG0/yLdbyUXBPBkaYyiKCJQ7dk/img.png?width=1670&amp;amp;height=1592&amp;amp;face=0_0_1670_1592');&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;플러터 개발 환경 구축 2 - 터미널과 Android Studio에서 데모 앱 돌려보기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;플러터 앱은 터미널과 Android Studio 각각에서 실행할 수 있습니다. 단, 앱을 설치할 Android Emulator와 iOS Simulator 각각이 먼저 실행되고 있어야 합니다. 터미널과 Android Studio에서 안드로이드 에뮬레이.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codeflow.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Hot Reload&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 8.53.01.png&quot; data-origin-width=&quot;1328&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvyXjQ/btrNKgUKZnu/uEXN20vyeDUUhnCzp6F4x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvyXjQ/btrNKgUKZnu/uEXN20vyeDUUhnCzp6F4x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvyXjQ/btrNKgUKZnu/uEXN20vyeDUUhnCzp6F4x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvyXjQ%2FbtrNKgUKZnu%2FuEXN20vyeDUUhnCzp6F4x0%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;1328&quot; height=&quot;198&quot; data-filename=&quot;스크린샷 2022-10-04 오전 8.53.01.png&quot; data-origin-width=&quot;1328&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hot Reload는 앱이 실행 중인 상태에서 변경 사항만 빠르게 적용하는 기능입니다. IDE 상단 번개 모양 아이콘 클릭을 통해 적용할 수 있습니다. 웹 기반 코딩을 해오신 분들은 이런 당연한 기능을 따로 소개하면서 아이콘까지 별도로 있나 싶겠지만, 플러터는 별도의 OS 기기에서 돌아가는 앱이기 때문에 상황이 다릅니다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;디버깅을 위해 무조건 처음부터 앱을 빌드해야 하는 경우, 앱의 실행 상태는 유지하면서 모든 값을 초기화하는 경우, 앱의 실행 상태는 유지하면서 현재 값도 그대로 두고 변경사항만 적용하는 경우&lt;/span&gt; 3가지로 나뉩니다. 실행 속도는 뒤로 갈수록 빠르죠. 그래서 Hot이라는 단어가 붙게 되었습니다. 디버깅 상황에 따라 이 3가지를 모두 적용할 수 있게 되었기 때문에 앱 개발 시 생산성 향상을 위해 중요한 기능입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.09.18.png&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;1330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOv2t3/btrNxaCh6jd/irJfCnmmDERHJDWVGjFqCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOv2t3/btrNxaCh6jd/irJfCnmmDERHJDWVGjFqCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOv2t3/btrNxaCh6jd/irJfCnmmDERHJDWVGjFqCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOv2t3%2FbtrNxaCh6jd%2FirJfCnmmDERHJDWVGjFqCk%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;2036&quot; height=&quot;1330&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.09.18.png&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;1330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hot Reload는 그중 가장 빠른 속도를 보이는&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'&lt;span style=&quot;background-color: #f6e199;&quot;&gt;앱의 실행 상태와 현재 값을 유지하면서 변경 사항만 적용&lt;/span&gt;'하는 경우에 해당합니다.&amp;nbsp;&lt;/span&gt;예를 들어 샘플 앱에서 카운트를 증가시킨 상태에서 primarySwatch 컬러 값을 변경한 후 Hot Reload 버튼을 누르면, 카운트 값은 그대로 있지만 색상만 변경되게 되죠.&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;Hot Restart&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.16.51.png&quot; data-origin-width=&quot;2042&quot; data-origin-height=&quot;1084&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3wD5U/btrNIKu1Y3w/q6DVxmXN0zDFS7UjiSEu9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3wD5U/btrNIKu1Y3w/q6DVxmXN0zDFS7UjiSEu9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3wD5U/btrNIKu1Y3w/q6DVxmXN0zDFS7UjiSEu9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3wD5U%2FbtrNIKu1Y3w%2Fq6DVxmXN0zDFS7UjiSEu9K%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;2042&quot; height=&quot;1084&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.16.51.png&quot; data-origin-width=&quot;2042&quot; data-origin-height=&quot;1084&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hot Reload를 완전히 이해하려면, Hot Restart와 비교하는 게 좋습니다. 앞서 얘기한 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;앱의 실행 상태는 유지하면서 모든 값을 초기화'&lt;/span&gt;하는 경우가 Hot Restart입니다. 위 상태에서 primarySwatch를 Colors.green으로 색상을 변경한 후 Hot Restart를 실행하면 색상도 변경되고 카운트도 초기화된 걸 확인할 수 있습니다. 카운트 값까지 변경하는 만큼 속도는 더 느려지겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 실행한 후에는 상단 녹색 Run 버튼을 실행 시에 적용되고, 별도로 IDE 하단 실행 상태 바에서&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.21.14.png&quot; data-origin-width=&quot;64&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B3WtR/btrNKfuNoTg/uKYKcXfgDkDnOAFYAprRL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B3WtR/btrNKfuNoTg/uKYKcXfgDkDnOAFYAprRL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B3WtR/btrNKfuNoTg/uKYKcXfgDkDnOAFYAprRL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB3WtR%2FbtrNKfuNoTg%2FuKYKcXfgDkDnOAFYAprRL1%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;56&quot; height=&quot;52&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.21.14.png&quot; data-origin-width=&quot;64&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼을 누르면 Hot Restart가 적용됩니다. 실행 속도는 343ms로 나오네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.20.19.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yTFq2/btrNyC6oO4O/XPqsifojx5lTrNW9khVAw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yTFq2/btrNyC6oO4O/XPqsifojx5lTrNW9khVAw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yTFq2/btrNyC6oO4O/XPqsifojx5lTrNW9khVAw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyTFq2%2FbtrNyC6oO4O%2FXPqsifojx5lTrNW9khVAw0%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;2052&quot; height=&quot;278&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.20.19.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;색상만 바꿀 때 Hot Reload의 경우에는 144ms가 걸렸습니다. 실행 속도가 Hot Restart의 2배 이상 빠릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.23.17.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw3qF2/btrNHTlnGhW/Bm4Zy8DznbAL4XDcxRyXpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw3qF2/btrNHTlnGhW/Bm4Zy8DznbAL4XDcxRyXpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw3qF2/btrNHTlnGhW/Bm4Zy8DznbAL4XDcxRyXpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw3qF2%2FbtrNHTlnGhW%2FBm4Zy8DznbAL4XDcxRyXpk%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;2052&quot; height=&quot;254&quot; data-filename=&quot;스크린샷 2022-10-04 오전 9.23.17.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규모가 작은 샘플 앱이 아니라 실제 상용 앱의 경우에는 속도 차이가 더 커질 수 있겠죠? 디버깅 상황에 따라 Hot Reload 혹은 Hot Restart를 자유자재로 사용해 봅시다!&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/9</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0-%EB%94%94%EB%B2%84%EA%B9%85-%EC%86%8D%EB%8F%84%EB%A5%BC-%EB%86%92%EC%97%AC%EC%A3%BC%EB%8A%94-Hot-Reload#entry9comment</comments>
      <pubDate>Tue, 4 Oct 2022 09:29:17 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 개발 환경 구축 2 - 터미널과 Android Studio에서 데모 앱 돌려보기</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-2-%ED%84%B0%EB%AF%B8%EB%84%90%EA%B3%BC-Android-Studio%EC%97%90%EC%84%9C-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EB%8F%8C%EB%A0%A4%EB%B3%B4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 앱은 터미널과 Android Studio 각각에서 실행할 수 있습니다. 단, 앱을 설치할 Android Emulator와 iOS Simulator 각각이 먼저 실행되고 있어야 합니다. 터미널과 Android Studio에서 안드로이드 에뮬레이터와 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;&lt;b&gt;TL;DR&lt;/b&gt;&amp;nbsp; 플러터 데모 앱을 실행시키기까지 전 과정은 다음 7가지 스텝으로 요약할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Android Studio 및 SDK 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Flutter SDK 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Android Studio SDK와 Flutter SDK 환경변수 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Flutter Doctor로 빠진 부분이 있는지 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 플러터 앱 프로젝트 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. (Android와 iOS 가상 디바이스가 없다면 새로 생성 후) 가상 디바이스 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 터미널 혹은 Android Studio를 통해 플러터 앱 실행&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;터미널에서 iOS Simulator로 플러터 앱 실행시키기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터로 본격적인 개발을 시작하기 전에 데모 앱부터 실행해봅시다. &lt;a href=&quot;https://docs.flutter.dev/get-started/install/macos#ios-setup&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;플러터 공식 개발 가이드&lt;/a&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;1. 터미널에서 iOS 시뮬레이터 실행 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;open -a Simulator&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 플러터 데모 앱 생성 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter create my_app&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 플러터로 데모 앱 실행&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt; flutter run&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;/span&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 12.21.48.png&quot; data-origin-width=&quot;2296&quot; data-origin-height=&quot;1430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J8kWf/btrNB41DtiY/jK8ADVRnoLItr90W0bU3y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J8kWf/btrNB41DtiY/jK8ADVRnoLItr90W0bU3y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J8kWf/btrNB41DtiY/jK8ADVRnoLItr90W0bU3y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ8kWf%2FbtrNB41DtiY%2FjK8ADVRnoLItr90W0bU3y1%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;860&quot; height=&quot;536&quot; data-filename=&quot;스크린샷 2022-10-03 오후 12.21.48.png&quot; data-origin-width=&quot;2296&quot; data-origin-height=&quot;1430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;터미널에서 Android Emulator로 플러터 앱 실행시키기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드의 경우 에뮬레이터 리스트를 확인해서 에뮬레이터 이름을 얻고 실행시킨 후, iOS와 동일하게 flutter run 명령어를 실행해주면 됩니다. iOS 테스트 시에 생성한 my_app을 그대로 띄워보겠습니다. 실행 순서는 다음과 같습니다.&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;1. 에뮬레이터 리스트 조회 &amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;emulator&amp;nbsp;-list-avds&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 특정 에뮬레이터 실행 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;emulator -avd &lt;i&gt;기기명&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 플러터로 데모 &lt;span&gt;앱 실행&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;flutter run&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.37.49.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgadIt/btrNwnPdqC5/LToUhq4u3k9yZxi4hcVXOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgadIt/btrNwnPdqC5/LToUhq4u3k9yZxi4hcVXOk/img.png&quot; data-alt=&quot;터미널에서 Pixel_3a_API_33_arm64-v8a 에뮬레이터 실행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgadIt/btrNwnPdqC5/LToUhq4u3k9yZxi4hcVXOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgadIt%2FbtrNwnPdqC5%2FLToUhq4u3k9yZxi4hcVXOk%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;2004&quot; height=&quot;1386&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.37.49.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;터미널에서 Pixel_3a_API_33_arm64-v8a 에뮬레이터 실행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.40.33.png&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDAuFz/btrNAyPwZGI/r7tag1a4ZSuZ3ZkLYNg2ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDAuFz/btrNAyPwZGI/r7tag1a4ZSuZ3ZkLYNg2ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDAuFz/btrNAyPwZGI/r7tag1a4ZSuZ3ZkLYNg2ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDAuFz%2FbtrNAyPwZGI%2Fr7tag1a4ZSuZ3ZkLYNg2ak%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;1722&quot; height=&quot;1118&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.40.33.png&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Android Studio에서 플러터 앱 프로젝트 만들기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Flutter와 Dart 플러그인 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Studio를 실행한 직후에 New Flutter Project 아이콘이 안 보인다면, Android Studio용 플러터와 다트 플러그인 먼저 설치해 줍니다. Plugins에서 flutter를 검색해서 플러그인을 설치하는데 도중에 나오는 Dart 플러그인도 함께 설치합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.13.01.png&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;1336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2mU2a/btrNB6d2JcA/sTxb4puG4ylFQdGgY75xcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2mU2a/btrNB6d2JcA/sTxb4puG4ylFQdGgY75xcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2mU2a/btrNB6d2JcA/sTxb4puG4ylFQdGgY75xcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2mU2a%2FbtrNB6d2JcA%2FsTxb4puG4ylFQdGgY75xcK%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;1736&quot; height=&quot;1336&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.13.01.png&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;1336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인 설치 후에는 메뉴에 아래와 같이 New Flutter Project 아이콘과 문구가 보이게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.13.41.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxBVCg/btrNyGNWp4g/hEjiznPw6GhjCkGDu1DQC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxBVCg/btrNyGNWp4g/hEjiznPw6GhjCkGDu1DQC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxBVCg/btrNyGNWp4g/hEjiznPw6GhjCkGDu1DQC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxBVCg%2FbtrNyGNWp4g%2FhEjiznPw6GhjCkGDu1DQC1%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;1824&quot; height=&quot;1424&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.13.41.png&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;1424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;New Flutter Project 클릭 시, Flutter SDK 경로를 확인하고 앱 이름을 설정하면 플러터 앱이 생성됩니다. Platforms에 디폴트로 Android와 iOS가 선택되어 있기 때문에, 별도로 수정할 필요가 없습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.56.41.png&quot; data-origin-width=&quot;1502&quot; data-origin-height=&quot;1504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVu0fj/btrNxexkLcy/TkdKQqCasIqvbzSdGgEczk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVu0fj/btrNxexkLcy/TkdKQqCasIqvbzSdGgEczk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVu0fj/btrNxexkLcy/TkdKQqCasIqvbzSdGgEczk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVu0fj%2FbtrNxexkLcy%2FTkdKQqCasIqvbzSdGgEczk%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;1502&quot; height=&quot;1504&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.56.41.png&quot; data-origin-width=&quot;1502&quot; data-origin-height=&quot;1504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.56.57.png&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by5x2V/btrNGwiT06N/Zd0faFxzwKtae69pjYExhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by5x2V/btrNGwiT06N/Zd0faFxzwKtae69pjYExhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by5x2V/btrNGwiT06N/Zd0faFxzwKtae69pjYExhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby5x2V%2FbtrNGwiT06N%2FZd0faFxzwKtae69pjYExhk%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;1670&quot; height=&quot;1592&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.56.57.png&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Android Studio에서 플러터 앱 실행시키기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.56.32.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNjrDK/btrNtiNunjb/fIsEmLRT7qxcoTppibpJDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNjrDK/btrNtiNunjb/fIsEmLRT7qxcoTppibpJDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNjrDK/btrNtiNunjb/fIsEmLRT7qxcoTppibpJDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNjrDK%2FbtrNtiNunjb%2FfIsEmLRT7qxcoTppibpJDk%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;821&quot; height=&quot;143&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.56.32.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 앱 프로젝트 실행 후 iOS Simuator나 Android Emulator가 돌고 있지 않다면 상단 device 선택 메뉴에서 실행시켜주면 됩니다. 먼저 iOS Simulator를 오픈한 뒤 초록색 Run 버튼을 눌러보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.54.18.png&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;915&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A7wJg/btrNILmFYFA/oIDKUCy5v50Y9kAfYZuiMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A7wJg/btrNILmFYFA/oIDKUCy5v50Y9kAfYZuiMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A7wJg/btrNILmFYFA/oIDKUCy5v50Y9kAfYZuiMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA7wJg%2FbtrNILmFYFA%2FoIDKUCy5v50Y9kAfYZuiMk%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;1594&quot; height=&quot;915&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.54.18.png&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;915&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Emulator도 마찬가지 방법으로 device를 실행시킨다음 Run 버튼을 누르면 잘 동작합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.59.26.png&quot; data-origin-width=&quot;1694&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mLgQs/btrNAMfQUG2/qXsaSqPLM6o7Lckhzplqq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mLgQs/btrNAMfQUG2/qXsaSqPLM6o7Lckhzplqq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mLgQs/btrNAMfQUG2/qXsaSqPLM6o7Lckhzplqq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmLgQs%2FbtrNAMfQUG2%2FqXsaSqPLM6o7Lckhzplqq1%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;1694&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2022-10-03 오후 2.59.26.png&quot; data-origin-width=&quot;1694&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터 앱 프로젝트는 기본적으로 설치만 되면 데모 앱이 돌아가도록 구성되어 있기 때문에, 필요한 설치 파일 설치 후 가상 디바이스 설정만 잘 한다면 실제 기기가 없어도 문제없이 실행됩니다.&lt;/p&gt;</description>
      <category>Flutter</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/7</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-2-%ED%84%B0%EB%AF%B8%EB%84%90%EA%B3%BC-Android-Studio%EC%97%90%EC%84%9C-%EB%8D%B0%EB%AA%A8-%EC%95%B1-%EB%8F%8C%EB%A0%A4%EB%B3%B4%EA%B8%B0#entry7comment</comments>
      <pubDate>Mon, 3 Oct 2022 15:08:51 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 개발 환경 구축 1 - SDK 설치와 환경변수 설정</title>
      <link>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-01 오후 12.48.19.png&quot; data-origin-width=&quot;2180&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uYswJ/btrNzKg16E3/YFsiQhgJ7C44sNu9O2sFKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uYswJ/btrNzKg16E3/YFsiQhgJ7C44sNu9O2sFKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uYswJ/btrNzKg16E3/YFsiQhgJ7C44sNu9O2sFKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuYswJ%2FbtrNzKg16E3%2FYFsiQhgJ7C44sNu9O2sFKk%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;2180&quot; height=&quot;558&quot; data-filename=&quot;스크린샷 2022-10-01 오후 12.48.19.png&quot; data-origin-width=&quot;2180&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터로 개발을 시작할 때 가장 기본적인 단계 세 가지는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;IDE로&amp;nbsp;Android Studio 설치, 플러터 언어를 쓰기 위한 Flutter SDK 설치, 환경변수 설정&lt;/span&gt;입니다. 최종적으로는 flutter doctor를 실행해 빠진 부분이 있는지 점검할 수도 있습니다. 차근차근 첫 단계부터 진행해보도록 합시다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Android Studio 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 상에서 &lt;a href=&quot;https://developer.android.com/studio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.android.com/studio&lt;/a&gt;에 접속해&amp;nbsp;Download Android Studio 버튼을 클릭해 설치 파일을 다운로드하여 설치를 진행합니다. Android Studio 대안으로 VS Code도 있지만, 구글이 플러터를 지원하는 만큼, Android Studio를 사용하는 편이 개발 과정에서 사소하지만 생산성에 영향을 주는 요소들을 피해 가기 위해 좋다고 생각합니다. 안드로이드 에뮬레이터를 쓸 수도 있고, 그 밖에도 Android Studio가 플러터 개발에 필요한 최적화가 잘 되어 있겠죠?&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flutter SDK 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter SDK 역시 브라우저 상에서 설치 파일을 받아 설치를 진행합니다. &lt;a href=&quot;https://docs.flutter.dev/get-started/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.flutter.dev/get-started/install&lt;/a&gt;에 접속하면 Windows, macOS, Linux, Chrome OS 4가지 OS 이미지 버튼이 보입니다. 플러터 개발을 진행할 OS에 맞게 아이콘을 클릭하고 설치를 진행합니다. macOS 사용자 중 M1 맥북을 쓴다면 Apple Sillicon 링크의 설치 파일을 클릭하면 됩니다. 단, M1 환경에서는 &lt;a href=&quot;https://docs.flutter.dev/get-started/install/macos&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.flutter.dev/get-started/install/macos&lt;/a&gt; 에서 얘기하는대로 터미널 상에서 Rosetta 환경을 먼저 설치해줍니다. Rosetta를 설치하는 이유는, 플러터 라이브러리 중 아직까지 M1 칩을 완벽하게 지원하지 않고 인텔 칩에서만 돌아가는 라이브러리들이 있기 때문입니다. 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;sudo softwareupdate --install-rosetta --agree-to-license&lt;/span&gt;&lt;/b&gt;를 입력합니다. 그 후에 홈 위치인 ~에서 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;mkdir development;&lt;/b&gt; &lt;b&gt;cd development; unzip ~/Downloads/flutter_macos_arm64_3.3.3-stable.zip&lt;/b&gt;&lt;/span&gt; 커맨드를 실행해줍니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;환경변수 설정 (Flutter SDK, Android Studio)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오와 플러터를 현재 설치된 경로 외에 다른 경로에서도 사용하려면 환경변수 등록이 필수입니다. 기본적으로 Android Studio SDK와 Flutter SDK가 설치된 위치를 찾고, 그 위치를 다른 경로에서도 파악할 수 있게 환경변수에 path로 등록해줍니다. Android Studio는 SDK 경로를 가리키는 SDK 변수 설정 후 SDK에 속한 emulator, tools, tools의 bin, platform-tools (adb용) 4가지 경로를 설정해주고, Flutter SDK는 Flutter SDK 경로 하나를 잡아줍니다. Android Studio의 경우, 등록해야할 경로가 많고 길기 때문에 먼저 Android SDK 경로를 ANDROID_SDK라는 변수에 저장하게 되는데요, 차근차근 진행해봅시다. (참고로 ANDROID-SDK, AND-SDK등 변수명은 본인의 마음에 드는 걸로 사용하면 됩니다.)&lt;span style=&quot;color: #000000; font-size: 1.44em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;윈도우&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Android Studio SDK 환경변수 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 Android Studio SDK 설치 경로는 대개 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;C:\Users\[Username]\AppData\Local\Android\Sdk&lt;/span&gt; 일겁니다. (이 경로는 Android Studio를 실행한 후 Settings 메뉴에서도 확인할 수 있습니다.) Android Studio SDK 경로 확인 후 UI를 통해 환경변수를 설정해 줍시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. 윈도우 검색창에 환경변수를 검색해서 나오는 시스템 환경 변수 편집을 실행시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. 시스템 속성 창이 뜨면, 고급 탭 하단의 환경 변수 버튼을 눌러 환경 변수 창으로 들어갑니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;3. 시스템 변수에 등록해도 상관없지만 일반적으로 로그인한 사용자에게 환경 변수를 설정해주면 되는데요,&lt;span&gt; 사용자 변수 섹션에서&lt;/span&gt;&lt;/span&gt; 새로 만들기 버튼을 클릭해 변수 이름에 ANDROID_SDK, 변수값에 SDK 경로를 넣어준 뒤 확인 버튼을 누릅니다. 이후 PATH에서 사용할 환경 변수를 새로 만들어준거죠. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;4. PATH 선택 후 편집 버튼을 클릭합니다. 그리고 새로 만들기를 클릭해 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;%ANDROID_SDK%\emulator&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;%ANDROID_SDK%\tools&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;%ANDROID_SDK%\tools\bin&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;%ANDROID_SDK%\platform-tools&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;를 입력한 뒤 확인 버튼을 클릭해줍니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Flutter SDK 환경변수 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.flutter.dev/get-started/install/windows&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; https://docs.flutter.dev/get-started/install/windows&lt;/a&gt;에 기술된 대로 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;where flutter dart&lt;/span&gt; &lt;/b&gt;명령어를 써서 Flutter SDK 위치를 찾아줍니다. 정확히는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;C:\dev\src\flutter\bin\..&lt;/span&gt;와 같은 형식으로 출력되는 경로에서 실행 파일인 bin 경로까지 확인하시면 됩니다. 이제 Android Studio와 마찬가지로 환경변수를 설정할 차례입니다. 사용자 변수에서 Path 변수에 조금 전에 확인한 Flutter SDK bin 파일 경로를 입력해줍니다. 터미널 창에 출력된 C:\부터 bin까지 경로를 복사해 붙여넣기 한 뒤 확인 버튼을 클릭해 환경변수에 반영해줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;맥OS&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Android Studio SDK 환경변수 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥에서 Android Studio SDK 설치 경로는 대개 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;/Users/[Username]/Library/Android/SDK&lt;/span&gt; 입니다. &lt;span&gt;그다음 환경변수 파일을 열어 경로를 설정해주면 되는데요, 터미널에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;open ~/.zprofile&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 실행해 텍스트 편집기에서 파일을 열고 경로를 입력해줍니다. 혹시 .zprofile 파일을 찾지 못한다면, 터미널에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;echo $SHELL&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;입력 후 자신의 터미널이 어떤 쉘 기반인지 먼저 확인후 .zshrc 등 다른 환경 변수 파일을 입력하면 됩니다.&lt;span&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;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;#&amp;nbsp;Android&amp;nbsp;Studio&lt;br /&gt;export&amp;nbsp;ANDROID_SDK=$HOME/Library/Android/sdk&lt;br /&gt;export&amp;nbsp;PATH=$PATH:$ANDROID_SDK/emulator&amp;nbsp;&lt;br /&gt;export&amp;nbsp;PATH=$PATH:$ANDROID_SDK/tools&lt;br /&gt;export&amp;nbsp;PATH=$PATH:$ANDROID_SDK/tools/bin&lt;br /&gt;export&amp;nbsp;PATH=$PATH:$ANDROID_SDK/platform-tools&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Flutter SDK 환경변수 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥의 경우 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;which flutter&lt;/span&gt;&lt;/b&gt;를 치시면 Flutter SDK 설치 경로를 확인할 수 있습니다. /User부터 /bin으로 끝나는 경로를 확인해 둡니다. 플러터 경로를 넣어줄 때는 export PATH=&quot;$PATH: 뒤에 아까 찾은 flutter 경로를 넣어주면 됩니다. 예를 들어 현재 로그인한 유저 이름이 codeflow이고 ~/development 위치에 Flutter SDK를 설치했다고 가정해보겠습니다. 이 경우 which flutter를 쳤을 때 출력되는 위치 경로가 /Users/codeflow/development/flutter/bin이기 때문에 .zprofile에 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;export PATH=&quot;$PATH:/Users/codeflow/development/flutter/bin&quot;&lt;/span&gt;&lt;/b&gt;라고 위치에 상관없이 한 줄 입력해주면 됩니다. 현재까지 설정된 PATH 변수의 값에 이어서 경로를 잡아준다는 의미이죠. 아니면&amp;nbsp; 아예 사용자 이름을 $HOME으로 대체하고 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;export PATH=&quot;$PATH:$HOME/development/flutter/bin&quot;&lt;/span&gt;&lt;/b&gt;로 입력해도 됩니다. 참고로 파일을 저장한 뒤 경로가 잘 입력되었나 보려면, 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;echo $PATH &lt;/span&gt;&lt;/b&gt;명령어를 입력해 확인하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.30.36.png&quot; data-origin-width=&quot;2114&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYoyC8/btrNwFWjm9X/gNmtmS1qJ7ubR5WKzr07V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYoyC8/btrNwFWjm9X/gNmtmS1qJ7ubR5WKzr07V1/img.png&quot; data-alt=&quot;Android Studio와 Flutter 경로를 PATH에 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYoyC8/btrNwFWjm9X/gNmtmS1qJ7ubR5WKzr07V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYoyC8%2FbtrNwFWjm9X%2FgNmtmS1qJ7ubR5WKzr07V1%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;2114&quot; height=&quot;724&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.30.36.png&quot; data-origin-width=&quot;2114&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Android Studio와 Flutter 경로를 PATH에 추가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.33.17.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wRrHx/btrNwD5aw7H/tWxGsH1hbqrWQr2If0jI81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wRrHx/btrNwD5aw7H/tWxGsH1hbqrWQr2If0jI81/img.png&quot; data-alt=&quot;Flutter 경로, 버전과 PATH 설정 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wRrHx/btrNwD5aw7H/tWxGsH1hbqrWQr2If0jI81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwRrHx%2FbtrNwD5aw7H%2FtWxGsH1hbqrWQr2If0jI81%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;2004&quot; height=&quot;836&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.33.17.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Flutter 경로, 버전과 PATH 설정 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Flutter Doctor&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 설정을 마친 후에는 터미널에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter doctor&lt;/span&gt;&lt;/b&gt;를 입력해봅시다. 그러면 설치 상태에 따라서 권장 사항인데 설치가 안된 항목들을 설치해주는데요, 가능한 지적하는 사항이 없도록 지시하는 내용을 따라 추가적으로 필요한 패키지들을 설치해줍시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.35.52.png&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;1052&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eE2IJ0/btrNxa2JvMq/yK6ochuZVUNf777YWNUdUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eE2IJ0/btrNxa2JvMq/yK6ochuZVUNf777YWNUdUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eE2IJ0/btrNxa2JvMq/yK6ochuZVUNf777YWNUdUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeE2IJ0%2FbtrNxa2JvMq%2FyK6ochuZVUNf777YWNUdUk%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;2148&quot; height=&quot;1052&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.35.52.png&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;1052&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 실행했을 때는 Android SDK에서 cmdline-tools를 추가하라는 메시지가 나왔습니다. Android Studio가 설치되어 있는 상태이기 때문에 Android Studio를 실행해서 커맨드라인 툴을 추가로 설치해 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.45.41.png&quot; data-origin-width=&quot;2100&quot; data-origin-height=&quot;1552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KCOEZ/btrNw93PXpv/ftxBwgUqyoN4hAdrcDXDPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KCOEZ/btrNw93PXpv/ftxBwgUqyoN4hAdrcDXDPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KCOEZ/btrNw93PXpv/ftxBwgUqyoN4hAdrcDXDPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKCOEZ%2FbtrNw93PXpv%2FftxBwgUqyoN4hAdrcDXDPK%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;2100&quot; height=&quot;1552&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.45.41.png&quot; data-origin-width=&quot;2100&quot; data-origin-height=&quot;1552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;남은 워닝을 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;flutter doctor --android-licenses&lt;/span&gt;&lt;/b&gt; 커맨드를 실행해 없애주고 다시 flutter doctor를 실행시키면 모두 체크 상태로 표시되는 걸 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.48.56.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdL3VJ/btrNxaIpJ8p/PxWWLKvHhhVAhRsUQkTZH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdL3VJ/btrNxaIpJ8p/PxWWLKvHhhVAhRsUQkTZH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdL3VJ/btrNxaIpJ8p/PxWWLKvHhhVAhRsUQkTZH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdL3VJ%2FbtrNxaIpJ8p%2FPxWWLKvHhhVAhRsUQkTZH1%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;2004&quot; height=&quot;800&quot; data-filename=&quot;스크린샷 2022-10-03 오전 11.48.56.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 모든 설정이 끝나고 flutter에 대한 가장 기본적인 설정은 끝난 상태가 됩니다!&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>Flutter</category>
      <category>flutter sdk</category>
      <category>플러터</category>
      <category>플러터 설정</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/3</guid>
      <comments>https://codeflow.tistory.com/entry/%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95#entry3comment</comments>
      <pubDate>Mon, 3 Oct 2022 09:12:27 +0900</pubDate>
    </item>
    <item>
      <title>맥북 터미널 설정 2 - iTerm2 추가 기능</title>
      <link>https://codeflow.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A7%A5%EB%B6%81-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%84%A4%EC%A0%95-2-iTerm2-%EC%B6%94%EA%B0%80-%EA%B8%B0%EB%8A%A5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;iTerm2가 제공하는 기능은 굉장히 다양합니다. 그 중 유용한 기능 몇 가지를 더 살펴보려고 합니다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;iTerm2 창 타이틀을 커스터마이징 하는 방법, 프롬프트에 사용자 이름을 보여주는 방법, 상태바를 통해 CPU나 메모리 상태를 표시하는 방법, 터미널에서 이미지 파일을 바로 출력하는 방법&lt;/span&gt;을 알아봅시다.&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;iTerm2 창 타이틀 커스터마이징&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iTerm2 윈도우나 탭에서 타이틀을 원하는 대로 변경하기 위해서는, 먼저 .zshrc 파일을 열어 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;DISABLE_AUTO_TITLE=&quot;true&quot;&lt;/span&gt;&lt;/b&gt;에 적용된 주석 처리를 제거해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 7.38.52.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z0r6o/btrNAN6HWYk/wu822r576IbG3aEHSkWNF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z0r6o/btrNAN6HWYk/wu822r576IbG3aEHSkWNF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z0r6o/btrNAN6HWYk/wu822r576IbG3aEHSkWNF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ0r6o%2FbtrNAN6HWYk%2Fwu822r576IbG3aEHSkWNF0%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;1588&quot; height=&quot;436&quot; data-filename=&quot;스크린샷 2022-10-03 오전 7.38.52.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 iTerm2 Preferences를 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;command ⌘ &lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;+ , &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단축키로 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;열고 Profiles&amp;gt; General 탭 Title에서 원하는 형식의 타이틀이 나오도록 설정합니다. 저는 기존 Default는 따로 카피한 뒤 삭제하고, codeflow라는 profile을 새로 생성해 적용해 주었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.58.47.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lRuhg/btrNwkxRJfI/bcz1GBq14ZawB44nEg1usk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lRuhg/btrNwkxRJfI/bcz1GBq14ZawB44nEg1usk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lRuhg/btrNwkxRJfI/bcz1GBq14ZawB44nEg1usk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlRuhg%2FbtrNwkxRJfI%2Fbcz1GBq14ZawB44nEg1usk%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;2060&quot; height=&quot;1464&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.58.47.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래와 같이 iTerm2 윈도우 타이틀에서 기존 사용자 이름은 사라지고 Preferences에 설정한 타이틀 형식대로 타이틀이 보이는 모습을 볼 수 있습니다. &lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.09.06.png&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUcBpF/btrNAwRwfeP/DuXegy65UISXyztoY3hGsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUcBpF/btrNAwRwfeP/DuXegy65UISXyztoY3hGsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUcBpF/btrNAwRwfeP/DuXegy65UISXyztoY3hGsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUcBpF%2FbtrNAwRwfeP%2FDuXegy65UISXyztoY3hGsk%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;1436&quot; height=&quot;346&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.09.06.png&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&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;프롬프트에 사용자 이름이나 다른 메시지를 넣어주고 싶다면 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;prompot_context()&lt;/span&gt; 함수를 써서 적용할 수 있습니다. .zshrc 파일을 열어서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;prompt_context() { prompt_segment [색상] default &quot;[출력할 메시지]&quot;] }&lt;/span&gt; &lt;/b&gt;단락을 넣어줍시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.11.35.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CpDOX/btrNAyu2uUb/eTvVleEoGkDJPow2GZIME1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CpDOX/btrNAyu2uUb/eTvVleEoGkDJPow2GZIME1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CpDOX/btrNAyu2uUb/eTvVleEoGkDJPow2GZIME1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCpDOX%2FbtrNAyu2uUb%2FeTvVleEoGkDJPow2GZIME1%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;1588&quot; height=&quot;422&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.11.35.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커맨드라인 상에서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;source ~/.zshrc&lt;/span&gt;&lt;/b&gt;을 치거나 터미널을 새로 열어서 적용이 잘 됐는지 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.11.00.png&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7xfPk/btrNAxbOPei/uSGfzk3k9KBvXyvkkRNQE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7xfPk/btrNAxbOPei/uSGfzk3k9KBvXyvkkRNQE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7xfPk/btrNAxbOPei/uSGfzk3k9KBvXyvkkRNQE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7xfPk%2FbtrNAxbOPei%2FuSGfzk3k9KBvXyvkkRNQE0%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;1876&quot; height=&quot;398&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.11.00.png&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;/figure&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;iTerm2에서는 상태바(Status Bar)를 통해 현재 배터리와 CPU, 메모리, 네트워크 처리량 상태 및 시계 등을 보여주는 기능도 제공합니다. 상태바를 설정하기 위해서는 먼저 Profiles&amp;gt; Preferences에서 'Status bar enabled'를 체크해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.15.45.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0zJAD/btrNtiNh6r1/biKLlQ18kGooaIH5lKVnkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0zJAD/btrNtiNh6r1/biKLlQ18kGooaIH5lKVnkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0zJAD/btrNtiNh6r1/biKLlQ18kGooaIH5lKVnkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0zJAD%2FbtrNtiNh6r1%2FbiKLlQ18kGooaIH5lKVnkK%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;2060&quot; height=&quot;1382&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.15.45.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 Status Bar Component Menu가 뜨는데요, 여기서 상태바에 출력되기 원하는 메뉴를 골라 하단 Active Components에 넣어줍니다. 저는 CPU, 메모리, 네트워크와 시계만 추가해볼게요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.17.33.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/esxgm4/btrNwkLtAm4/pTXECl0QfYLHtu4wRHV6h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/esxgm4/btrNwkLtAm4/pTXECl0QfYLHtu4wRHV6h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/esxgm4/btrNwkLtAm4/pTXECl0QfYLHtu4wRHV6h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fesxgm4%2FbtrNwkLtAm4%2FpTXECl0QfYLHtu4wRHV6h1%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;2060&quot; height=&quot;1422&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.17.33.png&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;1422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OK 버튼을 누르고 터미널을 보면 'Click here to configure status bar'라는 문구를 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.16.56.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by8Xu3/btrNEwwBKj1/YfBY19hgfiRCv3eKjeGz2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by8Xu3/btrNEwwBKj1/YfBY19hgfiRCv3eKjeGz2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by8Xu3/btrNEwwBKj1/YfBY19hgfiRCv3eKjeGz2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby8Xu3%2FbtrNEwwBKj1%2FYfBY19hgfiRCv3eKjeGz2K%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;2004&quot; height=&quot;440&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.16.56.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클릭하면 아래처럼 상태바에서 설정한 메뉴들이 보이게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.21.54.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uXIXK/btrNGwpAcCL/Aqts2gskk63T9ejbVeYfs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uXIXK/btrNGwpAcCL/Aqts2gskk63T9ejbVeYfs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uXIXK/btrNGwpAcCL/Aqts2gskk63T9ejbVeYfs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuXIXK%2FbtrNGwpAcCL%2FAqts2gskk63T9ejbVeYfs0%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;2004&quot; height=&quot;476&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.21.54.png&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 상태바는 터미널 하단에 두어야 필요할 때만 보기 좋겠죠? 상태바 위치를 바꾸려면 Appearance&amp;gt; General 탭에서 Status bar location을 Bottom으로 바꿔줍니다. 변경하는 순간 상태바는 터미널 하단에 위치하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.22.28.png&quot; data-origin-width=&quot;1572&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SaGMN/btrNzKvCNNu/kt8pLKm75GS4ffkV9crKk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SaGMN/btrNzKvCNNu/kt8pLKm75GS4ffkV9crKk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SaGMN/btrNzKvCNNu/kt8pLKm75GS4ffkV9crKk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSaGMN%2FbtrNzKvCNNu%2Fkt8pLKm75GS4ffkV9crKk1%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;1572&quot; height=&quot;826&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.22.28.png&quot; data-origin-width=&quot;1572&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;iTerm2에서 이미지 바로보기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iTerm2에서 한 가지 더 유용한 꿀팁은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;imgcat&lt;/span&gt; 으로 이미지를 바로 보는 기능을 사용하는 방법입니다. &lt;a href=&quot;https://iterm2.com/documentation-images.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://iterm2.com/documentation-images.html&lt;/a&gt;에서 이 기능을 소개하고 있는데요, 커맨드라인에 imgcat 명령어를 치면 현재 터미널 상에서 이미지를 바로 볼 수 있게 해 줍니다. 마치 cat 명령어로 파일 안 텍스트를 터미널에 출력하듯이 이미지도 터미널에 출력할 수 있게 해 주는 거죠. 프로젝트에 저장해 둔 이미지 파일 상태가 궁금할 때 유용하게 쓸 수 있답니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.27.44.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DjLUp/btrNyEPXUhC/yUH8tfG2TgtVhwKqaKxQ6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DjLUp/btrNyEPXUhC/yUH8tfG2TgtVhwKqaKxQ6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DjLUp/btrNyEPXUhC/yUH8tfG2TgtVhwKqaKxQ6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDjLUp%2FbtrNyEPXUhC%2FyUH8tfG2TgtVhwKqaKxQ6K%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;1796&quot; height=&quot;764&quot; data-filename=&quot;스크린샷 2022-10-03 오전 8.27.44.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>ProTips</category>
      <category>iterm2 상태바</category>
      <category>iterm2 유저 이름 표시</category>
      <category>iterm2 이미지</category>
      <category>iterm2 제목 변경</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/6</guid>
      <comments>https://codeflow.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A7%A5%EB%B6%81-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%84%A4%EC%A0%95-2-iTerm2-%EC%B6%94%EA%B0%80-%EA%B8%B0%EB%8A%A5#entry6comment</comments>
      <pubDate>Mon, 3 Oct 2022 09:11:24 +0900</pubDate>
    </item>
    <item>
      <title>맥북 터미널 설정 1 - iTerm2와 oh my zsh 설치하기</title>
      <link>https://codeflow.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A7%A5%EB%B6%81-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%84%A4%EC%A0%95-iTerm%EA%B3%BC-oh-my-zsh-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;맥OS 터미널을 좀 더 예쁘고 깔끔하게 싶다면 보통 터미널로 다양한 확장 기능을 제공하는 iTerm을 쓰게 됩니다. iTerm 설치 후에는 보통 터미널에 oh my zsh 프레임워크를 적용합니다. oh my zsh 프레임워크와 플러그인에서 제공하는 git 연동, 커맨드 자동 추천, 커맨드 인식 여부를 색깔로 표시하기 등의 기능을 써서 편리하게 개발할 수 있기 때문입니다. 이번 포스팅에서는 iTerm만 설치한 상태에서 git 저장소를 다운받았을 때의 상태와 oh my zsh를 적용한 후 git 저장소를 다운받았을 때의 상태를 비교해보겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;iTerm2 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 할 일은 iTerm2 설정입니다. iTerm2는 &lt;a href=&quot;https://iterm2.com/downloads.html&quot;&gt;https://iterm2.com/downloads.html&lt;/a&gt;에서&amp;nbsp;다운로드 받고 실행하면 됩니다. iTerm2를 다운로드한 직후에 곧 설치할 ohmyzsh git 저장소를 클로닝 해보겠습니다. 아직은 아래 이미지와 같이 맥OS 기본 터미널과 딱히 다를 게 없어 보입니다. 이제 oh my zsh를 적용해 밋밋한 터미널에 컬러를 입혀보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 9.43.47.png&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qpahO/btrNwDKHQD0/lBNkBDd10sLM2LZSpr26tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qpahO/btrNwDKHQD0/lBNkBDd10sLM2LZSpr26tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qpahO/btrNwDKHQD0/lBNkBDd10sLM2LZSpr26tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqpahO%2FbtrNwDKHQD0%2FlBNkBDd10sLM2LZSpr26tk%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;838&quot; height=&quot;221&quot; data-filename=&quot;스크린샷 2022-10-02 오후 9.43.47.png&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;oh my zsh 설치 및 theme 변경&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxZUBC/btrNtiNcAut/ZemRGS4k7BY0U8MFKmzCBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxZUBC/btrNtiNcAut/ZemRGS4k7BY0U8MFKmzCBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxZUBC/btrNtiNcAut/ZemRGS4k7BY0U8MFKmzCBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxZUBC%2FbtrNtiNcAut%2FZemRGS4k7BY0U8MFKmzCBk%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;1280&quot; height=&quot;611&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oh-my-zsh 설치를 설치하기 위해서는 먼저 iTerm2를 켜두고 &lt;a href=&quot;https://ohmyz.sh/&quot;&gt;https://ohmyz.sh/&lt;/a&gt;에 들어갑니다. 화면에 보이는 Install oh-my-zsh 버튼을 누르고 연결된 링크에서 sh로 시작하는 curl 커맨드를 카피한 뒤 터미널에 붙여넣고 엔터를 쳐줍니다.&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Note.&lt;/b&gt;&lt;span style=&quot;background-color: #fafafa;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;curl이란 client URL의 약자로, CLI(Comman Line Interface) 환경에서 http, https 프로토콜을 통해 서버에 접속할 수 있게 해줍니다. 개발자라면 postman 없이도 curl을 통해 서버 API를 테스트할 수 있습니다. 위의 경우엔 별도로 브라우저에서 파일을 다운로드 받고 설치하는 과정 없이 터미널 환경에서 ohmyzsh 서버에 접속해 oh-my-zsh 플러그인 데이터를 받아 설치할 수 있게 해 줍니다. -s는 silent 모드로 에러 출력 방지 옵션, -S는 silent 모드일 때도 에러 출력, -L은 redirection을 가능하게 하는 옵션입니다. curl이 설치되어 있지 않은 경우엔 터미널에 brew install curl을 입력해 설치할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.19.00.png&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pVD3Z/btrNv0sSvH3/vjojhTlUGEShiOZROS3kOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pVD3Z/btrNv0sSvH3/vjojhTlUGEShiOZROS3kOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pVD3Z/btrNv0sSvH3/vjojhTlUGEShiOZROS3kOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpVD3Z%2FbtrNv0sSvH3%2FvjojhTlUGEShiOZROS3kOk%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;889&quot; height=&quot;614&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.19.00.png&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oh my zsh가 무사히 설치되면 터미널 프롬프트에 컬러가 적용되게 됩니다. 아래 이미지처럼 ohmyzsh git 위치로 이동하면 프롬프트에 git branch 정보가 표시되는 걸 확인할 수 있습니다.&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.49.29.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btDB3C/btrNAyPfNzK/wYHQ9JmpA500yiK7zCGst0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btDB3C/btrNAyPfNzK/wYHQ9JmpA500yiK7zCGst0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btDB3C/btrNAyPfNzK/wYHQ9JmpA500yiK7zCGst0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtDB3C%2FbtrNAyPfNzK%2FwYHQ9JmpA500yiK7zCGst0%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;764&quot; height=&quot;98&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.49.29.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;색상이 반전된 상태로 표시하기 위해서는 oh my zsh의 color theme을 바꿔줄 필요가 있는데요, 그 전에 iTerm 자체에서 색상을 바꾸는 방법을 먼저 알아보겠습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;iTerm2에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;command ⌘&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ ,&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;키를 누르면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Preferences&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;창을 띄워줍니다. 여기서 Profiles를 선택해 colors 탭에서 Color Presets를 Tango Dark로 바꿔보겠습니다. 그러면 아래와 같이 색상이 약간 변한 걸 확인할 수 있는데요, iTerm2 color scheme (&lt;a href=&quot;https://iterm2colorschemes.com/&quot;&gt;https://iterm2colorschemes.com/&lt;/a&gt;)을 쓰면 좀 더 다양한 색상 테마를 적용해 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.55.23.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgmuq6/btrNyGtrmNO/I51MycA8eKrkaKGiD7AtV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgmuq6/btrNyGtrmNO/I51MycA8eKrkaKGiD7AtV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgmuq6/btrNyGtrmNO/I51MycA8eKrkaKGiD7AtV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgmuq6%2FbtrNyGtrmNO%2FI51MycA8eKrkaKGiD7AtV1%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;1032&quot; height=&quot;773&quot; data-filename=&quot;스크린샷 2022-10-02 오후 10.55.23.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;이제 oh my zsh theme을 먼저 적용해 프롬프트 텍스트에 색상 반전 효과를 입혀보도록 하겠습니다. 보통 이 효과를 적용하기 위해서 oh my zsh 설정에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#agnoster&quot;&gt;https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#agnoster&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;처럼 theme으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000; background-color: #9feec3;&quot;&gt;agnoster&lt;/span&gt;를 적용시킵니다. 그러기 위해 먼저 아래 이미지 대로 터미널에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;open ~/.zshrc&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;커맨드를 쳐서 .zshrc 파일을 열어 봅시다. 그러면 oh my zsh 설치 시에 생성된 각종 설정들을 확인할 수 있습니다.&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;우리는 그 중 ZSH_THEME 변수를 찾아&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3; color: #000000;&quot;&gt;agnoster&lt;/span&gt;로 바꿔주도록 하겠습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ZSH_THEME=&quot;agnoster&quot;&lt;/span&gt;&lt;/b&gt;로 바꾼 후 저장해줍시다. 그런 다음 터미널에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;source ~/.zshrc&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;명령어로 .zshrc 변경사항을 적용해주거나 iTerm2를 다시 실행해주면, 아래와 같이 git branch 텍스트에 색상 배경이 들어간 걸 확인할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.09.46.png&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JggaU/btrNDVXrWzy/tihYoCRXapr0PrNOE9ixb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JggaU/btrNDVXrWzy/tihYoCRXapr0PrNOE9ixb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JggaU/btrNDVXrWzy/tihYoCRXapr0PrNOE9ixb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJggaU%2FbtrNDVXrWzy%2FtihYoCRXapr0PrNOE9ixb0%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;851&quot; height=&quot;349&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.09.46.png&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;349&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;터미널 폰트 변경하기&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.19.33.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI4NKW/btrNDU5jAWU/D8f1VknfoTAFdqhxho6rK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI4NKW/btrNDU5jAWU/D8f1VknfoTAFdqhxho6rK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI4NKW/btrNDU5jAWU/D8f1VknfoTAFdqhxho6rK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI4NKW%2FbtrNDU5jAWU%2FD8f1VknfoTAFdqhxho6rK0%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;890&quot; height=&quot;321&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.19.33.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oh my zsh theme을 agnoster로 적용하면 폰트가 깨지기 때문에, 호환이 되는 폰트를 설치해보겠습니다. 보통 개발용으로 많이 쓰이는 D2 폰트를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/naver/d2codingfont/releases&quot;&gt;h&lt;/a&gt;&lt;a href=&quot;https://github.com/naver/d2codingfont/releases&quot;&gt;ttps://github.com/naver/d2codingfont/releases&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에서 다운로드 받아 서체를 설치해 줍니다. 그 다음 iTerm2 Preferences에서 D2Coding 폰트를 적용하고 글자 크기를 약간 키워주면 아래 이미지와 같이 더 이상 폰트가 깨지지 않고 잘 나오는 모습을 볼 수 있습니다.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.21.11.png&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHHHS1/btrNyFH5uoH/3CcQMKGPC5PZPK9FAJ450K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHHHS1/btrNyFH5uoH/3CcQMKGPC5PZPK9FAJ450K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHHHS1/btrNyFH5uoH/3CcQMKGPC5PZPK9FAJ450K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHHHS1%2FbtrNyFH5uoH%2F3CcQMKGPC5PZPK9FAJ450K%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;941&quot; height=&quot;541&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.21.11.png&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프롬프트에서 사용자 이름 없애기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git을 쓰면서 branch 이름이 길어지면 사용자 이름과 섞여 너무 길어지기 때문에 터미널에서 보기 불편할 수 있습니다. 이런 경우에는 사용자 이름이 프롬프트에 표시되지 않도록 아래와 같이 .zprofile을 생성해 DEFAULT_USER 변수에 현재 사용자 이름을 대입합니다. 파일 저장 후에 사용자 이름이 사라진 걸 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.30.12.png&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rs8PO/btrNxdE3CiX/8a5wTsdEKcCvmIN4zVxUKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rs8PO/btrNxdE3CiX/8a5wTsdEKcCvmIN4zVxUKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rs8PO/btrNxdE3CiX/8a5wTsdEKcCvmIN4zVxUKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frs8PO%2FbtrNxdE3CiX%2F8a5wTsdEKcCvmIN4zVxUKK%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;653&quot; height=&quot;197&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.30.12.png&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;oh my zsh 관련 패키지 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oh my zsh에서 highligting 패키지를 설치하면 인식이 된 명령어는 초록색, 인식이 안 된 명령어는 빨간색으로 뜹니다. 여기에 autosuggestion까지 설치해주면 사용성이 좋습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.38.02.png&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjKb5f/btrNFSTHfXu/QVVj5rFjH9aqGKwBRLiwp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjKb5f/btrNFSTHfXu/QVVj5rFjH9aqGKwBRLiwp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjKb5f/btrNFSTHfXu/QVVj5rFjH9aqGKwBRLiwp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjKb5f%2FbtrNFSTHfXu%2FQVVj5rFjH9aqGKwBRLiwp1%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;867&quot; height=&quot;156&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.38.02.png&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;brew install zsh-syntax-highlighting&lt;/span&gt;&lt;/b&gt;을 치면 되는데 현재 패키지 관리자인 homebrew가 설치되어 있아서 에러 메시지가 뜨네요.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://brew.sh/index_ko&quot;&gt;https://brew.sh/index_ko&lt;/a&gt;에 들어가 curl로 homebrew를 먼저 설치해줍시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.41.18.png&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eb6uis/btrNwo79h9M/89TZDfvoIcpExQIYvWldVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eb6uis/btrNwo79h9M/89TZDfvoIcpExQIYvWldVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eb6uis/btrNwo79h9M/89TZDfvoIcpExQIYvWldVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feb6uis%2FbtrNwo79h9M%2F89TZDfvoIcpExQIYvWldVK%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;879&quot; height=&quot;419&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.41.18.png&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 시에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;/opt/homebrew/bin&lt;/span&gt;을 PATH에 추가하라는 warning이 뜹니다. 무시하면 brew 명령어가 터미널에서 인식되지 않기 때문에, 제시하는 그대로 명령어를 쳐서 PATH에 추가해 줍시다. (M1 맥북 프로에 설치한 경우로 인텔 칩 경로와 다를 수 있습니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.45.02.png&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsv4Me/btrNCgU1iy1/nLpjCAXotiSqdzYxCKWQu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsv4Me/btrNCgU1iy1/nLpjCAXotiSqdzYxCKWQu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsv4Me/btrNCgU1iy1/nLpjCAXotiSqdzYxCKWQu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsv4Me%2FbtrNCgU1iy1%2FnLpjCAXotiSqdzYxCKWQu1%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;854&quot; height=&quot;259&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.45.02.png&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;brew install zsh-syntax-highlighting; brew install zsh-autosuggestions&lt;/span&gt;&amp;nbsp;&lt;/b&gt;커맨드를 쳐서 syntax highlighting, autosuggestions 추가 플러그인들을 설치해줍니다. 설치 후에는 activate하기 위해 .zshrc 하단에 설치된 플러그인을 불러들이는 커맨드를 추가하라는 안내가 나옵니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.54.06.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;47&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvak7I/btrNzJKaacg/euTJLOX7QHKYNE3TrwAz8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvak7I/btrNzJKaacg/euTJLOX7QHKYNE3TrwAz8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvak7I/btrNzJKaacg/euTJLOX7QHKYNE3TrwAz8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdvak7I%2FbtrNzJKaacg%2FeuTJLOX7QHKYNE3TrwAz8k%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;695&quot; height=&quot;47&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.54.06.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;47&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그대로 따라해준 뒤에 .zshrc 파일 설정을 적용하고, 다시 똑같은 명령어를 치면 잘 적용된 걸 확인할 수 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.59.45.png&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVsjfo/btrNFSzoTJY/hDhbdUpUOSRkz0cK0ro3yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVsjfo/btrNFSzoTJY/hDhbdUpUOSRkz0cK0ro3yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVsjfo/btrNFSzoTJY/hDhbdUpUOSRkz0cK0ro3yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVsjfo%2FbtrNFSzoTJY%2FhDhbdUpUOSRkz0cK0ro3yk%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;832&quot; height=&quot;158&quot; data-filename=&quot;스크린샷 2022-10-02 오후 11.59.45.png&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;158&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>ProTips</category>
      <category>iterm</category>
      <category>oh my zsh</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/5</guid>
      <comments>https://codeflow.tistory.com/entry/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A7%A5%EB%B6%81-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%84%A4%EC%A0%95-iTerm%EA%B3%BC-oh-my-zsh-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0#entry5comment</comments>
      <pubDate>Mon, 3 Oct 2022 00:13:38 +0900</pubDate>
    </item>
    <item>
      <title>맥북으로 갈아타기 - 파일 찾기, 검색하기, 화면 전환, Dock 설정</title>
      <link>https://codeflow.tistory.com/entry/%EB%A7%A5%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%88%EC%95%84%ED%83%80%EA%B8%B0-%ED%8C%8C%EC%9D%BC-%EC%B0%BE%EA%B8%B0-%EA%B2%80%EC%83%89%ED%95%98%EA%B8%B0-%ED%99%94%EB%A9%B4-%EC%A0%84%ED%99%98-Dock-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 PC만 쓰다가 맥북을 처음 쓰게 되면 낯선 UI와 윈도우와 다른 한영키 위치, 위아래가 다르게 움직이는 스크롤 방식, &lt;span&gt;alt키 대신 보이는 option키와 command 키를 보며&lt;/span&gt; 어지럽게 느껴집니다. 윈도우 PC에서 맥북으로 갈아타신 분들의 빠른 적응을 돕기 위해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;윈도우의 탐색기, 검색창, 캡쳐 도구를 대신하는 맥북 기능들&lt;/span&gt;과 맥북을 맥북답게 만드는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;화면 전환과 Dock 설정 방법&lt;/span&gt;에 대해 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;윈도우에서 맥OS로&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;탐색기에서 Finder로&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.11.53.png&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;1262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/62nOT/btrNAyuNg4o/AQPkVoWJmAE1LG3oCkuMxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/62nOT/btrNAyuNg4o/AQPkVoWJmAE1LG3oCkuMxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/62nOT/btrNAyuNg4o/AQPkVoWJmAE1LG3oCkuMxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F62nOT%2FbtrNAyuNg4o%2FAQPkVoWJmAE1LG3oCkuMxk%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;2010&quot; height=&quot;1262&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.11.53.png&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;1262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥북에서 윈도우의 파일 탐색기에 대응하는 프로그램은 바로 Finder입니다. 맥북에서 브라우저로 다운로드한 파일들은 기본적으로 /Users/[현재 로그인한 유저 이름]/Downloads 폴더에 저장되는데, Finder 왼쪽 즐겨찾기 메뉴에서 다운로드 항목을 클릭하면 한 번에 다운로드 파일로 접근할 수 있습니다. 응용 프로그램은 앱스토어나 브라우저에서 설치한 프로그램들이 모여 있는 공간입니다. 데스크탑은 윈도우의 바탕화면과 같고, 스크린샷을 찍으면 기본적으로 데스크탑에 저장됩니다. 그밖에 별도 파일 보관을 위한 공간인 문서가 있고, AirDrop, iCloud Drive 파일들도 Finder에서 바로 접근할 수 있답니다.&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;검색창에서 Spotlight로&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.44.53.png&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buX9at/btrNwDw3mT7/KuuvPEIk37HkJtq5pNZN50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buX9at/btrNwDw3mT7/KuuvPEIk37HkJtq5pNZN50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buX9at/btrNwDw3mT7/KuuvPEIk37HkJtq5pNZN50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuX9at%2FbtrNwDw3mT7%2FKuuvPEIk37HkJtq5pNZN50%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;1584&quot; height=&quot;328&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.44.53.png&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spotlight는 검색 도구입니다. &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;shift ⇧ + command ⌘&lt;/span&gt; &lt;/b&gt;키를 동시에 누르면 열리게 됩니다. 검색 도구인 만큼 자주 사용하게 되는데요, 맥북에서 이 두 키가 바로 옆에 있기 때문에 편리하게 사용할 수 있습니다. Spotlight는 파일 검색 외에도 좀 더 확장된 기능을 제공합니다. 저는 현재 원달러 환율을 확인할 때도 Spotlight를 사용하는데요, 아래 이미지와 같이 '1달러'라는 단어를 입력하면 바로 원화로 환전한 결과를 제공해 줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.43.18.png&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QqFQF/btrNAM0O0cV/WfD4556RWkcwAm3icKJJok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QqFQF/btrNAM0O0cV/WfD4556RWkcwAm3icKJJok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QqFQF/btrNAM0O0cV/WfD4556RWkcwAm3icKJJok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQqFQF%2FbtrNAM0O0cV%2FWfD4556RWkcwAm3icKJJok%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;1336&quot; height=&quot;688&quot; data-filename=&quot;스크린샷 2022-10-02 오후 8.43.18.png&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;688&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;b&gt;캡쳐 도구에서 스크린샷 도구 막대로&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥북에선 스크린샷 도구 막대를 통한 스크린샷 캡쳐 기능을 지원합니다. 보통 스크린샷은 도구 막대를 호출하는 대신 바로 단축키를 통해 캡쳐하게 되는데요, 아래 4가지 경우를 가장 많이 사용하게 됩니다. 단축키 조합에 익숙해질 때까지 별도로 복사해놓고 쓰시길 추천합니다.&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 style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;shift ⇧ + command&amp;nbsp;⌘ + 4 + &amp;nbsp;control ⌃&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;특정 영역을 캡쳐해서 파일로 저장 (데스크탑에 저장됨) &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;shift ⇧ + command &lt;span style=&quot;background-color: #ffffff;&quot;&gt;⌘ + 4&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전체 화면을 캡쳐해서 파일로 저장 (데스크탑에 저장됨) &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;shift ⇧ + command&amp;nbsp;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;⌘ + 3&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;비디오 레코딩을 위해 스크린샷 도구 막대 열기 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;shift ⇧ + command&amp;nbsp;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;⌘ + 5&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;기본적으로 스크린샷이 저장되는 위치를 데스크탑에서 다른 위치로 변경하고 싶다면, 스크린샷 도구 막대를 열어 옵션 메뉴에서 변경하고 싶은 위치로 지정해주면 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;맥이 좋은 이유! 화면 전환 하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker (1).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNyJp/btrNxfisjwX/Ps2er3mdtkIGYk3hTStWtk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNyJp/btrNxfisjwX/Ps2er3mdtkIGYk3hTStWtk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNyJp/btrNxfisjwX/Ps2er3mdtkIGYk3hTStWtk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/tNyJp/btrNxfisjwX/Ps2er3mdtkIGYk3hTStWtk/img.gif&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;600&quot; height=&quot;309&quot; data-filename=&quot;ezgif.com-gif-maker (1).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 맥에서 가장 편리한 기능이 바로 화면 전환 기능입니다. 맥북에서는 미션 컨트롤 앱에서 화면 단위를 스페이스라 부르며 화면 전환 기능을 제공하고 있습니다. 현재 작업 중인 화면에서 이전 화면이나 다음 화면으로 옮겨갈 때 굳이 독을 열 필요 없이 세 손가락으로 터치패드를 왼쪽이나 오른쪽으로 이동시키면 화면 전환이 이루어집니다. 세 손가락을 아래에서 위로 이동하면 스페이스 막대가 보이고, 이때 특정 스페이스를 다른 듀얼 모니터로 옮기거나 스페이스 간 화면 순서를 바꿀 수 있게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Dock에 필요한 앱만 남기기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.00.32.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N3iXS/btrNCfIq26k/kaq33yHcUOAlLX0IUswa6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N3iXS/btrNCfIq26k/kaq33yHcUOAlLX0IUswa6K/img.png&quot; data-alt=&quot;Dock의 디폴트 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N3iXS/btrNCfIq26k/kaq33yHcUOAlLX0IUswa6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN3iXS%2FbtrNCfIq26k%2Fkaq33yHcUOAlLX0IUswa6K%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;1776&quot; height=&quot;144&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.00.32.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dock의 디폴트 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MacOS에서 화면 하단 앱 메뉴 바를 Dock이라고 부릅니다. 맥북을 처음 켜면 Dock에서 굉장히 많은 애플 앱들을 보여줍니다. 이 기능들을 모두 쓸 거라면 상관없지만, 그렇지 않다면 사용하지 않는 앱들은 Dock에서 제거할 수도 있습니다. 제거하고 싶은 앱을 클릭해 옵션에서 'Dock에서 제거'를 선택하면 됩니다. 말그대로 Dock에서만 제거하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.01.07.png&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b13LcL/btrNxdLHoqP/krvxxkmPBiyoBDgmtl0q0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b13LcL/btrNxdLHoqP/krvxxkmPBiyoBDgmtl0q0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b13LcL/btrNxdLHoqP/krvxxkmPBiyoBDgmtl0q0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb13LcL%2FbtrNxdLHoqP%2FkrvxxkmPBiyoBDgmtl0q0K%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;1872&quot; height=&quot;450&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.01.07.png&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 앱을 Dock에 추가할 때는 앱을 실행해 앱 아이콘을 클릭한 후 옵션 메뉴에서 'Dock에서 유지'를 선택하면 됩니다. 아래 이미지에서는 커스터마이징을 통해 제가 자주 사용하는 앱들만 &lt;span&gt;Dock에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;보여주도록 변경했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.40.39.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OKUIt/btrNwCx5jir/9ABikxCKUN0uwAUv14sEhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OKUIt/btrNwCx5jir/9ABikxCKUN0uwAUv14sEhk/img.png&quot; data-alt=&quot;Dock 커스터미이징&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OKUIt/btrNwCx5jir/9ABikxCKUN0uwAUv14sEhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOKUIt%2FbtrNwCx5jir%2F9ABikxCKUN0uwAUv14sEhk%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;1466&quot; height=&quot;196&quot; data-filename=&quot;스크린샷 2022-10-02 오후 7.40.39.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dock 커스터미이징&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Dock에서 앱 아이콘 크기를 조정하고 확대 효과 주기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAHLUs/btrNv9XyigI/GWQYeBW2hZgzaN75bB8Qck/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAHLUs/btrNv9XyigI/GWQYeBW2hZgzaN75bB8Qck/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAHLUs/btrNv9XyigI/GWQYeBW2hZgzaN75bB8Qck/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bAHLUs/btrNv9XyigI/GWQYeBW2hZgzaN75bB8Qck/img.gif&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;600&quot; height=&quot;449&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dock 앱 아이콘 크기를 변경하고 싶을 때는 시스템 환경설정 앱에 들어가 'Dock 및 메뉴 막대' 메뉴에서 Dock 크기를 조정해주면 됩니다. 앱에 포커싱이 갈 때 상대적으로 포커싱된 앱의 아이콘 크기가 커지도록 조절 할 수도 있는데요, 'Dock 및 메뉴 막대' 메뉴에서 '확대'를 체크해주면, Dock에서 포커싱하고 있는 앱 아이콘이 확대되어 나타나게 됩니다.&lt;/p&gt;</description>
      <category>ProTips</category>
      <category>맥북 dock</category>
      <category>맥북 사용법</category>
      <category>맥북 캡쳐</category>
      <category>맥북 하단 메뉴</category>
      <author>codeflow</author>
      <guid isPermaLink="true">https://codeflow.tistory.com/4</guid>
      <comments>https://codeflow.tistory.com/entry/%EB%A7%A5%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%88%EC%95%84%ED%83%80%EA%B8%B0-%ED%8C%8C%EC%9D%BC-%EC%B0%BE%EA%B8%B0-%EA%B2%80%EC%83%89%ED%95%98%EA%B8%B0-%ED%99%94%EB%A9%B4-%EC%A0%84%ED%99%98-Dock-%EC%84%A4%EC%A0%95#entry4comment</comments>
      <pubDate>Sun, 2 Oct 2022 21:27:43 +0900</pubDate>
    </item>
  </channel>
</rss>