์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ Swift ์˜์กด์„ฑ ๊ด€๋ฆฌ ์ „๋žต: SPM, CocoaPods, Carthage ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์‹ฌ์ธต ๋น„๊ต
๐Ÿ“ฆ Swift ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ

๐Ÿš€ Swift ์˜์กด์„ฑ ๊ด€๋ฆฌ ์ „๋žต: SPM, CocoaPods, Carthage ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์‹ฌ์ธต ๋น„๊ต

Swift ํ”„๋กœ์ ํŠธ์—์„œ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค๋ฃจ๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•, ์ œ๋Œ€๋กœ ํŒŒํ—ค์ณ๋ณด์ž!
์•ผ ๊ทผ๋ฐ Swift ํ”„๋กœ์ ํŠธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ญ ์จ? SPM? CocoaPods? ๐Ÿค”

ใ…‹ใ…‹ใ…‹ ๊ทธ๊ฑฐ ์ง„์งœ ์ค‘์š”ํ•œ ์งˆ๋ฌธ์ž„! ๋ญ˜ ์“ฐ๋ƒ์— ๋”ฐ๋ผ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๊ฐ€ ์™„์ „ ๋‹ฌ๋ผ์ง€๊ฑฐ๋“ ~

iOS/macOS ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(์˜์กด์„ฑ)๋ฅผ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์ˆœ๊ฐ„์ด ๋ฐ˜๋“œ์‹œ ์˜ด. Alamofire, SnapKit, Kingfisher ๊ฐ™์€ ์œ ๋ช…ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ง์ ‘ ์†Œ์Šค์ฝ”๋“œ ๋ณต๋ถ™ํ•ด์„œ ์“ธ ์ˆ˜๋„ ์žˆ์ง€๋งŒ... ๊ทธ๊ฑด ์ง„์งœ ๋…ธ๋‹ต์ด์ž–์•„? ๐Ÿ˜…

๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒŒ ๋ฐ”๋กœ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €(Package Manager)! ์˜์กด์„ฑ์„ ์ž๋™์œผ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ , ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•˜๊ณ , ํ”„๋กœ์ ํŠธ์— ํ†ตํ•ฉ์‹œ์ผœ์ฃผ๋Š” ๋„๊ตฌ์•ผ.

Swift ์ƒํƒœ๊ณ„์—์„œ๋Š” ํฌ๊ฒŒ 3๊ฐ€์ง€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๊ฐ€ ์žˆ์–ด:

๐ŸŽ SPM
Swift Package Manager
Apple ๊ณต์‹ ๋„๊ตฌ
๐Ÿฆ… CocoaPods
๊ฐ€์žฅ ์˜ค๋ž˜๋œ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €
Ruby ๊ธฐ๋ฐ˜
๐Ÿน Carthage
๋ถ„์‚ฐํ˜• ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €
Go ๊ธฐ๋ฐ˜

์ด ์„ธ ๊ฐ€์ง€๋ฅผ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ์ƒํ™ฉ์— ๋งž๋Š” ์ตœ์ ์˜ ์„ ํƒ์„ ํ•  ์ˆ˜ ์žˆ์–ด. ์ง€๊ธˆ๋ถ€ํ„ฐ ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด์ž! ๐Ÿ”ฅ

Swift ์˜์กด์„ฑ ๊ด€๋ฆฌ ์ƒํƒœ๊ณ„ ์„ธ ๊ฐ€์ง€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์˜ ํฌ์ง€์…”๋‹ Swift ํ”„๋กœ์ ํŠธ SPM Swift Package Manager Apple ๊ณต์‹ Xcode ํ†ตํ•ฉ CocoaPods Ruby ๊ธฐ๋ฐ˜ ์ค‘์•™์ง‘์ค‘์‹ ๊ฐ€์žฅ ๋งŽ์€ ํŒŸ Podfile ์„ค์ • Carthage ๋ถ„์‚ฐํ˜• ยท ๋น„์นจ์Šต์  Cartfile ์„ค์ • ํ”„๋ ˆ์ž„์›Œํฌ
๐Ÿ“… ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์˜ ์—ญ์‚ฌ: ์–ด์ฉŒ๋‹ค ์ด๋ ‡๊ฒŒ ๋๋ƒ๊ณ ?

Swift ์ƒํƒœ๊ณ„์—์„œ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๊ฐ€ 3๊ฐœ๋‚˜ ๊ณต์กดํ•˜๊ฒŒ ๋œ ๊ฑด ์‚ฌ์‹ค ์—ญ์‚ฌ์ ์ธ ์ด์œ ๊ฐ€ ์žˆ์–ด. ํƒ€์ž„๋ผ์ธ์œผ๋กœ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์‰ฌ์›€!

1
2011๋…„ - CocoaPods ๋“ฑ์žฅ ๐Ÿฆ…
Objective-C ์‹œ์ ˆ๋ถ€ํ„ฐ ์‹œ์ž‘. Ruby์˜ gem ์‹œ์Šคํ…œ์—์„œ ์˜๊ฐ๋ฐ›์•„ ๋งŒ๋“ค์–ด์ง„ ์ตœ์ดˆ์˜ iOS ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €. ๋‹น์‹œ์—” ์ง„์งœ ํ˜๋ช…์ด์—ˆ์Œ. ์ˆ˜๋™์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒŒ์ผ ๋ณต๋ถ™ํ•˜๋˜ ์‹œ๋Œ€๋ฅผ ๋๋ƒˆ๊ฑฐ๋“ !
2
2014๋…„ - Carthage ๋“ฑ์žฅ ๐Ÿน
Swift๊ฐ€ ๋ฐœํ‘œ๋œ ํ•ด์— CocoaPods์˜ ๋‹จ์ (ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์ˆ˜์ •, ์ค‘์•™ ์„œ๋ฒ„ ์˜์กด)์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅ. "๋น„์นจ์Šต์ (non-invasive)" ์ฒ ํ•™์„ ๋‚ด์„ธ์›€. ๊ทผ๋ฐ ๋นŒ๋“œ๊ฐ€ ๋А๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ์Œ ใ…‹ใ…‹
3
2015๋…„ - SPM ๋“ฑ์žฅ ๐ŸŽ
Apple์ด Swift ์˜คํ”ˆ์†Œ์Šคํ™”์™€ ํ•จ๊ป˜ ๊ณต์‹ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋ฅผ ๋ฐœํ‘œ. ์ฒ˜์Œ์—” iOS ์ง€์›๋„ ์•ˆ ๋๊ณ  ๊ธฐ๋Šฅ์ด ๋งŽ์ด ๋ถ€์กฑํ–ˆ์Œ. ๊ทผ๋ฐ Xcode 11(2019๋…„)๋ถ€ํ„ฐ iOS ์ง€์› + Xcode ํ†ตํ•ฉ์ด ๋˜๋ฉด์„œ ๊ธ‰์„ฑ์žฅ!
๐Ÿ’ก ํ˜„์žฌ ํŠธ๋ Œ๋“œ: 2024๋…„ ๊ธฐ์ค€์œผ๋กœ SPM์ด ์ ์  ๋Œ€์„ธ๊ฐ€ ๋˜๊ณ  ์žˆ์–ด. ์ƒˆ ํ”„๋กœ์ ํŠธ๋Š” ๋Œ€๋ถ€๋ถ„ SPM์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ , ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ๋“ค๋„ CocoaPods์—์„œ SPM์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ์ถ”์„ธ์•ผ!
๐ŸŽ SPM (Swift Package Manager) ์™„์ „ ํ•ด๋ถ€

SPM์€ Apple์ด ๊ณต์‹์œผ๋กœ ๋งŒ๋“  ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์•ผ. Swift ์–ธ์–ด ์ž์ฒด์— ๋‚ด์žฅ๋˜์–ด ์žˆ๊ณ , Xcode์™€ ์™„๋ฒฝํ•˜๊ฒŒ ํ†ตํ•ฉ๋˜์–ด ์žˆ์–ด์„œ ๋ณ„๋„ ์„ค์น˜๊ฐ€ ํ•„์š” ์—†์Œ!

๐Ÿ“ Package.swift - SPM์˜ ์‹ฌ์žฅ

