Tomo.Log()


Making My CocoaPods Compatible with SPM

[10/19, 2024]

日本語 / English

Hi, this is Tomo. Since CocoaPods seems to be in maintenance mode, and it's unclear if it will support Xcode 16, I decided to make my custom CocoaPods compatible with Swift Package Manager (SPM).

Looking back, I could have structured things even more towards SPM. But hopefully, this post will help others trying to do the same.

In this post, I’ll show how to make your project compatible with both SPM and CocoaPods.

Process

  • Adjust the folder structure for SPM.
  • Update the podspec file.
  • Regenerate .xcworkspace.
  • Verify CocoaPods functionality.
  • Add Package.swift.
  • Verify SPM functionality.
  • Test in an app.

Adjust the Folder Structure for SPM

Let's say you have a Pod named "Pod_Name". Change the structure as follows:

Before:

Pod_Name/
    Pod_Name/
        Classes/
        Assets/
    Example/
    Pod_Name.podspec
    etc..

After (for SPM):

Pod_Name/
	Sources/
       Classes/
        Assets/
    Tests/
    Example/
    Pod_Name.podspec
    etc...

Update the podspec File

Update the paths to match the new structure.

Before:

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

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

After (for SPM):

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

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

Verify CocoaPods Functionality

Regenerate the .xcworkspace by running pod init or pod update in the Example folder. Make sure the project works properly.

Create the Package.swift File

Add Package.swift to the root of the project (Pod_Name).

Updated structure:

Pod_Name/
	Sources/
    		Classes/
    		Assets/
    Tests/
    Example/
    Pod_Name.podspec
    Package.swift <--Added
    etc...

Package.swift contents:

// 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: [
        //Add dependency for AnotherPod if needed
        .package(url: "git@github.com:xxx/anotherpod.git", from: "1.0.0")
    ],
    targets: [
        .target(
            name: "MLanguage",
            dependencies: [
                // Add dependency for AnotherPod if needed
                .product(name: "AnotherPod", package: "anotherpod"),
            ],
           path: "Sources/Classes",
            resources: [
                .process("../Assets")
            ]
        ),
         .testTarget(
             name: "Pod_Name",
             dependencies: ["Pod_Name"]
         )
    ]
)

If no dependencies are required, remove the relevant parts.

I'm still new to this, so I'm not fully confident yet. Since the path is set to "Sources/Classes," I've used a relative path from there to specify the location of the assets.

If I fully adapt the structure to SPM, I could make things simpler by placing the asset files directly under Sources, alongside the class files, without using nested directories. This would make the setup more straightforward.

Verify SPM Functionality

When Xcode finds Package.swift at the project’s root, it will recognize the folder as an SPM package. Right-click Package.swift, open it with Xcode, and check if the project builds properly.

Commit the SPM-Compatible Version

If everything works, update the version in your podspec, tag it, and push it to your repository.

Configuring IDEPackageSupportUseBuiltinSCM

For private SPM repositories, access can be done by:

  • Logging into GitHub through Xcode.
  • Using a token (I haven't looked into this much 😅).
  • Using SSH settings from your Mac.

CocoaPods works with SSH settings, and we want Xcode to do the same. I found this helpful article suggesting that setting IDEPackageSupportUseBuiltinSCM to YES allows Xcode to use SSH configurations.

defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM YES

The last parameter:

  • YES: Xcode uses SSH settings.
  • NO: Xcode requires login settings.

Once this is set to YES, navigate to:

Files > Add Package Dependencies... > Then Open The Window
この投稿をInstagramで見る

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

In Xcode 16, enter your SSH URL (e.g., git@github.com:xxxx/pod_name.git) in the popup. If the package loads successfully, you’re good to go! Then, add the package to your app, build it, and you're done.

The best part? You can still maintain CocoaPods support while migrating to SPM!

Since I have dozens of custom pods, I’ll be gradually migrating them over 😭.