์๋ ํ์ธ์ ์ ์ธ์ ๋๋ค :)
์ค๋์ ํ๋ก์ ํธ์ fastlane์ ๋์ ํ ๊ฒฝํ์ ํ๋ฒ ๊ณต์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค!!
๋ฐฐํฌ ์๋ํ๋?
๋จผ์ , ๋ฐฐํฌ ์๋ํ๊ฐ ๋ฌด์์ธ์ง๋ถํฐ ์ ๋ฆฌํ๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค!
๊ฐ๋ฐ ๊ณต๋ถ๋ฅผ ํ๋ค๋ณด๋ฉด CI/CD๋ผ๋ ๋จ์ด๋ฅผ ํ๋ฒ์ฏค ์ ํด๋ณด์ จ์ํ ๋ฐ์, ๋ฐฐํฌ ์๋ํ๋ CD์ ํด๋นํฉ๋๋ค.
CI/CD๋ ์ฑ ๊ฐ๋ฐ ๋จ๊ณ์ ์๋ํ๋ฅผ ํตํฉํ๋ ์ฑ ์ ๊ณต ๋ฐฉ์์ผ๋ก, ์ง์์ ํตํฉ(Continuous Integration)/์ง์์ ์ ๊ณต ๋๋ ๋ฐฐํฌ(Continuous Deployment ๋๋ Delivery)๋ฅผ ๋ปํฉ๋๋ค.
๋ฐฐํฌ๋ฅผ ์๋ํ ํด์ผํ๋ ์ด์ ?
๊ทธ๋ ๋ค๋ฉด ๋ฐฐํฌ ์๋ํ๋ ์ ํ์ํ ๊น์?
๋น์ฐํ ๋ฐฐํฌ๋ฅผ ์๋ํํ์ง ์๊ณ , ์๋์ผ๋ก ํ ์๋ ์๊ฒ ์ฃ . ํ์ง๋ง, ์๋์ผ๋ก ๋ฐฐํฌํ๋ ๊ณผ์ ์ ์๊ฐ๋ ์ค๋ ๊ฑธ๋ฆฌ๊ณ ๋ฒ๊ฑฐ๋กญ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ์ด ๊ณผ์ ์์ ์ค์๊ฐ ์๊ธด๋ค๋ฉด ๋ฐฐํฌํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ๋ ๋์ด๋๊ฒ ์ฃ .
๋น๋ฒํ ๋ฐฐํฌ๊ฐ ์ด๋ฃจ์ด์ง๋ ์๋น์ค์์๋ ๋ฐฐํฌ ๋ฃฐ์ ํ๋ฒ ์ ํด๋๊ณ ์๋์ผ๋ก ๋ฐฐํฌ ๊ณผ์ ์ด ์งํ๋๋๋ก ํด์ ๋ฐฐํฌ์ ๋๋ ์ธํ์ ์ค์ด๋ ๊ฒ์ด ํจ์จ์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ ์ ๊ฒฝ์ฐ, ๊ธฐ์กด ํํ๋ก์ ํธ์์ QA๋ฅผ ์งํํ๊ฑฐ๋ ์ฑ์คํ ์ด ์ฌ์ฌ ์ ์ถ ์ ๋ฐฐํฌ ๊ณผ์ ์ด ๋ฒ๊ฑฐ๋กญ๊ณ ์๊ฐ๋ ๋ง์ด ์์๋จ์ ๋๊ผ์ต๋๋ค.
์ฌ์ฌ์ ํ์ํ ๋น๋ ์ ์ถ ์, ํ ์คํธํ๋ผ์ดํธ์ ๋ฒ ํ ๋ฒ์ ์ ๋ฐฐํฌํด์ ์ด๋ฅผ ์ฌ์ฌ์ ํฌํจ์์ผ์ผ ํฉ๋๋ค.
๋ฒ ํ ๋ฒ์ ๋ฐฐํฌ์ ๊ณผ์ ์ ์ฑ Achive - ์ ๋ก๋ํ ์ฑ ๋ฒ์ ์ ํ - ๋ฐฐํฌ ๋ฐฉ์ ์ ํ - ์ฌ๋ฌ๊ฐ์ง ์ต์ ์ ํ - ์ฌ๋์ผ๋ก ํ์๋ค์๊ฒ ๋ ธํฐํ๊ธฐ .. ๋ฑ ์ ๊ณผ์ ์ผ๋ก ์งํ๋๋๋ฐ ์ด ๊ณผ์ ์ด ์ ์๊ฒ๋ ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๊ฒ ๋๊ปด์ก์ต๋๋ค. (์ฌ์ง์ด ์๊ฐ๋ ์ต์ 10์ฌ๋ถ ๊ฑธ๋ฆฝ๋๋ค..)
๊ทธ๋ฆฌ๊ณ ํด๋น ํ๋ก์ ํธ๋ ๊ฐ์ธ ํ๋ก์ ํธ ์๊ธฐ์ ๊ธฐํ๋ถํฐ ๋ฐฐํฌ๊น์ง ๋ชจ๋ ์ผ์ ํผ์ ํด์ผํ๊ธฐ์
๋ฐฐํฌ๋ฅผ ์๋ํํด์ ๊ธฐ๋ฅ ๊ตฌํ ๋ฐ ์ฝ๋ ํ์ง์ ๋์ด๋ ์ผ์ ๋ ์๊ฐ์ ๋ง์ด ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ ์ํด fastlane์ด๋ผ๋ ๋๊ตฌ๋ฅผ ์ด์ฉํด์ ๋ฐฐํฌ๋ฅผ ์๋ํํ๊ฒ ๋์์ต๋๋ค.
fastlane
๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด, fastlane์ iOS ๋ฐ Android ๊ฐ๋ฐ์๊ฐ ์คํฌ๋ฆฐ์ท ์์ฑ, ํ๋กํ ํ๋ก๋น์ ๋ ์ฒ๋ฆฌ, ์ ํ๋ฆฌ์ผ์ด์ ์ถ์์ ๊ฐ์ ์ง๋ฃจํ ์์ ์ ์๋ํํ ์ ์๋ ๋๊ตฌ์ ๋๋ค.
๐ฝ fastlane ๊ณต์๋ฌธ์
์ฆ, fastlane์ iOS์ Android์์ ๋ฐฐํฌ๋ฅผ ์๋ํํ ์ ์๋๋ก ํด์ฃผ๋ ๋๊ตฌ์ ๋๋ค.
fastlane์ผ๋ก ๋ฐฐํฌ ์๋ํํ๊ธฐ
1. fastlane ์ค์น
๋จผ์ , ์ค์น๋ถํฐ ํด์ผ๊ฒ ์ฃ ? ์ ๋ HomeBrew ๋ฅผ ์ด์ฉํด ์ค์น๋ฅผ ํด์ฃผ์๋๋ฐ์, ์๋ ๋ช ๋ น์ด๋ก ์ฝ๊ฒ ์ค์นํ ์ ์์ต๋๋ค.
brew install fastlane
์ถ๊ฐ๋ก, fastlane์ ์ ๋ฐ์ดํธํด์ผ ํ๋ค๋ฉด bundler๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ด์ฉํ๋ฉด ๋ฉ๋๋ค.
gem install bundler
bundler๋ ์์ ๋ช ๋ น์ด๋ฅผ ํตํด ์ค์นํ ์ ์์ผ๋ฉฐ, ์ ๋ฐ์ดํธ ์์๋ bundle update ๋ง ์ ๋ ฅํ๋ฉด ๋ฉ๋๋ค.
2. fastlane ๊ธฐ๋ณธ ์ค์
fastlane์ ์ด์ฉํด ์๋ ๋ฐฐํฌ ์ค์ ์ ํ๊ธฐ ์ํด์๋ ์ฌ์ฉํ Xcode ํ๋ก์ ํธ๊ฐ ์๋ ๊ฒฝ๋ก๋ก ์ด๋ํด์ฃผ์ธ์!
๊ทธ๋ฐ ๋ค์ ์๋์ ๋ช ๋ น์ด๋ก ๊ธฐ๋ณธ ์ค์ ์ ์์ํ ์ ์์ต๋๋ค.
fastlane init
์์ ์คํฌ๋ฆฐ์ท์ ๋ณด๋ฉด, Xcode ํ๋ก์ ํธ ํ์ผ์ด ์๋ ๊ณณ์์ initํ ๊ฒฝ์ฐ, sub ๋๋ ํ ๋ฆฌ๋ก ์ด๋ํด์ ์งํํ๋ผ๋ ์ค๋ฅ๊ฐ ๋จ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. .xcodeproj ํ์ผ์ด ์๋ ๋๋ ํ ๋ฆฌ๋ก ์ด๋ํด์ ํ๋ฒ ๋ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ๋ฉด fastlane ํด๋๊ฐ ์ ์์ฑ๋๊ฒ ๋ฉ๋๋ค.
๊ทธ ๋ค์์ผ๋ก ์ด๋ค ์์ ์ ํ ์ง ๋ฌป๋ ๋ฉ์ธ์ง๊ฐ ๋์ค๊ฒ ๋ฉ๋๋ค.
์ ๋ ํ ์คํธ๋ ์ฌ์ฌ์ ํ์ํ testflight beta ๋ฒ์ ์ ์๋์ผ๋ก ๋ฐฐํฌํ๊ณ ์ถ์ด์ 2๋ฒ์ ์ ํํด์ฃผ์์ต๋๋ค. (์ด์ ์๋น์ค ๋ฆด๋ฆฌ์ฆ๋ ์๋ฃ๋์์ผ๋ App Store์ ์๋์ผ๋ก ๋ฐฐํฌ๋๋๋ก ์ธํ ๋ ํ๋ฒ ํด๋ด์ผ๊ฒ ์ด์!)
๊ทธ๋ฌ๋ฉด ํ๋ก์ ํธ ํ์ผ ๊ฒ์ฌ, ํจํค์ง ์์กด์ฑ ์ฒดํฌ ๋ฑ๋ฑ ์ฌ๋ฌ๊ฐ์ง ์์ ์ ํ๊ฒ ๋ฉ๋๋ค.
์๋ฃ๊ฐ ๋๋ฉด, Apple ID๋ก ๋ก๊ทธ์ธ ํด๋ฌ๋ผ๊ณ ๋น๋๋ค!
์๊ตฌ๋๋ก ์ ํ ๊ณ๋ฐ์ ๊ณ์ ์ ์ด๋ฉ์ผ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ๊ณ , ์ด์ค์ธ์ฆ 6์๋ฆฌ ์ฝ๋๋ ์
๋ ฅํ๋ฉด ๋ฉ๋๋ค. (์
๋ ฅ๋ ๋ก๊ทธ์ธ ์ ๋ณด๋ ๋งฅ์ ํค์ฒด์ธ ๋ด์ ์ ์ฅ๋๋ค๊ณ ํฉ๋๋ค.)
์์ ๊ฐ์ ๋ฉ์์ง๊ฐ ๋จ๋ฉด ๊ธฐ๋ณธ์ ์ธ fastlane ์ค์ ์ ์๋ฃ๋์์ต๋๋ค.
์ด์ ํด๋น ํด๋์ ์๋์ ๊ฐ์ 4๊ฐ์ง ํ์ผ์ด ์์ฑ๋์์ ๊ฑฐ์์!
- Gemfile
- Gemfile.lock
- fastlane/Appfile
- fastlane/Fastfile
3. ๋ฐฐํฌ ์ค์
์์ฑ๋ ํ์ผ์ ๊ฐ์ง๊ณ ๋ฐฐํฌ์ ํ์ํ ์ฌ๋ฌ๊ฐ์ง ์ค์ ์ ํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ฐฐํฌ์ ํ์ํ ์ค์ ์ ํ๊ธฐ ์ํด ์์ ํด์ผ ํ ํ์ผ์ Appfile๊ณผ Fastfile์ ๋๋ค.
- Appfile: ID, Identifier ๋ฑ ๋ฐฐํฌ์ ํ์ํ ํ์์ ์ธ ๊ฐ ์ค์
- Fastfile: ์๋ํ ํ ๋ฐฐํฌ ๋ฃฐ ์ค์
Appfile
Appfile์๋ Apple ID ๋๋ ์ ํ๋ฆฌ์ผ์ด์ Bundle Identifier์ ๊ฐ์ ๋ชจ๋ fastlane ๋๊ตฌ์ ์ฌ์ฉ๋๋ ์ ์ฉํ ์ ๋ณด๊ฐ ์ ์ฅ๋์ด ์์ด ํ๋ก์ ํธ ์๊ตฌ ์ฌํญ์ ๋ง๋๋ก ๋ ๋น ๋ฅด๊ฒ lane์ ๋ฐฐ์นํ ์ ์์ต๋๋ค.
์์์ ์ฑ๊ณต์ ์ผ๋ก ๋ก๊ทธ์ธํ๋ค๋ฉด ์ด๋ฐ์์ผ๋ก ๊ธฐ๋ณธ ๊ฐ๋ค์ด ์ธํ ๋ ํ ๋ฐ,
๋ง์ฝ ๊ฐ์ธํ๋ก์ ํธ๊ฐ ์๋๋ผ ํํ๋ก์ ํธ๋ก ์งํํ๋ฉฐ ์ฌ๋ฌ ํ์๋ค์ด ํ๋ก๋น์ ๋ ํ์ผ ๋ฐ ์ธ์ฆ์๋ฅผ ๊ณต์ ํด์ ๊ณต๋์์ ์ ํ๊ฒ ๋๋ค๋ฉด apple_id ๋ถ๋ถ์์ ์ฆ์ ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ .env ํ์ผ์ ์ด์ฉํด ํ๊ฒฝ๋ณ์๋ก ์ค์ ํ์ฌ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
Fastfile
Fastfile์๋ fastlane๊ณผ ํจ๊ป ์คํํ ์ ์๋ ์๋ํ ๊ตฌ์ฑ์ด ์ ์ฅ๋ฉ๋๋ค.
fastlane์ ์ฌ์ฉ๋๋ ์ฌ๋ฌ๊ฐ์ง ๋ฃฐ์ ํด๋น ํ์ผ์์ Ruby ์ธ์ด๋ก ์์ฑํ ์ ์์ต๋๋ค.
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
increment_build_number(build_number: latest_testflight_build_number + 1)
build_app(scheme: "LuckyVicky")
upload_to_testflight
slack(
message: "TestFlight ๋ฐฐํฌ์ ์ฑ๊ณตํ์ต๋๋ค๐",
slack_url: "์ฌ๋ webhookURL",
payload: {
"Build Date" => Time.new.to_s,
},
success: true
)
end
end
์ ์ ๊ฒฝ์ฐ, beta ๋ฒ์ ์ด ์ ์์ ์ผ๋ก testflight์ ๋ฐฐํฌ ์๋ฃ๋๋ฉด, ์ฌ๋์ ๋ ธํฐ๊น์ง ์ค ์ ์๋๋ก ์ค์ ํด์ฃผ์๋๋ฐ์!
์ฝ๋๋ ์์ ๊ฐ์ต๋๋ค.
์ฝ๋๋ฅผ ์ข ์ดํด๋ณด์๋ฉด,
default_platform(:ios)
๊ธฐ๋ณธ ํ๋ซํผ์ iOS๋ก ์ค์ ํ์ฌ fastlane [lane name]์ผ๋ก ๊ฐํธํ๊ฒ ์คํํ ์ ์์ต๋๋ค.
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
...
end
end
- desc "Push a new beta build to TestFlight": ์ด lane์ ์ค๋ช ์ ์์ฑํฉ๋๋ค.
- lane: [lane name] do ... end: lane์ ์์ ํ๋ฆ์ ์ ์ํฉ๋๋ค. beta lane์ TestFlight์ ๋ฒ ํ ๋น๋๋ฅผ ๋ฐฐํฌํ๋ ๊ณผ์ ์ ์๋ํํฉ๋๋ค.
์ ๊ฐ ์ค์ ํ lane์ ์์ ํ๋ฆ์ ์ข ๋ ์์ธํ ๋ณผ๊ฒ์!
increment_build_number(build_number: latest_testflight_build_number + 1)
ํ์ฌ TestFlight์ ์ฌ๋ผ๊ฐ ์๋ ์ต์ ๋น๋ ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๋น๋ ๋ฒํธ๋ฅผ 1 ์ฆ๊ฐ์ํต๋๋ค.
build_app(scheme: "LuckyVicky")โ
์ง์ ๋ scheme("LuckyVicky")์ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น๋ํฉ๋๋ค.
ํด๋น lane์ ๋ง๋ sheme์ ์ง์ ํด์ฃผ๋ฉด ๋๊ฒ ์ฃ ? (beta ๋ฒ์ ์์๋ debug, ์ค์ ๋ฐฐํฌ์์๋ release ๋ฑ)
upload_to_testflight
slack(
message: "TestFlight ๋ฐฐํฌ์ ์ฑ๊ณตํ์ต๋๋ค๐",
slack_url: "์ฌ๋ webhookURL",
payload: {
"Build Date" => Time.new.to_s,
},
success: true
)
๋น๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ TestFlight์ ์ ๋ก๋ํ๋ ๋ถ๋ถ์ ๋๋ค.
์ธ์ฆ์ด ์๋ฃ๋๋ค๋ฉด ๋ฐฐํฌํ๊ณ , ์ฌ๋์ ์๋ฆผ๊น์ง ์ฃผ๊ณ ์์ต๋๋ค.
์ด์ ๊ณต์
์ ๋ Fastfile์ ์์ ํ๋ ๊ณผ์ ์์ ํ๊ฐ์ง ์ด์๊ฐ ์์๋๋ฐ์, ์๊ฑธ ํ ๋ฒ ๊ณต์ ํด๋ณผ๊ฒ์!
์์ ๊ฐ์ด Fastfile์ ์ ์์ ํ๊ณ , fastlane beta ๋ฅผ ์ ๋ ฅํด ๋ฐฐํฌ๋ฅผ ํด๋ณด์๋๋ฐ์, ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค๐ฅ
์๋ฌ๋ฅผ ์ดํด๋ณด๋ฉด,
๊ถํ์ ์ป๋๋ฐ ์คํจํ๊ณ , 23๋ฒ ๋ผ์ธ์์ ์๋ฌ๊ฐ ๋๊ณ ์๊ณ ipa ํ์ผ์ ์ ๋ก๋ํ๋ ๋ฐ ์คํจํ๊ธฐ ๋๋ฌธ์ archive๋ฅผ ์ ๋ก๋ ํ ์ ์๋ค.
๋ญ ์ด๋ฐ ์ค๋ฅ๊ฐ ๋๊ณ ์๋ค์.
fastlane ๋ฌธ์์ Authentication์ด๋ผ๋ ํํธ๊ฐ ์์ด์ ์ฐพ์๋ณด์์ต๋๋ค.
https://docs.fastlane.tools/getting-started/ios/authentication/
๋ฌธ์๋ฅผ ํ์ธํด๋ณด๋ฉด, ๊ฐ์ฅ ์ฒซ๋ฒ์งธ๋ก AppStore Connect API๋ฅผ ์ฌ์ฉํ๋ผ๋ ๋ด์ฉ์ด ๋์ต๋๋ค.
๋ฌธ์์์ ๊ฐ์ด๋ํด์ฃผ๋๋๋ก App Store Connect > ์ฌ์ฉ์ ๋ฐ ์ก์ธ์ค > ํตํฉ > App Store Connect API ์์ key ๋ฅผ ์์ฑํ๊ณ json ํ์ผ์ ๋ง๋ค์ด์ ์ ์ฉํด์ฃผ์์ต๋๋ค.
๋ฌธ์์์ ๋งค์ฐ ์์ธํ ํค ๊ด๋ฆฌ ๋ฐฉ๋ฒ๊น์ง ์๋ ค์ค๋๋ค!
ํค ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด์ด๋ ๋ฆฌ๋ชจํธ์ ์ฌ๋ฆฌ์ง ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.(์ ์ ๊ฒฝ์ฐ.gitignore์ ํ์ผ ์ถ๊ฐ)
์ด๋ ๊ฒ ์ด์๊น์ง ํด๊ฒฐํ ์ต์ข ์ ์ธ Fastfile ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
increment_build_number(build_number: latest_testflight_build_number + 1)
build_app(scheme: "LuckyVicky")
upload_to_testflight(
api_key_path: "fastlane/key.json"
)
slack(
message: "TestFlight ๋ฐฐํฌ์ ์ฑ๊ณตํ์ต๋๋ค๐",
slack_url: "https://hooks.slack.com/services/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",
payload: {
"Build Date" => Time.new.to_s,
},
success: true
)
end
end
์ด์ ์ ์ฅํ๊ณ fastlane beta๋ฅผ ์ ๋ ฅํด์ฃผ๋ฉด?!? ์๋์ ๊ฐ์ด ์ฑ๊ณต ๋ฉ์์ง๊ฐ ๋น๋๋ค!
๋ฐฐํฌ ์๋ํ๋ฅผ ์ฒ์ ํด๋ณด๋ ๊ฒ์ด๋ผ ์ค์ ๊ณผ์ ์ด ์ฝ์ง๋ ์์์ง๋ง, ๊ฐ์ธ์ ์ผ๋ก ๋งค์ฐ ๋ง์กฑํ๊ณ ์์ต๋๋ค!
๋ช ๋ น์ด ํ๋๋ก archive ๋ถํฐ testflight์ ์ฌ๋ฆฌ๋ ๊ฒ๊น์ง ์๋์ผ๋ก ๋๋, ๊ฐ๋ฐ๊ณผ์ ์๋ง ์ง์คํ ์ ์์ด ๋งค์ฐ ํธํ ๊ฒ ๊ฐ์ต๋๋ค.
๊ธํ๊ฒ ์ฌ์ฌ๋ฅผ ์ฌ๋ฆฌ๊ฑฐ๋, ํ ์คํธ๋ฅผ ํด๋ณด์์ผ ํ ๋๋ ๋งค์ฐ ์ ์ฉํ ๊ฒ ๊ฐ์์.
๋ฌธ์๋ ๋๋ฌด ์ ์ ๋ฆฌ๋์ด์์ด์ ์๋ํด๋ณผ๋งํ ๊ฒ ๊ฐ์ต๋๋ค.
fastlane์ผ๋ก ๋ฐฐํฌ ์๋ํ๋ฅผ ์๋ํด๋ณด์๋ ๋ถ๋ค๊ป ์ด ๊ธ์ด ์กฐ๊ธ์ด๋๋ง ๋์์ด ๋๊ธธ ๋ฐ๋๋๋ค๐๐
[์ฐธ๊ณ ์๋ฃ]
'๐ iOS > iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] ์ด๋ฏธ์ง์ ์ํ๋ ๋ชจ์์ ๋ง์คํฌ ์ ์ฉํ๊ธฐ (0) | 2024.05.16 |
---|---|
[iOS] TDD์ Unit Test (3) | 2023.12.14 |
[iOS] iOS ํ์ผ ์์คํ (1) | 2023.11.28 |
[iOS] ํค์ฒด์ธ(Keychain)์ ์ด์ฉํ ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ (0) | 2023.08.06 |
[iOS/Architecture] Coordinator Pattern (2) | 2022.12.11 |