SPM์˜ ๋ชจ๋“  ์„ค์ •์€ Package.swift ํŒŒ์ผ ํ•˜๋‚˜๋กœ ๊ด€๋ฆฌ๋ผ. Swift ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ ํŠน์ง•!

// Package.swift ์˜ˆ์‹œ
// Swift: Package Description
import PackageDescription

let package = Package(
    name: "MyAwesomeApp",
    platforms: [
        .iOS(.v15),
        .macOS(.v12)
    ],
    products: [
        .library(
            name: "MyAwesomeApp",
            targets: ["MyAwesomeApp"]
        ),
    ],
    dependencies: [
        // ์˜์กด์„ฑ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณณ!
        .package(
            url: "https://github.com/Alamofire/Alamofire.git",
            .upToNextMajor(from: "5.8.0")
        ),
        .package(
            url: "https://github.com/onevcat/Kingfisher.git",
            from: "7.0.0"
        ),
    ],
    targets: [
        .target(
            name: "MyAwesomeApp",
            dependencies: [
                "Alamofire",
                "Kingfisher"
            ]
        ),
        .testTarget(
            name: "MyAwesomeAppTests",
            dependencies: ["MyAwesomeApp"]
        ),
    ]
)
๐ŸŽฏ ๋ฒ„์ „ ์ง€์ • ๋ฐฉ๋ฒ•

SPM์—์„œ ๋ฒ„์ „์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žˆ๋Š”๋ฐ, ์ด๊ฒŒ ์ง„์งœ ์ค‘์š”ํ•ด!

