Skip to content

Add manual for Swift Package Manager dependencies - #694

Merged
ekharkunov merged 1 commit into
masterfrom
extensions-spm
Nov 4, 2026
Merged

ekharkunov merged 1 commit into
masterfrom
extensions-spm

Conversation

@ekharkunov

@ekharkunov ekharkunov commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

@ekharkunov
ekharkunov marked this pull request as ready for review November 3, 2026 16:24
@ekharkunov
ekharkunov requested a review from britzl November 3, 2026 16:24
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T16:29:53.227140Z 8fbc697 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.


By default all Swift packages are combined into one static library which is linked into the engine executable.

Some SDKs cannot be combined into a static library, and the engine then fails to link with duplicate symbol errors. In this case set `"wrapperType": "dynamic"` in `SwiftPackages.json`. The packages are then built into a dynamic framework, which is embedded in the application bundle.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some SDKs cannot be combined into a static library, and the engine then fails to link with duplicate symbol errors

Why? Should we provide an example of when it does not work? Or is it enough to state this as a fact?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During testing LevelPlay produced "duplicate symbols" error because LevelPlay supplied as static library (not framework) and every ad adapter has LevelPlay as a dependency. I led to include LevelPlay into intermediate static library several times. I've implemented custom code for remove duplicated symbols from the intemediate library before final engine linkage. And now it builds ok if wrapperTpe = static. But who know what else can be and "dynamic" is and option to workaround it.


Copy this file into the extension, next to `SwiftPackages.json` (for example `manifests/ios/Package.resolved`), to lock the package versions. The build server then uses the locked versions as long as they match the requirements in `SwiftPackages.json`. It also makes the build faster: without a `Package.resolved` file the build server discovers the dependencies of the packages step by step, which can take a long time for packages with many dependencies.

If several extensions include a `Package.resolved` file for the same platform, only one of them is used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is mainly useful while iterating on an extension itself? Does it pick one at random? And what does it mean for the build? Will it finish successfully?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It picks the first Package.resolved from alphabetically sorted list. Packages.resolved is usual to cut the time needed for package resolution. We do it in several rounds because we don't allow to run custom swift code during package resolution. So we tried to download every package one-by-one into local cache and than run package resolution with local cache (to avoid network access). If package has it's own dependencies - cycle is repeated. In case if we will have Packages.resolved we can download package almost in one round because we know all needed information from Packages.resolved.


## Limitations

* Only package repositories that are publicly accessible over `https://` are supported. Swift package registries are not supported.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this might be requested at some point?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case we won't provide access to privately-hosted packages because it will require credentials for authentication for download package. It means we need transfer it from client to our server. The second, if we start using credentials it can lead to keychain access popup when xcodebuild builds.

We don't support Swift package registries right now because I didn't have any test with it and I can't be sure that nothing else needed from configuration point of view.

* Only package repositories that are publicly accessible over `https://` are supported. Swift package registries are not supported.
* The `Package.swift` files and plugins of the packages run without network access on the build server. The build server downloads the packages and their binary frameworks itself before the packages are built.
* Building packages that contain asset catalogs (`.xcassets`) for iOS requires a build server that uses Xcode 27 or later. With an earlier version of Xcode the build fails with an error that names these packages.
* The `SwiftPackages.json` files of a project can declare at most 32 packages and 64 products per platform.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this limitation come from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the limits that I introduced in Extender to avoid case when very-very-very large project tries to consume more resources for one build and takes more build time. Also we have limit for package resolution time (15 minutes).

Limitation regarding xcassets comes from how Xcode processed asset catalog. For processing it uses simulator. In XCode 27 Apple provide lightweight simulator runtime which xcode uses. In pre-27 version it requires for effort to configure and maintain. I decided to skip all pre-27 versions (they still can use Cocoapods version of extensions)

@britzl britzl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions. Otherwise good.

@britzl
britzl self-requested a review November 4, 2026 08:49
@ekharkunov
ekharkunov merged commit 9a34a36 into master Nov 4, 2026
3 checks passed
@ekharkunov
ekharkunov deleted the extensions-spm branch November 4, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants