Creating a signed Swift package collection

Swift 5.5 brought us a new feature which allows creating Swift package collections (SE-0291). In this blog post we’ll go through required steps and create a package collection with Augmented Code packages. At the time of writing, there is only one package: IndexedDataStore.

Install Swift Package Collection Generator

First, we’ll need to install a tool which Apple created for package collections. It is called Swift Package Collection Generator. We’ll need to clone the repository, build it and then either using the built tools in their current location or also installing them to /usr/local/bin for easy access later on.


git clone https://github.com/apple/swift-package-collection-generator.git
cd swift-package-collection-generator
swift build --configuration release
install .build/release/package-collection-generate /usr/local/bin/package-collection-generate
install .build/release/package-collection-diff /usr/local/bin/package-collection-diff
install .build/release/package-collection-sign /usr/local/bin/package-collection-sign
install .build/release/package-collection-validate /usr/local/bin/package-collection-validate

Collection description in JSON

When the tool is installed, then the next step is to create a definition for the collection. Supported keys in that JSON file are available here: PackageCollectionsModel/Formats/v1.md.

{
  "name": "Augmented Code Collection",
  "overview": "Packages created by Augmented Code",
  "author": {
    "name": "Toomas Vahter"
  },
  "packages": [
    { "url": "https://github.com/laevandus/IndexedDataStore.git" }
  ]
}

Next step is to feed that JSON into the package-collection-generate tool which fetches additional metadata for these packages (–auth-token argument with GitHub personal access token must be used if the GitHub access is not already set up with SSH).

package-collection-generate input.json output.json --verbose --pretty-printed

The output.json looks like this:

{
  "formatVersion" : "1.0",
  "generatedAt" : "2022-01-08T07:05:44Z",
  "generatedBy" : {
    "name" : "Toomas Vahter"
  },
  "name" : "Augmented Code Collection",
  "overview" : "Packages created by Augmented Code",
  "packages" : [
    {
      "keywords" : [

      ],
      "license" : {
        "name" : "MIT",
        "url" : "https://raw.githubusercontent.com/laevandus/IndexedDataStore/main/LICENSE"
      },
      "readmeURL" : "https://raw.githubusercontent.com/laevandus/IndexedDataStore/main/README.md",
      "url" : "https://github.com/laevandus/IndexedDataStore.git",
      "versions" : [
        {
// … version descriptions which are pretty long

Signing the package collection

Before we go ahead and sign the package collection, we’ll need to prepare certificates. Open Keychain Access and then from the main menu Keychain Access > Certificate Assistant > Request Certificate from a Certificate Authority. Use your email and name and check the “Saved to disk” option. The next step is uploading the certificate request file to Apple. Uploading is done in Certificates, Identifiers & Profiles by tapping on the plus button and selecting Swift Package Collection Certificate. After clicking on the Continue button, we can upload the certificate request file we created with the Keychain Access. After that, we’ll download the certificate and double-clicking on the certificate file adds it to Keychain Access. Before we can sign the collection, the next step is exporting the private key from Keychain Access. Look for “Swift Package Collection” certificate, expand the item which reveals the private key, right-click on it and export it (set a password). Keychain Access creates .p12 file, which we’ll need to convert to .pem (set a password when asked). In the example below, I saved the exported private key to swift_package.p12.

openssl pkcs12 -nocerts -in swift_package.p12 -out swift_package.pem
openssl rsa -in swift_package.pem -out swift_package_rsa.pem

Now we have ready for signing the package collection as we have .cer and .pem files prepared.

package-collection-sign output.json output-signed.json swift_package_rsa.pem swift_package.cer

When the command is successful, we have an output-signed.json file, which we can share and add to Xcode.

Adding a new package collection

A new package collection can be added in Xcode by navigating to File > Add Packages sheet and clicking on the plus button and selecting Add Swift Package Collection. Xcode asks for a https URL of the collection. One option is to upload the signed collection json file to GitHub and then passing in an URL to the raw representation of the file. The URL to Augmented Code’s package collection is available here.

Package collection view in Xcode showing added Augmented Code Packages collection.
Package collection view in Xcode.

If this was helpful, please let me know on Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.