๋ฐฉ๋ฒ• ์ฝ”๋“œ ์˜๋ฏธ
upToNextMajor .upToNextMajor(from: "5.0.0") 5.x.x ๋ฒ”์œ„ (6.0.0 ๋ฏธ๋งŒ)
upToNextMinor .upToNextMinor(from: "5.8.0") 5.8.x ๋ฒ”์œ„ (5.9.0 ๋ฏธ๋งŒ)
exact .exact("5.8.1") ์ •ํ™•ํžˆ 5.8.1๋งŒ
branch .branch("main") ํŠน์ • ๋ธŒ๋žœ์น˜ ์ตœ์‹  ์ปค๋ฐ‹
revision .revision("abc1234") ํŠน์ • ์ปค๋ฐ‹ ํ•ด์‹œ
โšก Xcode์—์„œ SPM ์ถ”๊ฐ€ํ•˜๋Š” ๋ฒ•
1
Xcode ๋ฉ”๋‰ด โ†’ File โ†’ Add Package Dependencies... ํด๋ฆญ
2
๊ฒ€์ƒ‰์ฐฝ์— GitHub URL ์ž…๋ ฅ (์˜ˆ: https://github.com/Alamofire/Alamofire)
3
๋ฒ„์ „ ๊ทœ์น™ ์„ ํƒ ํ›„ Add Package ํด๋ฆญ
4
ํƒ€๊ฒŸ์— ์ถ”๊ฐ€ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒ โ†’ ์™„๋ฃŒ! ๐ŸŽ‰
๐Ÿ”’ Package.resolved - ๋ฒ„์ „ ์ž ๊ธˆ ํŒŒ์ผ

SPM์€ ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๋ฉด Package.resolved ํŒŒ์ผ์„ ์ž๋™ ์ƒ์„ฑํ•ด. ์ด ํŒŒ์ผ์€ ์ •ํ™•ํ•œ ๋ฒ„์ „ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด์„œ ํŒ€์›๋“ค์ด ๋™์ผํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณด์žฅํ•ด์คŒ.

// Package.resolved ์˜ˆ์‹œ (JSON ํ˜•์‹)
{
  "pins" : [
    {
      "identity" : "alamofire",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/Alamofire/Alamofire.git",
      "state" : {
        "revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a",
        "version" : "5.8.1"
      }
    }
  ],
  "version" : 2
}
๐Ÿ’ก ํŒ: Package.resolved ํŒŒ์ผ์€ ๋ฐ˜๋“œ์‹œ Git์— ์ปค๋ฐ‹ํ•ด์•ผ ํ•ด! ๊ทธ๋ž˜์•ผ ํŒ€์›๋“ค์ด ๋™์ผํ•œ ๋ฒ„์ „์„ ์“ธ ์ˆ˜ ์žˆ๊ฑฐ๋“ . ์ด๊ฑฐ .gitignore์— ๋„ฃ์œผ๋ฉด ๋‚˜์ค‘์— ๋ฒ„์ „ ์ถฉ๋Œ๋กœ ๊ณ ์ƒํ•จ ใ…‹ใ…‹
โœ… SPM์˜ ์žฅ๋‹จ์ 
๐Ÿ‘ ์žฅ์ 

Apple ๊ณต์‹ ์ง€์›
๋ณ„๋„ ์„ค์น˜ ๋ถˆํ•„์š”
Xcode ์™„๋ฒฝ ํ†ตํ•ฉ
Swift๋กœ ์„ค์ • ํŒŒ์ผ ์ž‘์„ฑ
๋น ๋ฅธ ๋นŒ๋“œ ์†๋„
xcworkspace ๋ถˆํ•„์š”
Linux ์ง€์›
๐Ÿ‘Ž ๋‹จ์ 

๋ ˆ๊ฑฐ์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฏธ์ง€์›
๋ฆฌ์†Œ์Šค ๋ฒˆ๋“ค ์ฒ˜๋ฆฌ ๋ณต์žก
Objective-C ํ˜ผ์šฉ ์‹œ ์ œํ•œ
๋„คํŠธ์›Œํฌ ์˜์กด์„ฑ ๋†’์Œ
Private ํŒจํ‚ค์ง€ ์„ค์ • ๋ณต์žก
๐Ÿฆ… CocoaPods - ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์ „ํ†ต์˜ ๊ฐ•์ž

CocoaPods๋Š” 2011๋…„๋ถ€ํ„ฐ ์‹œ์ž‘๋œ iOS ์ƒํƒœ๊ณ„์˜ ํ„ฐ์ค๋Œ€๊ฐ์ด์•ผ. Ruby๋กœ ๋งŒ๋“ค์–ด์กŒ๊ณ , ์ค‘์•™ ์ €์žฅ์†Œ(CocoaPods Trunk)๋ฅผ ํ†ตํ•ด ํŒจํ‚ค์ง€๋ฅผ ๊ด€๋ฆฌํ•ด. ํ˜„์žฌ๋„ ์ˆ˜๋งŒ ๊ฐœ์˜ ํŒŸ(Pod)์ด ๋“ฑ๋ก๋˜์–ด ์žˆ์–ด์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ˜๋Š” ๊ฐ€์žฅ ๋งŽ์Œ!

๐Ÿ”ง CocoaPods ์„ค์น˜ ๋ฐ ์ดˆ๊ธฐ ์„ค์ •

CocoaPods๋Š” Ruby gem์œผ๋กœ ์„ค์น˜ํ•ด. macOS์—๋Š” Ruby๊ฐ€ ๊ธฐ๋ณธ ์„ค์น˜๋˜์–ด ์žˆ์–ด์„œ ํ„ฐ๋ฏธ๋„์—์„œ ๋ฐ”๋กœ ์„ค์น˜ ๊ฐ€๋Šฅ!

# CocoaPods ์„ค์น˜
sudo gem install cocoapods

# ๋ฒ„์ „ ํ™•์ธ
pod --version

# ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™” (Podfile ์ƒ์„ฑ)
cd /path/to/your/project
pod init
๐Ÿ“„ Podfile - CocoaPods์˜ ์„ค์ • ํŒŒ์ผ

CocoaPods์˜ ์„ค์ •์€ Podfile์— ์ž‘์„ฑํ•ด. Ruby DSL๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ ํŠน์ง•!

# Podfile ์˜ˆ์‹œ
platform :ios, '15.0'
use_frameworks!

# ์ „์ฒด ํƒ€๊ฒŸ์— ์ ์šฉ
target 'MyAwesomeApp' do
  # ๋„คํŠธ์›Œํ‚น
  pod 'Alamofire', '~> 5.8'
  
  # ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ
  pod 'Kingfisher', '~> 7.0'
  
  # UI
  pod 'SnapKit', '~> 5.6'
  pod 'Then', '~> 3.0'
  
  # ํ…Œ์ŠคํŠธ ํƒ€๊ฒŸ
  target 'MyAwesomeAppTests' do
    inherit! :search_paths
    pod 'Quick', '~> 7.0'
    pod 'Nimble', '~> 13.0'
  end
end

# ๋นŒ๋“œ ์„ค์ • ํ›„์ฒ˜๋ฆฌ (์„ ํƒ์‚ฌํ•ญ)
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '5.0'
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
    end
  end
end
๐Ÿ”ข CocoaPods ๋ฒ„์ „ ์ง€์ • ๋ฐฉ๋ฒ•
์—ฐ์‚ฐ์ž ์˜ˆ์‹œ ์˜๋ฏธ
~> pod 'Alamofire', '~> 5.8' 5.8 ์ด์ƒ 6.0 ๋ฏธ๋งŒ (๋‚™๊ด€์  ์—ฐ์‚ฐ์ž)
>= pod 'Alamofire', '>= 5.0' 5.0 ์ด์ƒ ๋ชจ๋“  ๋ฒ„์ „
= pod 'Alamofire', '5.8.1' ์ •ํ™•ํžˆ 5.8.1๋งŒ
:git pod 'MyLib', :git => 'https://...' Git ์ €์žฅ์†Œ ์ง์ ‘ ์ง€์ •
โš™๏ธ pod install vs pod update

์ด๊ฑฐ ํ—ท๊ฐˆ๋ฆฌ๋Š” ์‚ฌ๋žŒ ์ง„์งœ ๋งŽ์Œ! ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํžˆ ์•Œ์•„์•ผ ํ•ด ใ…‹ใ…‹

# pod install
# - Podfile.lock์— ๋ช…์‹œ๋œ ๋ฒ„์ „์œผ๋กœ ์„ค์น˜
# - ์ฒ˜์Œ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ ์ƒˆ ํŒŸ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉ
# - ๊ธฐ์กด ํŒŸ ๋ฒ„์ „์€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ (์•ˆ์ „!)
pod install

# pod update
# - Podfile์˜ ๋ฒ„์ „ ๋ฒ”์œ„ ๋‚ด์—์„œ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธ
# - ํŠน์ • ํŒŸ๋งŒ ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ
pod update
pod update Alamofire  # Alamofire๋งŒ ์—…๋ฐ์ดํŠธ

# pod outdated
# - ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅํ•œ ํŒŸ ๋ชฉ๋ก ํ™•์ธ
pod outdated
โš ๏ธ ์ฃผ์˜! pod update๋Š” ๋ชจ๋“  ํŒŸ์„ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์˜ฌ๋ ค๋ฒ„๋ ค์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ Breaking Change๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์–ด. ํŠน์ • ํŒŸ๋งŒ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜, ์ถฉ๋ถ„ํ•œ ํ…Œ์ŠคํŠธ ํ›„์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹์•„!
๐Ÿ“ฆ CocoaPods ์„ค์น˜ ํ›„ ์ƒ์„ฑ๋˜๋Š” ํŒŒ์ผ๋“ค

๐Ÿ“ Pods/ - ๋‹ค์šด๋กœ๋“œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์ €์žฅ๋˜๋Š” ํด๋”
๐Ÿ“„ Podfile.lock - ์ •ํ™•ํ•œ ๋ฒ„์ „ ์ž ๊ธˆ ํŒŒ์ผ (Git์— ์ปค๋ฐ‹ ํ•„์ˆ˜!)
๐Ÿ“„ MyApp.xcworkspace - ์ด์ œ ์ด๊ฑธ๋กœ ํ”„๋กœ์ ํŠธ ์—ด์–ด์•ผ ํ•จ!
๐Ÿ“„ Pods/Pods.xcodeproj - ํŒŸ๋“ค์˜ Xcode ํ”„๋กœ์ ํŠธ

โ„น๏ธ ์ค‘์š”! CocoaPods ์„ค์น˜ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ .xcworkspace ํŒŒ์ผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด์•ผ ํ•ด. .xcodeproj๋กœ ์—ด๋ฉด ํŒŸ๋“ค์ด ์ธ์‹์ด ์•ˆ ๋จ!
โœ… CocoaPods์˜ ์žฅ๋‹จ์ 
๐Ÿ‘ ์žฅ์ 

๊ฐ€์žฅ ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
์„ฑ์ˆ™ํ•œ ์ƒํƒœ๊ณ„
Podspec์œผ๋กœ ์„ธ๋ฐ€ํ•œ ์„ค์ •
Private Pod ์ง€์›
ObjC ์™„๋ฒฝ ์ง€์›
๐Ÿ‘Ž ๋‹จ์ 

Ruby ํ™˜๊ฒฝ ํ•„์š”
xcworkspace ๊ฐ•์ œ
ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์ˆ˜์ •
๋А๋ฆฐ pod install
Pods ํด๋” ์šฉ๋Ÿ‰ ํผ
CocoaPods ๋™์ž‘ ํ๋ฆ„๋„ โ‘  Podfile ์ž‘์„ฑ ์˜์กด์„ฑ ๋ชฉ๋ก ์ •์˜ ๋ฒ„์ „ ๋ฒ”์œ„ ์ง€์ • โ‘ก pod install CocoaPods Trunk ์—์„œ ๋‹ค์šด๋กœ๋“œ โ‘ข Pods/ ์ƒ์„ฑ ์†Œ์Šค์ฝ”๋“œ ์ €์žฅ Podfile.lock ์ƒ์„ฑ โ‘ฃ xcworkspace ํ†ตํ•ฉ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์ƒ์„ฑ CocoaPods ์ ์šฉ ํ›„ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ MyApp/ MyApp.xcworkspace โ† ์ด๊ฑธ๋กœ ์—ด์–ด์•ผ ํ•จ! โญ MyApp.xcodeproj Podfile Podfile.lock โ† Git ์ปค๋ฐ‹ ํ•„์ˆ˜! Pods/ โ† .gitignore ์ถ”๊ฐ€ ๊ถŒ์žฅ Alamofire/, Kingfisher/, SnapKit/, ... Sources/ (์•ฑ ์†Œ์Šค์ฝ”๋“œ) Tests/
๐Ÿน Carthage - ๋น„์นจ์Šต์  ์ฒ ํ•™์˜ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €

Carthage๋Š” "Simple, decentralized dependency manager for Cocoa"๋ฅผ ํ‘œ๋ฐฉํ•ด. CocoaPods์ฒ˜๋Ÿผ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ , ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋นŒ๋“œํ•ด์„œ ์ง์ ‘ ๋งํฌํ•˜๋Š” ๋ฐฉ์‹์ด์•ผ.

๐Ÿ”ง Carthage ์„ค์น˜
# Homebrew๋กœ ์„ค์น˜ (๊ถŒ์žฅ)
brew install carthage

# ๋ฒ„์ „ ํ™•์ธ
carthage version
๐Ÿ“„ Cartfile - Carthage์˜ ์„ค์ • ํŒŒ์ผ

Carthage๋Š” Cartfile์— ์˜์กด์„ฑ์„ ์ •์˜ํ•ด. ๋ฌธ๋ฒ•์ด ๋งค์šฐ ๊ฐ„๋‹จํ•จ!

# Cartfile ์˜ˆ์‹œ

# GitHub ์ €์žฅ์†Œ (๊ฐ€์žฅ ์ผ๋ฐ˜์ )
github "Alamofire/Alamofire" ~> 5.8
github "onevcat/Kingfisher" ~> 7.0
github "SnapKit/SnapKit" >= 5.6.0

# Git ์ €์žฅ์†Œ ์ง์ ‘ ์ง€์ •
git "https://my-private-server.com/MyLib.git" "main"

# ๋ฐ”์ด๋„ˆ๋ฆฌ ํ”„๋ ˆ์ž„์›Œํฌ (๋นŒ๋“œ ์—†์ด ๋ฐ”๋กœ ์‚ฌ์šฉ)
binary "https://my-server.com/MyFramework.json" ~> 2.0
โš™๏ธ Carthage ๋นŒ๋“œ ๋ฐ ์—…๋ฐ์ดํŠธ
# ์˜์กด์„ฑ ๋นŒ๋“œ (์ฒ˜์Œ ์„ค์น˜ ๋˜๋Š” Cartfile ๋ณ€๊ฒฝ ์‹œ)
# iOS์šฉ XCFramework ๋นŒ๋“œ (Xcode 12+, ๊ถŒ์žฅ)
carthage bootstrap --use-xcframeworks --platform iOS

# ์—…๋ฐ์ดํŠธ
carthage update --use-xcframeworks --platform iOS

# ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ ์—…๋ฐ์ดํŠธ
carthage update Alamofire --use-xcframeworks --platform iOS

# ๋นŒ๋“œ๋งŒ (๋‹ค์šด๋กœ๋“œ ์—†์ด)
carthage build --use-xcframeworks --platform iOS
๐Ÿ”— Xcode ํ”„๋กœ์ ํŠธ์— ํ”„๋ ˆ์ž„์›Œํฌ ์—ฐ๊ฒฐ

Carthage๋Š” ๋นŒ๋“œ ํ›„ ์ˆ˜๋™์œผ๋กœ Xcode ํ”„๋กœ์ ํŠธ์— ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์—ฐ๊ฒฐํ•ด์•ผ ํ•ด. ์ด๊ฒŒ CocoaPods์™€ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ !

1
Carthage/Build/ ํด๋”์—์„œ .xcframework ํŒŒ์ผ ํ™•์ธ
carthage bootstrap ์‹คํ–‰ ํ›„ Carthage/Build/iOS/ ๋˜๋Š” Carthage/Build/XCFrameworks/ ํด๋”์— ์ƒ์„ฑ๋จ
2
Xcode โ†’ Target โ†’ General โ†’ Frameworks, Libraries, and Embedded Content
์—ฌ๊ธฐ์— .xcframework ํŒŒ์ผ์„ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ
3
Build Phases์— carthage copy-frameworks ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€
์•ฑ ์Šคํ† ์–ด ์ œ์ถœ ์‹œ ๋ถˆํ•„์š”ํ•œ ์•„ํ‚คํ…์ฒ˜ ์ œ๊ฑฐ๋ฅผ ์œ„ํ•ด ํ•„์š” (XCFramework ์‚ฌ์šฉ ์‹œ ๋ถˆํ•„์š”ํ•  ์ˆ˜ ์žˆ์Œ)
# Build Phases โ†’ Run Script์— ์ถ”๊ฐ€ (๊ตฌํ˜• ๋ฐฉ์‹)
/usr/local/bin/carthage copy-frameworks

# Input Files:
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
$(SRCROOT)/Carthage/Build/iOS/Kingfisher.framework
๐Ÿ“ Carthage ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
MyApp/
โ”œโ”€โ”€ Cartfile              โ† ์˜์กด์„ฑ ์ •์˜
โ”œโ”€โ”€ Cartfile.resolved     โ† ๋ฒ„์ „ ์ž ๊ธˆ (Git ์ปค๋ฐ‹ ํ•„์ˆ˜!)
โ”œโ”€โ”€ Carthage/
โ”‚   โ”œโ”€โ”€ Build/           โ† ๋นŒ๋“œ๋œ ํ”„๋ ˆ์ž„์›Œํฌ (Git ์ปค๋ฐ‹ ์„ ํƒ)
โ”‚   โ”‚   โ”œโ”€โ”€ iOS/
โ”‚   โ”‚   โ””โ”€โ”€ XCFrameworks/
โ”‚   โ””โ”€โ”€ Checkouts/       โ† ์†Œ์Šค์ฝ”๋“œ ์ฒดํฌ์•„์›ƒ (Git ์ปค๋ฐ‹ ๋น„๊ถŒ์žฅ)
โ”œโ”€โ”€ MyApp.xcodeproj      โ† ์›๋ณธ ๊ทธ๋Œ€๋กœ! (xcworkspace ๋ถˆํ•„์š”)
โ””โ”€โ”€ Sources/
๐Ÿ’ก XCFramework vs Framework: Xcode 12๋ถ€ํ„ฐ --use-xcframeworks ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด XCFramework ํ˜•์‹์œผ๋กœ ๋นŒ๋“œ๋ผ. XCFramework๋Š” ์—ฌ๋Ÿฌ ํ”Œ๋žซํผ(iOS, macOS, Simulator)์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ์ง€์›ํ•ด์„œ ํ›จ์”ฌ ํŽธ๋ฆฌํ•ด!
โœ… Carthage์˜ ์žฅ๋‹จ์ 
๐Ÿ‘ ์žฅ์ 

ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ๋น„์นจ์Šต
xcworkspace ๋ถˆํ•„์š”
๋ถ„์‚ฐํ˜• (์ค‘์•™ ์„œ๋ฒ„ ์—†์Œ)
๋นŒ๋“œ ์บ์‹œ ํ™œ์šฉ ๊ฐ€๋Šฅ
ํ”„๋ ˆ์ž„์›Œํฌ ์žฌ์‚ฌ์šฉ
๐Ÿ‘Ž ๋‹จ์ 

์ˆ˜๋™ Xcode ์„ค์ • ํ•„์š”
๋นŒ๋“œ ์‹œ๊ฐ„ ๋งค์šฐ ๋А๋ฆผ
Swift ๋ฒ„์ „ ํ˜ธํ™˜์„ฑ ์ด์Šˆ
์ ์  ์ค„์–ด๋“œ๋Š” ์ง€์›
์„ค์ • ๋ณต์žก๋„ ๋†’์Œ
โš ๏ธ Carthage ํ˜„ํ™ฉ: ์†”์งํžˆ ๋งํ•˜๋ฉด Carthage๋Š” ํ˜„์žฌ ์‚ฌ์šฉ์ด ๋งŽ์ด ์ค„์—ˆ์–ด. SPM์ด ๊ฐ•๋ ฅํ•ด์ง€๋ฉด์„œ Carthage๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ๋Š˜๊ณ  ์žˆ๊ฑฐ๋“ . ์ƒˆ ํ”„๋กœ์ ํŠธ์—์„œ Carthage๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฑด ์ž˜ ์ƒ๊ฐํ•ด๋ด์•ผ ํ•ด!
์„ธ ๊ฐ€์ง€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ๋น„๊ต ๋ ˆ์ด๋” SPM CocoaPods Carthage ์„ค์น˜ ํŽธ์˜์„ฑ 95% 68% 50% ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ˜ 70% 98% 60% ๋นŒ๋“œ ์†๋„ 90% 60% 35% Xcode ํ†ตํ•ฉ 100% 75% 40% ๋ฏธ๋ž˜ ์ „๋ง 98% 65% 30% * ์ˆ˜์น˜๋Š” ์ƒ๋Œ€์  ๋น„๊ต๋ฅผ ์œ„ํ•œ ์ฐธ๊ณ ๊ฐ’์ž…๋‹ˆ๋‹ค
โš”๏ธ SPM vs CocoaPods vs Carthage ์™„์ „ ๋น„๊ต

์ž ์ด์ œ ์„ธ ๊ฐ€์ง€๋ฅผ ํ•œ๋ˆˆ์— ๋น„๊ตํ•ด๋ณด์ž! ํ‘œ๋กœ ์ •๋ฆฌํ•˜๋ฉด ์ดํ•ด๊ฐ€ ํ›จ์”ฌ ์‰ฌ์›€ ใ…‹ใ…‹

ํ•ญ๋ชฉ ๐ŸŽ SPM ๐Ÿฆ… CocoaPods ๐Ÿน Carthage
์ถœ์‹œ๋…„๋„ 2015๋…„ 2011๋…„ 2014๋…„
๊ฐœ๋ฐœ ์–ธ์–ด Swift Ruby Go
์„ค์ • ํŒŒ์ผ Package.swift Podfile Cartfile
์ž ๊ธˆ ํŒŒ์ผ Package.resolved Podfile.lock Cartfile.resolved
๋ณ„๋„ ์„ค์น˜ โŒ ๋ถˆํ•„์š” โœ… Ruby gem ์„ค์น˜ โœ… Homebrew ์„ค์น˜
xcworkspace โŒ ๋ถˆํ•„์š” โœ… ํ•„์ˆ˜ โŒ ๋ถˆํ•„์š”
ํ”„๋กœ์ ํŠธ ์ˆ˜์ • ์ตœ์†Œ ๋งŽ์Œ ์ˆ˜๋™ ์„ค์ •
๋นŒ๋“œ ๋ฐฉ์‹ ์†Œ์Šค ๋นŒ๋“œ ์†Œ์Šค ๋นŒ๋“œ ํ”„๋ ˆ์ž„์›Œํฌ ๋นŒ๋“œ
์ €์žฅ์†Œ ๋ฐฉ์‹ ๋ถ„์‚ฐํ˜• ์ค‘์•™์ง‘์ค‘ํ˜• ๋ถ„์‚ฐํ˜•
Linux ์ง€์› โœ… โŒ โŒ
Xcode ํ†ตํ•ฉ โญโญโญโญโญ โญโญโญ โญโญ
๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ˜ ์ฆ๊ฐ€ ์ค‘ ๊ฐ€์žฅ ๋งŽ์Œ ๊ฐ์†Œ ์ค‘
๐ŸŽฏ ์–ธ์ œ ๋ญ˜ ์จ์•ผ ํ• ๊นŒ?
๐ŸŽ SPM์„ ์„ ํƒํ•ด์•ผ ํ•  ๋•Œ
์ƒˆ ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ Swift 5.5+ ํ™˜๊ฒฝ Apple ์ƒํƒœ๊ณ„ ์ „์šฉ ํŒ€ ํ˜‘์—… ํ™˜๊ฒฝ CI/CD ํŒŒ์ดํ”„๋ผ์ธ

โ†’ 2024๋…„ ๊ธฐ์ค€ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ผ๋ฉด SPM์ด ๊ฑฐ์˜ ์ •๋‹ต์ด์•ผ. Apple์ด ๊ณต์‹ ์ง€์›ํ•˜๊ณ , Xcode ํ†ตํ•ฉ์ด ์™„๋ฒฝํ•˜๊ณ , ๋ณ„๋„ ์„ค์น˜๋„ ํ•„์š” ์—†์–ด. ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ SPM์„ ์ง€์›ํ•˜๋Š”์ง€๋งŒ ํ™•์ธํ•˜๋ฉด ๋จ!
๐Ÿฆ… CocoaPods๋ฅผ ์„ ํƒํ•ด์•ผ ํ•  ๋•Œ
๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ ์œ ์ง€๋ณด์ˆ˜ SPM ๋ฏธ์ง€์› ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•„์š” Objective-C ํ˜ผ์šฉ ํ”„๋กœ์ ํŠธ ํŒ€ ์ „์ฒด๊ฐ€ CocoaPods ์ต์ˆ™

โ†’ ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ๋‚˜ SPM์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ผญ ํ•„์š”ํ•  ๋•Œ. ๋˜๋Š” ํŒ€ ์ „์ฒด๊ฐ€ CocoaPods์— ์ต์ˆ™ํ•˜๊ณ  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋น„์šฉ์ด ํด ๋•Œ!
๐Ÿน Carthage๋ฅผ ์„ ํƒํ•ด์•ผ ํ•  ๋•Œ
๊ธฐ์กด Carthage ํ”„๋กœ์ ํŠธ ์œ ์ง€ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์ˆ˜์ • ์ ˆ๋Œ€ ๋ถˆ๊ฐ€ ๋นŒ๋“œ ์บ์‹œ ์ตœ๋Œ€ ํ™œ์šฉ ํ•„์š”

โ†’ ์†”์งํžˆ ์ƒˆ ํ”„๋กœ์ ํŠธ์—์„œ Carthage๋ฅผ ์„ ํƒํ•  ์ด์œ ๋Š” ๊ฑฐ์˜ ์—†์–ด. ๊ธฐ์กด Carthage ํ”„๋กœ์ ํŠธ๋ฅผ ์œ ์ง€๋ณด์ˆ˜ํ•˜๋Š” ์ƒํ™ฉ์ด ๋Œ€๋ถ€๋ถ„์ผ ๊ฑฐ์•ผ.
๐Ÿ”„ CocoaPods์—์„œ SPM์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ

๋งŽ์€ ํŒ€๋“ค์ด CocoaPods์—์„œ SPM์œผ๋กœ ์ด์ „ํ•˜๊ณ  ์žˆ์–ด. ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์ž!

๐Ÿ“‹ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
1
ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ๋ชจ๋“  Pod์ด SPM์„ ์ง€์›ํ•˜๋Š”์ง€ ํ™•์ธ
๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ GitHub ์ €์žฅ์†Œ์—์„œ Package.swift ํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ํ™•์ธ. ์—†์œผ๋ฉด SPM ๋ฏธ์ง€์›!
2
Xcode ๋ฒ„์ „ ํ™•์ธ (์ตœ์†Œ Xcode 11 ์ด์ƒ ํ•„์š”)
Xcode 12 ์ด์ƒ์„ ๊ฐ•๋ ฅ ๊ถŒ์žฅ. SPM์˜ iOS ์ง€์›์ด Xcode 11๋ถ€ํ„ฐ ์‹œ์ž‘๋๊ฑฐ๋“ .
3
Git ๋ธŒ๋žœ์น˜ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์„œ ์ž‘์—…
๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๋กค๋ฐฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๊ผญ ๋ณ„๋„ ๋ธŒ๋žœ์น˜์—์„œ ์ž‘์—…ํ•ด!
๐Ÿš€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋‹จ๊ณ„
# 1. CocoaPods ์ œ๊ฑฐ
pod deintegrate  # Xcode ํ”„๋กœ์ ํŠธ์—์„œ CocoaPods ์„ค์ • ์ œ๊ฑฐ
pod clean        # ์บ์‹œ ์ •๋ฆฌ

# 2. ๊ด€๋ จ ํŒŒ์ผ ์‚ญ์ œ
rm Podfile
rm Podfile.lock
rm -rf Pods/
rm MyApp.xcworkspace  # xcworkspace ์‚ญ์ œ (xcodeproj ๋‚จ๊ฒจ๋‘ )

# 3. Xcode์—์„œ SPM ํŒจํ‚ค์ง€ ์ถ”๊ฐ€
# File โ†’ Add Package Dependencies...
# ๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ GitHub URL ์ž…๋ ฅ

# 4. ๋นŒ๋“œ ํ…Œ์ŠคํŠธ
xcodebuild -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
๐Ÿ’ก ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒ: ํ•œ ๋ฒˆ์— ๋ชจ๋“  ๊ฑธ ๋ฐ”๊พธ๋ ค ํ•˜์ง€ ๋ง๊ณ , ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•˜๋‚˜์”ฉ SPM์œผ๋กœ ๊ต์ฒดํ•˜๋ฉด์„œ ๋นŒ๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒŒ ์•ˆ์ „ํ•ด. ํŠนํžˆ ๋Œ€ํ˜• ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ๋”์šฑ ์‹ ์ค‘ํ•˜๊ฒŒ!
โš ๏ธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ ์ฃผ์˜์‚ฌํ•ญ
๋ฆฌ์†Œ์Šค ๋ฒˆ๋“ค ์ฒ˜๋ฆฌ
CocoaPods๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™์œผ๋กœ ๋ฒˆ๋“ค์— ํฌํ•จ์‹œ์ผœ์ฃผ์ง€๋งŒ, SPM์€ Package.swift์— ๋ช…์‹œ์ ์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•ด. ์ด๋ฏธ์ง€, ํฐํŠธ, ์Šคํ† ๋ฆฌ๋ณด๋“œ ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๋ฉด ํŠนํžˆ ์ฃผ์˜!
Objective-C ๋ธŒ๋ฆฌ์ง• ํ—ค๋”
CocoaPods๋Š” ์ž๋™์œผ๋กœ ๋ธŒ๋ฆฌ์ง• ํ—ค๋”๋ฅผ ๊ด€๋ฆฌํ•ด์ฃผ์ง€๋งŒ, SPM์€ ์ˆ˜๋™ ์„ค์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์–ด. ObjC ์ฝ”๋“œ๊ฐ€ ๋งŽ์€ ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Œ.
๋นŒ๋“œ ์„ค์ • ์ฐจ์ด
CocoaPods์˜ post_install ์Šคํฌ๋ฆฝํŠธ์—์„œ ํ–ˆ๋˜ ๋นŒ๋“œ ์„ค์ •๋“ค์„ SPM์—์„œ๋Š” ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ด. ํŠนํžˆ SWIFT_VERSION์ด๋‚˜ IPHONEOS_DEPLOYMENT_TARGET ๊ฐ™์€ ์„ค์ •๋“ค.
๐Ÿ› ๏ธ ์‹ค์ „ ํŒ: ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋ฅผ ์ž˜ ์“ฐ๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์˜์กด์„ฑ ๊ด€๋ฆฌ ์ž์ฒด๋ฅผ ์ž˜ ํ•˜๋Š” ๊ฒŒ ๋” ์ค‘์š”ํ•ด! ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ์จ๋จน์„ ์ˆ˜ ์žˆ๋Š” ํŒ๋“ค์„ ๋ชจ์•˜์Œ ใ…‹ใ…‹

1๏ธโƒฃ ์˜์กด์„ฑ์€ ์ตœ์†Œํ™”ํ•˜๋ผ

์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์ •๋ง ํ•„์š”ํ•œ๊ฐ€?๋ฅผ ๋จผ์ € ๋ฌผ์–ด๋ด. ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ ํ•˜๋‚˜๋ฅผ ์œ„ํ•ด ์ˆ˜์‹ญ MB์งœ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฑด ์•ฑ ํฌ๊ธฐ๋„ ํ‚ค์šฐ๊ณ , ๋ณด์•ˆ ์ทจ์•ฝ์  ๋…ธ์ถœ ์œ„ํ—˜๋„ ๋†’์—ฌ. Swift ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ Apple ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ์ง€ ๋จผ์ € ํ™•์ธํ•ด๋ด!

2๏ธโƒฃ ๋ฒ„์ „ ์ž ๊ธˆ ํŒŒ์ผ์€ ๋ฐ˜๋“œ์‹œ Git์— ์ปค๋ฐ‹

Package.resolved, Podfile.lock, Cartfile.resolved ํŒŒ์ผ์€ ๋ฐ˜๋“œ์‹œ Git์— ํฌํ•จ์‹œ์ผœ์•ผ ํ•ด. ์ด ํŒŒ์ผ๋“ค์ด ์—†์œผ๋ฉด ํŒ€์›๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ฒ„์ „์„ ์“ฐ๊ฒŒ ๋˜๊ณ , "๋‚ด ์ปดํ“จํ„ฐ์—์„œ๋Š” ๋๋Š”๋ฐ?" ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•จ ใ…‹ใ…‹

3๏ธโƒฃ Pods ํด๋” Git ํฌํ•จ ์—ฌ๋ถ€

ํฌํ•จ ๊ถŒ์žฅ (์†Œ๊ทœ๋ชจ ํŒ€): ๋„คํŠธ์›Œํฌ ์—†์ด๋„ ๋นŒ๋“œ ๊ฐ€๋Šฅ, CI ์†๋„ ํ–ฅ์ƒ
๋ฏธํฌํ•จ ๊ถŒ์žฅ (๋Œ€๊ทœ๋ชจ ํŒ€): ์ €์žฅ์†Œ ํฌ๊ธฐ ์ ˆ์•ฝ, ์ถฉ๋Œ ๊ฐ์†Œ

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ .gitignore์— Pods/๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Podfile.lock๋งŒ ์ปค๋ฐ‹ํ•˜๋Š” ๊ฒŒ ์ผ๋ฐ˜์ ์ด์•ผ.

4๏ธโƒฃ ์˜์กด์„ฑ ์—…๋ฐ์ดํŠธ๋Š” ์‹ ์ค‘ํ•˜๊ฒŒ
# SPM - Package.resolved ํ™•์ธ ํ›„ ์—…๋ฐ์ดํŠธ
# Xcode โ†’ File โ†’ Packages โ†’ Update to Latest Package Versions

# CocoaPods - ํŠน์ • ํŒŸ๋งŒ ์—…๋ฐ์ดํŠธ
pod update Alamofire  # ์ „์ฒด ์—…๋ฐ์ดํŠธ ๋Œ€์‹  ๊ฐœ๋ณ„ ์—…๋ฐ์ดํŠธ

# ์—…๋ฐ์ดํŠธ ํ›„ ๋ฐ˜๋“œ์‹œ ์ „์ฒด ํ…Œ์ŠคํŠธ ์‹คํ–‰!
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
5๏ธโƒฃ Private ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ

ํšŒ์‚ฌ ๋‚ด๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํŒจํ‚ค์ง€๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์•Œ์•„๋‘๋ฉด ์ข‹์•„!

// SPM - Private ํŒจํ‚ค์ง€ (Package.swift)
.package(
    url: "https://github.com/mycompany/private-lib.git",
    from: "1.0.0"
)
// โ†’ GitHub/GitLab์—์„œ SSH ํ‚ค ๋˜๋Š” ํ† ํฐ ์„ค์ • ํ•„์š”

// CocoaPods - Private Podspec ์ €์žฅ์†Œ
source 'https://github.com/mycompany/private-specs.git'
source 'https://cdn.cocoapods.org/'

pod 'MyPrivateLib', '~> 1.0'
6๏ธโƒฃ CI/CD ํ™˜๊ฒฝ์—์„œ์˜ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ
# GitHub Actions์—์„œ SPM ์บ์‹œ ํ™œ์šฉ
- name: Cache SPM packages
  uses: actions/cache@v3
  with:
    path: |
      ~/Library/Developer/Xcode/DerivedData
      .build
    key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}

