Shipmark / Guides

How to generate an SBOM for an iOS app

Updated 14 November 2026 · 6 min read

In short

  • An iOS app usually has two dependency lockfiles: Podfile.lock for CocoaPods and Package.resolved for Swift Package Manager. Many apps have both.
  • Both record exact versions, so both can be turned into a CycloneDX SBOM. Each one covers only its own package manager, so merge them for one release.
  • Swift Package Manager is getting built-in SBOM generation (proposal SE-0509, accepted), but check that your toolchain has it before you rely on it.

What the CRA asks for

Annex I, Part II, point (1) of Regulation (EU) 2024/2847 requires manufacturers to "identify and document vulnerabilities and components contained in products with digital elements, including by drawing up a software bill of materials in a commonly used and machine-readable format covering at the very least the top-level dependencies of the products". The text names no format. CycloneDX and SPDX are the two usual choices, and this guide uses CycloneDX.

For an iOS app, "components" means the third-party libraries you link into the app. They come from CocoaPods, from Swift Package Manager, or from files you copied into the project by hand. Only the first two have a lockfile.

Step 1. Find your two lockfiles

Package managerFileWhere it lives
CocoaPodsPodfile.lockNext to your Podfile. It is generated by the first pod install and tracks the exact version of each pod installed.
Swift Package Manager in XcodePackage.resolvedInside your Xcode project or workspace bundle, in the xcshareddata/swiftpm folder (full paths below).

In an Xcode project the file is at the first path below, and in a workspace at the second:

MyApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
MyApp.xcworkspace/xcshareddata/swiftpm/Package.resolved

The CocoaPods guide says the Podfile and Podfile.lock should always be kept under version control. A later pod install honours the locked versions, and they change only when you edit the Podfile or run pod update. A developer writing about Xcode's Package.resolved also recommends checking it in, because it pins the exact package versions for every machine and for CI. If your repository ignores .xcodeproj or .xcworkspace bundles, add an exception so the file stays tracked.

If you use a cross-platform framework, the same files exist inside it: ios/Podfile.lock in Flutter and React Native projects.

Step 2. Turn them into CycloneDX

Option A: in your browser

Drop Podfile.lock or Package.resolved on the Shipmark free scanner. It builds a CycloneDX 1.6 SBOM locally and checks each version against OSV.dev. The file stays in your browser, and only package names and versions are sent to OSV.dev.

Option B: command-line tools

Several open-source tools read these files. We checked what their own documentation says:

ToolWhat its documentation says
cyclonedx-cocoapodsA Ruby gem (gem install cyclonedx-cocoapods) that creates a CycloneDX BOM from a CocoaPods project. It takes --path for the project directory and --output for the file. CocoaPods only, so it will not see Swift packages.
SyftLists Podfile.lock (CocoaPods cataloger) and Package.resolved (Swift Package Manager cataloger) as files it reads. Check its documentation for the CycloneDX output option of the version you install.

Whichever tool you use, test it on your own project and open the result. Confirm that the pod and package names, exact versions and package URLs (pkg:cocoapods/…, pkg:swift/…) look right, and that nothing you ship is missing. The free SBOM checker compares a CycloneDX or SPDX file with the CRA minimum.

Google's OSV-Scanner is a common choice for scanning lockfiles for known vulnerabilities, but the supported-lockfiles page we read lists neither Podfile.lock nor Package.resolved. It documents a route for unsupported lockfiles: convert them to its own osv-scanner.json format and pass that with --lockfile. Check the current page before you build a pipeline on it.

Step 3. Swift Package Manager is adding its own SBOM support

The Swift forums pitch for SBOM generation notes that Swift Package Manager currently lacks built-in SBOM support, and that external tools typically read Package.swift and Package.resolved, so they cannot tell which product uses which dependency. The proposal, SE-0509, was accepted in an announcement dated 27 February 2026. As pitched, it adds swift build --sbom-spec and a swift package generate-sbom subcommand, with CycloneDX and SPDX JSON output. The prototype did not capture XCFrameworks or artifact bundles.

The announcement does not say which Swift release ships it, so check your toolchain's release notes. Until you have confirmed it, the lockfile route above works today.

Step 4. Close the gaps lockfiles leave

These are our practical suggestions, not CRA text.

Step 5. Automate it in CI

The free open-source Shipmark SBOM action reads Podfile.lock on every build or release, among other lockfiles, writes one CycloneDX 1.6 SBOM and checks it against OSV.dev:

- uses: actions/checkout@v4
- uses: shipmark-eu/sbom-action@v1
  with:
    output: sbom-${{ github.ref_name }}.cdx.json

Common questions

Does my iOS app need an SBOM under the CRA?

If you place the app on the EU market as part of a commercial activity, Annex I, Part II, point (1) applies to you as manufacturer. See whether the CRA applies to mobile apps. The full set of requirements applies from 11 December 2027.

Is Podfile.lock enough if I also use Swift packages?

No. It lists only what CocoaPods installed. Swift packages resolved by Xcode are recorded in Package.resolved, so you need both.

Does the SBOM have to list every transitive dependency?

The CRA text requires "at the very least the top-level dependencies". Both lockfiles record resolved versions, so including everything they list costs little and helps you answer "are we affected?" quickly.

Turn your Podfile.lock or Package.resolved into a CycloneDX SBOM in seconds. No account, and the file stays in your browser.

Open the free scanner

Sources

This guide summarises Regulation (EU) 2024/2847 for practical use. Tool behaviour was read from each tool's documentation, not tested on your project. It is not legal advice. Related: SBOM for Flutter apps · SBOM for React Native apps · SBOM for Android apps · Technical documentation.