Tomo.Log()


CocoaPodsのPodをSPM対応した話

[10/19, 2024]

日本語 / English

こんにちは、トモです。Cocoapodsがメンテナンスモードらしく、Xcode16への対応がされるのか不鮮明なので、自作のCocoaPodsたちをSPM対応することにしました。

今は少し知識がついたのでこのブログを書いて思ったのは、もっとSPMの構成に寄せてもよかったかなと思っていますwただもしも同じようなことをしたい人がいれば何かの助けになれば幸いです。

ここでは、SPMに対応してもcocoapodsでも引き作業を続き行えるようになっています。

流れ

  • SPMはフォルダの構成に変更する
  • podspecを変更した内容に合わせる
  • .workspaceの再生成
  • CocoaPodsとして認識できることを確認
  • Package.swiftの追加
  • SPMのパッケージとして認識されることを確認
  • SPMとしてAppから読み込んでみる

こんな感じになっています。

CocoaPodsのフォルダ構成をSPMように変更する

Pod_NameというPodがあったと仮定して、以下のように構成を変更しました。

変更前

Pod_Name/
    Pod_Name/
        Classes/
        Assets/
    Example/
    Pod_Name.podspec
    など

変更後(SPM用)

Pod_Name/
	Sources/
       Classes/
        Assets/
    Tests/
    Example/
    Pod_Name.podspec
    など

podspecを書き換える

変更したディレクトリに対応するようにpathを書き換えます。

変更前

s.source_files = 'Pod_Name/Classes/**/*'

s.resource_bundles = {
	'RFTextKit' => ['Pod_Name/Assets/*.png']
}

変更後(SPM用)

s.source_files = 'Sources/Classes/**/*'

s.resource_bundles = {
	'RFTextKit' => ['Sources/Assets/*.png']
}

Podとして読み込めることを確認する

Exampleの中でpod init か pod updateして.xcworkspaceを再生成する

.xcworkspaceを読み込んで起動して、ちゃんとファイルが認識できていることを確認する

Package.swiftを作成する

Package.swiftを直下(Pod_Name)に追加します。

Pod_Name/
	Sources/
    		Classes/
    		Assets/
    Tests/
    Example/
    Pod_Name.podspec
    Package.swift <--追加
    など

Package.swiftの中身

// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Pod_Name",
    platforms: [
        .iOS(.v12),
    ],
    products: [
        .library(
            name: "Pod_Name",
            targets: ["Pod_Name"]
        ),
        
    ],
    //依存関係がある場合は必要
    dependencies: [
        // BasePackageの依存関係を追加
        .package(url: "git@github.com:xxx/anotherpod.git", from: "1.0.0")
    ],
    targets: [
        .target(
            name: "MLanguage",
            //依存関係がある場合は必要
            dependencies: [
                .product(name: "AnotherPod", package: "anotherpod"),
            ],
           path: "Sources/Classes",
            resources: [
                .process("../Assets")
            ]
        ),
         .testTarget(
             name: "Pod_Name",
             dependencies: ["Pod_Name"]
         )
    ]
)

Dependencyが不要な場合は該当の箇所を削除してください。

自分まだ覚えたてで、理解しきっていないのですが、pathに"Sources/Classes"を指定してるので、Assetsのパスはそこを起点に相対パスで指定してあります。

SPMに寄せきって、Sourcesの直下にClassesのファイルを入れて、その中にAssetsを置いたらもっとシンプルでいいかもしれません。

SPMとして読み込めることを確認する

Xcodeは、フォルダの直下にPackage.swiftが入っているとそこを、SPMのフォルダとして認識してくれます。
なので追加したPackage.swiftを

Package.swiftを右クリック > Xcodeで開く

で開くとSPMのパッケージとしてXcodeが開かれます。

ここで問題なくビルドできるかなどを確認します。

SPM対応版のCommit

ここまでうまく行ったら、podspecのバージョンを上げてtagを打ってpushします。

IDEPackageSupportUseBuiltinSCMの設定

そもそも、SPM用のプライベートリポジトリにアクセするには

  • Xcodeでgithubなどに直接ログインしておく
  • Tokenを使う?(ちゃんと調べてないです😅)
  • Macの.sshの設定を使う

などがあるみたいです。

Cocoapodsでは.sshの設定が使えていたのでXcodeも同様にしたいところです。

調べていたところこちらの記事にIDEPackageSupportUseBuiltinSCMの設定をするとXcodeが.sshの設定を使用してくれると書いてありました。

defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM YES

最後のパラメータが

  • Yes : Xcodeが.sshの設定を使ってくれる
  • NO : Xcodeでログインなどの設定が必要

となっているようです。

この設定をYESにした状態で

Files > Add Package Dependencies... > から開く小窓の右上
この投稿をInstagramで見る

Tomolog(@tomologram)がシェアした投稿

Xcode16の場合はここに

git@github.com:xxxx/pod_name.git

SSH用のURLを入れると、ちゃんとロードしてパッケージリストに出てきたら成功です!!これであとはAppの本体へ追加してビルドできれば完成です!

これの良いところはcocoapodsのworkspaceで更新を続けながらSPMの対応もできるってところですね。

自分は自作のpodが数十個あるのでこれからちまちま対応していきたいと思います😭