# CocoaPods ์บ์‹œ
- name: Cache CocoaPods
  uses: actions/cache@v3
  with:
    path: Pods
    key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
๐Ÿ’ก ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ Swift ๊ฐœ๋ฐœ ๊ด€๋ จ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•  ๋•Œ๋„, ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ๋ช…ํ™•ํžˆ ๋ฌธ์„œํ™”ํ•ด๋‘๋ฉด ํ˜‘์—…์ด ํ›จ์”ฌ ์ˆ˜์›”ํ•ด์ ธ. README์— ์–ด๋–ค ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋ฅผ ์“ฐ๋Š”์ง€, ์„ค์น˜ ๋ฐฉ๋ฒ•์€ ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ๊ผญ ์ ์–ด๋‘์ž!
๐Ÿ” ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ๋ฒ•

ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์“ฐ๋‹ค ๋ณด๋ฉด ์ง„์งœ ๋ณ„๋ณ„ ์—๋Ÿฌ๊ฐ€ ๋‹ค ๋‚˜์™€ ใ…‹ใ…‹ ์ž์ฃผ ๋งŒ๋‚˜๋Š” ๋ฌธ์ œ๋“ค ์ •๋ฆฌํ•ด๋ดค์–ด!

๐Ÿšจ SPM ๊ด€๋ จ ๋ฌธ์ œ
โŒ ๋ฌธ์ œ: "package at '...' is not a valid package"
์›์ธ: Package.swift ๋ฌธ๋ฒ• ์˜ค๋ฅ˜ ๋˜๋Š” URL์ด ์ž˜๋ชป๋จ
ํ•ด๊ฒฐ: Package.swift ๋ฌธ๋ฒ• ํ™•์ธ, URL์ด ์ •ํ™•ํ•œ GitHub ์ €์žฅ์†Œ URL์ธ์ง€ ํ™•์ธ. swift package describe๋กœ ํŒจํ‚ค์ง€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
โŒ ๋ฌธ์ œ: "no such module 'Alamofire'"
์›์ธ: ํŒจํ‚ค์ง€๊ฐ€ ํƒ€๊ฒŸ์— ์ œ๋Œ€๋กœ ์ถ”๊ฐ€๋˜์ง€ ์•Š์Œ
ํ•ด๊ฒฐ: Xcode โ†’ Target โ†’ General โ†’ Frameworks, Libraries, and Embedded Content์—์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ. ์—†์œผ๋ฉด + ๋ฒ„ํŠผ์œผ๋กœ ์ถ”๊ฐ€
โŒ ๋ฌธ์ œ: SPM ํŒจํ‚ค์ง€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์•ˆ ๋จ
ํ•ด๊ฒฐ: Xcode โ†’ File โ†’ Packages โ†’ Reset Package Caches ์‹คํ–‰. ๊ทธ๋ž˜๋„ ์•ˆ ๋˜๋ฉด DerivedData ํด๋” ์‚ญ์ œ ํ›„ ์žฌ๋นŒ๋“œ
๐Ÿšจ CocoaPods ๊ด€๋ จ ๋ฌธ์ œ
โŒ ๋ฌธ์ œ: "Unable to find a specification for 'PodName'"
์›์ธ: ๋กœ์ปฌ CocoaPods ์ŠคํŽ™ ์ €์žฅ์†Œ๊ฐ€ ์˜ค๋ž˜๋จ
ํ•ด๊ฒฐ: pod repo update ์‹คํ–‰ ํ›„ ๋‹ค์‹œ pod install
โŒ ๋ฌธ์ œ: "CocoaPods could not find compatible versions"
์›์ธ: ์—ฌ๋Ÿฌ ํŒŸ ๊ฐ„์˜ ๋ฒ„์ „ ์ถฉ๋Œ
ํ•ด๊ฒฐ: pod install --verbose๋กœ ์ƒ์„ธ ๋กœ๊ทธ ํ™•์ธ. ์ถฉ๋Œํ•˜๋Š” ํŒŸ๋“ค์˜ ๋ฒ„์ „ ๋ฒ”์œ„๋ฅผ ์กฐ์ •ํ•˜๊ฑฐ๋‚˜, pod update๋กœ ํ•ด๊ฒฐ ์‹œ๋„
โŒ ๋ฌธ์ œ: "The sandbox is not in sync with the Podfile.lock"
์›์ธ: Podfile.lock๊ณผ ์‹ค์ œ ์„ค์น˜๋œ ํŒŸ์ด ๋‹ค๋ฆ„
ํ•ด๊ฒฐ: pod install ์žฌ์‹คํ–‰. ๊ทธ๋ž˜๋„ ์•ˆ ๋˜๋ฉด Pods ํด๋” ์‚ญ์ œ ํ›„ pod install
โŒ ๋ฌธ์ œ: Ruby ๋ฒ„์ „ ๊ด€๋ จ ์—๋Ÿฌ
์›์ธ: macOS ๊ธฐ๋ณธ Ruby ๋ฒ„์ „์ด ๋„ˆ๋ฌด ๋‚ฎ๊ฑฐ๋‚˜ ๊ถŒํ•œ ๋ฌธ์ œ
ํ•ด๊ฒฐ: rbenv๋‚˜ rvm์œผ๋กœ Ruby ๋ฒ„์ „ ๊ด€๋ฆฌ. rbenv install 3.2.0 && rbenv global 3.2.0
๐Ÿšจ Carthage ๊ด€๋ จ ๋ฌธ์ œ
โŒ ๋ฌธ์ œ: "Build Failed" ์—๋Ÿฌ
์›์ธ: Swift ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ๋˜๋Š” Xcode ๋ฒ„์ „ ๋ฌธ์ œ
ํ•ด๊ฒฐ: carthage build --verbose๋กœ ์ƒ์„ธ ๋กœ๊ทธ ํ™•์ธ. --use-xcframeworks ์˜ต์…˜ ์ถ”๊ฐ€ ์‹œ๋„
โŒ ๋ฌธ์ œ: "Incompatible Swift version"
์›์ธ: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ˜„์žฌ Swift ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Œ
ํ•ด๊ฒฐ: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ตœ์‹  ๋ฒ„์ „ ํ™•์ธ. ๋˜๋Š” ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ SPM ๋ฒ„์ „์œผ๋กœ ๊ต์ฒด ๊ณ ๋ ค
๐Ÿ“ฆ ๋‚˜๋งŒ์˜ Swift ํŒจํ‚ค์ง€ ๋งŒ๋“ค๊ธฐ

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์“ฐ๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ๋„ ์•Œ์•„๋‘๋ฉด ์ข‹์•„! ํŠนํžˆ ํŒ€ ๋‚ด ๊ณตํ†ต ๋ชจ๋“ˆ์„ ํŒจํ‚ค์ง€๋กœ ๋งŒ๋“ค๋ฉด ์žฌ์‚ฌ์šฉ์„ฑ์ด ์—„์ฒญ ์˜ฌ๋ผ๊ฐ€๊ฑฐ๋“  ใ…‹ใ…‹

๐Ÿš€ SPM ํŒจํ‚ค์ง€ ์ƒ์„ฑ
# ์ƒˆ ํŒจํ‚ค์ง€ ์ƒ์„ฑ
mkdir MySwiftPackage
cd MySwiftPackage
swift package init --type library

# ์ƒ์„ฑ๋˜๋Š” ๊ตฌ์กฐ:
# MySwiftPackage/
# โ”œโ”€โ”€ Package.swift
# โ”œโ”€โ”€ README.md
# โ”œโ”€โ”€ Sources/
# โ”‚   โ””โ”€โ”€ MySwiftPackage/
# โ”‚       โ””โ”€โ”€ MySwiftPackage.swift
# โ””โ”€โ”€ Tests/
#     โ””โ”€โ”€ MySwiftPackageTests/
#         โ””โ”€โ”€ MySwiftPackageTests.swift

# ๋นŒ๋“œ ํ…Œ์ŠคํŠธ
swift build

# ํ…Œ์ŠคํŠธ ์‹คํ–‰
swift test
๐Ÿ“ Package.swift ์ž‘์„ฑ ์˜ˆ์‹œ
// Package.swift - ๋‚˜๋งŒ์˜ ๋„คํŠธ์›Œํ‚น ์œ ํ‹ธ๋ฆฌํ‹ฐ ํŒจํ‚ค์ง€
import PackageDescription

let package = Package(
    name: "NetworkKit",
    platforms: [
        .iOS(.v15),
        .macOS(.v12),
        .watchOS(.v8),
        .tvOS(.v15)
    ],
    products: [
        // ์™ธ๋ถ€์— ๋…ธ์ถœํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
        .library(
            name: "NetworkKit",
            targets: ["NetworkKit"]
        ),
    ],
    dependencies: [
        // ์ด ํŒจํ‚ค์ง€๊ฐ€ ์˜์กดํ•˜๋Š” ์™ธ๋ถ€ ํŒจํ‚ค์ง€
        .package(
            url: "https://github.com/Alamofire/Alamofire.git",
            .upToNextMajor(from: "5.8.0")
        ),
    ],
    targets: [
        .target(
            name: "NetworkKit",
            dependencies: ["Alamofire"],
            // ๋ฆฌ์†Œ์Šค ํฌํ•จ ์‹œ
            resources: [
                .process("Resources")
            ]
        ),
        .testTarget(
            name: "NetworkKitTests",
            dependencies: ["NetworkKit"]
        ),
    ],
    swiftLanguageVersions: [.v5]
)
๐ŸŒ GitHub์— ํŒจํ‚ค์ง€ ๋ฐฐํฌํ•˜๊ธฐ
1
GitHub์— ์ƒˆ ์ €์žฅ์†Œ ์ƒ์„ฑ (Public ๋˜๋Š” Private)
2
๋กœ์ปฌ ํŒจํ‚ค์ง€๋ฅผ GitHub์— ํ‘ธ์‹œ
3
GitHub์—์„œ Release ์ƒ์„ฑ (ํƒœ๊ทธ: 1.0.0 ํ˜•์‹์œผ๋กœ)
4
๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ URL๋กœ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ!
๐Ÿ’ก ์‹œ๋งจํ‹ฑ ๋ฒ„์ €๋‹(Semantic Versioning): ํŒจํ‚ค์ง€ ๋ฒ„์ „์€ MAJOR.MINOR.PATCH ํ˜•์‹์„ ๋”ฐ๋ผ์•ผ ํ•ด. MAJOR๋Š” Breaking Change, MINOR๋Š” ํ•˜์œ„ ํ˜ธํ™˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€, PATCH๋Š” ๋ฒ„๊ทธ ์ˆ˜์ •. SPM์˜ upToNextMajor๊ฐ€ ์ด ๊ทœ์น™์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ด!
๐Ÿ”ฎ 2024๋…„ ์ดํ›„ Swift ์˜์กด์„ฑ ๊ด€๋ฆฌ ํŠธ๋ Œ๋“œ

๋งˆ์ง€๋ง‰์œผ๋กœ ์•ž์œผ๋กœ์˜ ๋ฐฉํ–ฅ์„ฑ์„ ์งš์–ด๋ณด์ž. ๊ฐœ๋ฐœ ์ƒํƒœ๊ณ„๋Š” ๊ณ„์† ๋ณ€ํ•˜๋‹ˆ๊นŒ ํŠธ๋ Œ๋“œ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด!

๐Ÿ“ˆ SPM์˜ ๊ธ‰์„ฑ์žฅ

2019๋…„ Xcode 11์—์„œ iOS ์ง€์›์ด ์‹œ์ž‘๋œ ์ดํ›„ SPM ์ฑ„ํƒ๋ฅ ์ด ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ์–ด. ์ฃผ์š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค(Alamofire, Kingfisher, SnapKit, RxSwift ๋“ฑ)์ด ๋ชจ๋‘ SPM์„ ์ง€์›ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๊ณ , Apple๋„ ์ž์‚ฌ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์„ SPM์œผ๋กœ ๋ฐฐํฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์–ด.

2024๋…„ ๊ธฐ์ค€ ์ƒˆ๋กœ์šด iOS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ 90% ์ด์ƒ์ด SPM์„ ์ง€์›ํ•˜๊ณ  ์žˆ์–ด!

๐Ÿ”ง Swift 5.9+ ์ƒˆ๋กœ์šด SPM ๊ธฐ๋Šฅ๋“ค
// Swift 5.9 - ๋งคํฌ๋กœ(Macro) ํŒจํ‚ค์ง€ ์ง€์›
.target(
    name: "MyMacros",
    dependencies: [
        .product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
        .product(name: "SwiftCompilerPlugin", package: "swift-syntax")
    ]
),

// ์กฐ๊ฑด๋ถ€ ์˜์กด์„ฑ (ํ”Œ๋žซํผ๋ณ„)
.target(
    name: "MyTarget",
    dependencies: [
        .product(name: "CryptoKit", package: "swift-crypto",
                 condition: .when(platforms: [.linux]))
    ]
)
๐ŸŒ Swift Package Index

Swift Package Index๋Š” SPM ํŒจํ‚ค์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํ˜ธํ™˜์„ฑ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ์‚ฌ์ดํŠธ์•ผ. CocoaPods์˜ cocoapods.org์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•ด. Swift ๋ฒ„์ „ ํ˜ธํ™˜์„ฑ, ํ”Œ๋žซํผ ์ง€์› ์—ฌ๋ถ€๋ฅผ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ์ง„์งœ ์œ ์šฉํ•จ!

์žฌ๋Šฅ๋„ท์—์„œ iOS ๊ฐœ๋ฐœ ๊ด€๋ จ ์ง€์‹์„ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ํ”„๋ฆฌ๋žœ์„œ๋กœ ํ™œ๋™ํ•  ๋•Œ๋„, ์ด๋Ÿฐ ์ตœ์‹  ๋„๊ตฌ๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋Š” ๊ฒŒ ๊ฒฝ์Ÿ๋ ฅ์ด ๋ผ!

๐Ÿ“‰ CocoaPods์˜ ๋ฏธ๋ž˜

CocoaPods๋Š” ์—ฌ์ „ํžˆ ์ˆ˜๋งŒ ๊ฐœ์˜ ํŒจํ‚ค์ง€๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ๊ณ , ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ณ„์† ์‚ฌ์šฉ๋  ๊ฑฐ์•ผ. ํ•˜์ง€๋งŒ ์‹ ๊ทœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด CocoaPods ์ง€์›์„ ์ค‘๋‹จํ•˜๊ฑฐ๋‚˜ SPM๋งŒ ์ง€์›ํ•˜๋Š” ์ถ”์„ธ์•ผ. CocoaPods ํŒ€๋„ ์œ ์ง€๋ณด์ˆ˜ ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•œ ์ƒํƒœ๋ผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€๋Š” ๊ฑฐ์˜ ์—†์–ด.

๊ฒฐ๋ก : CocoaPods๋Š” ์ฃฝ์ง€ ์•Š์ง€๋งŒ, ์ƒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” SPM์ด ์ •๋‹ต!

๐Ÿน Carthage์˜ ํ˜„ํ™ฉ

Carthage๋Š” SPM์˜ ๋“ฑ์žฅ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์ด ์ค„์—ˆ์–ด. ์ฃผ์š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด Carthage ์ง€์›์„ ์ค‘๋‹จํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์ƒ๊ธฐ๊ณ  ์žˆ์Œ. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ(ํ”„๋ ˆ์ž„์›Œํฌ ๋นŒ๋“œ ์บ์‹œ ํ™œ์šฉ, ํŠน์ • ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ํ™˜๊ฒฝ)์—์„œ๋Š” ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ผ ์ˆ˜ ์žˆ์–ด.

ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์„ ํƒ ๊ฐ€์ด๋“œ ํ”Œ๋กœ์šฐ์ฐจํŠธ ์ƒˆ ํ”„๋กœ์ ํŠธ? Yes No ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ SPM ์ง€์›? Yes ๐ŸŽ SPM ๊ฐ•๋ ฅ ์ถ”์ฒœ! No ๐Ÿฆ… CocoaPods SPM ๋ฏธ์ง€์› ์‹œ ๊ธฐ์กด ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์œ ์ง€ or ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜? ์œ ์ง€ ๊ธฐ์กด ๋ฐฉ์‹ ์œ ์ง€ CocoaPods/Carthage ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๐ŸŽ SPM์œผ๋กœ ๋‹จ๊ณ„์  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ 2024๋…„ ๊ธฐ์ค€ ๊ถŒ์žฅ ์„ ํƒ ๊ฐ€์ด๋“œ
๐Ÿ“ ํ•ต์‹ฌ ์ •๋ฆฌ: ์˜ค๋Š˜ ๋ฐฐ์šด ๊ฒƒ๋“ค
๐ŸŽ SPM (Swift Package Manager)
โ€ข Apple ๊ณต์‹ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €, Xcode์— ๋‚ด์žฅ
โ€ข Package.swift๋กœ ์„ค์ •, Package.resolved๋กœ ๋ฒ„์ „ ์ž ๊ธˆ
โ€ข ์ƒˆ ํ”„๋กœ์ ํŠธ์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€, 2024๋…„ ๊ธฐ์ค€ ๊ฐ€์žฅ ๊ถŒ์žฅ
โ€ข ๋ณ„๋„ ์„ค์น˜ ๋ถˆํ•„์š”, xcworkspace ๋ถˆํ•„์š”
๐Ÿฆ… CocoaPods
โ€ข 2011๋…„๋ถ€ํ„ฐ ์‹œ์ž‘๋œ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €
โ€ข Podfile๋กœ ์„ค์ •, Podfile.lock์œผ๋กœ ๋ฒ„์ „ ์ž ๊ธˆ
โ€ข ๊ฐ€์žฅ ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณด์œ , ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉ
โ€ข Ruby ์„ค์น˜ ํ•„์š”, xcworkspace ํŒŒ์ผ ์ƒ์„ฑ
๐Ÿน Carthage
โ€ข 2014๋…„ ๋“ฑ์žฅ, ๋น„์นจ์Šต์  ์ฒ ํ•™์˜ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €
โ€ข Cartfile๋กœ ์„ค์ •, ํ”„๋ ˆ์ž„์›Œํฌ ๋นŒ๋“œ ๋ฐฉ์‹
โ€ข ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์ˆ˜์ • ์—†์Œ, ์ˆ˜๋™ Xcode ์„ค์ • ํ•„์š”
โ€ข ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ์†Œ ์ถ”์„ธ, ์ƒˆ ํ”„๋กœ์ ํŠธ ๋น„๊ถŒ์žฅ
๐ŸŽฏ ์ตœ์ข… ๊ฒฐ๋ก : 2024๋…„์— ์ƒˆ Swift ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด SPM์ด ์ •๋‹ต์ด์•ผ. ๊ธฐ์กด CocoaPods ํ”„๋กœ์ ํŠธ๋Š” ์ ์ง„์ ์œผ๋กœ SPM์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฑธ ๊ณ ๋ คํ•ด๋ด. Carthage๋Š” ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ์œ ์ง€๋ณด์ˆ˜ ์™ธ์—๋Š” ์ƒˆ๋กœ ์„ ํƒํ•  ์ด์œ ๊ฐ€ ๊ฑฐ์˜ ์—†์–ด!
๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.