braintree_ios icon indicating copy to clipboard operation
braintree_ios copied to clipboard

Braintree iOS SDK takes a long amount of time to resolve via SPM

Open waitbutY opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe.

In our app, we have 40-50 SPM dependencies, and Braintree is in the top 3 slowest packages to resolve.

Describe the solution you'd like.

This is a known SPM issue, as SPM by default pulls not just the code but all the branches and commit history, etc. https://github.com/swiftlang/swift-package-manager/issues/6062

Some larger repositories have solved this by creating a separate repo that just points to the precompiled XCFramework, resulting in much, much smaller and faster package resolution.

Example, Lottie: https://github.com/airbnb/lottie-spm

Can Braintree SDK be offered in this way for iOS app consumption?

waitbutY avatar Jul 02 '24 01:07 waitbutY

Hello @waitbutY - thank you for bringing this to our attention. I do see that SPM does a git clone --mirror (snippet) which copies all ref, remotes, & branches.

This is something we would love to improve. My first idea of why our SDK is so massive is the way we store our 3rd party dependencies (in a local Frameworks dir). We will explore this route, as well as others, to see how we can get the SPM install time down.

Will update this ticket once we're able to prioritize this initiative. Any other concerns please don't hesitate to bring them to our attention - any feedback helps us greatly!

scannillo avatar Jul 02 '24 13:07 scannillo

Just wanted to throw in my two cents to second the original suggestion here of offering Braintree's SDKs as precompiled binary targets. Running git clone --mirror against this repo pulls down 557 MB due to the depth of the history, whereas a single branch is only 12 MB. In lieu of SPM offering any way to perform a shallow fetch, binary targets referencing precompiled .xcframework(s) stored outside the repo seems to be emerging as the most common way of providing quick package resolution for packages with large repositories. As another data point, AWS utilizes the same approach for consuming their iOS SDK via SPM.

sphanley avatar Aug 26 '24 01:08 sphanley

The reasons for SPM size is due to Cardinal and Magnes which we are unable to decouple from the SDK due to security. Since the SDK relies on these libraries, the SPM size is out of our hands. This wasn't necessarily intentional but it's unfortunately unavoidable.

stechiu avatar Jun 12 '25 20:06 stechiu

Hi @stechiu! I'm hoping I can get you to take a second look at what's being proposed here, as I believe there is an actionable suggestion. I definitely recognize that the compiled Cardinal and Magnes frameworks are the largest part of the codebase. But as I noted above, those frameworks are 2.6 MB and 4.6 MB, respectively, and the whole repository's contents for a given commit are approximately 12 MB, which is fairly typical for a Swift package, and poses no problem in and of itself.

Rather, the problem is that as described in the link provided by @waitbutY, SPM is implemented such that when it resolves a package, it does so by doing a full-depth checkout, including the entire repository history. This means that (at least as of when I last measured it in August 2024) for this Braintree repository, SPM is checking out 557 MB of repository history when it only actually needs the 12 MB that comprises the specific tagged version.

There's a pattern utilized by many other vendors such as AWS, AppDynamics, and Lottie, by which the developers create a separate repository which only houses the Package.swift files, and then reference binary targets which are stored as zip files external to the repo. Since the Package.swift file is very small and is only changed (to update the binary target URLs) when a new release is tagged, this means that even if the repo where you store your sources has a large and complex history, the repo which SPM is pointed to will always remain small and lightweight.

I hope this makes sense– if Braintree would consider implementing this same pattern, it would hugely improve performance for customers who are resolving this SDK via SPM. Thanks in advance for your consideration!

sphanley avatar Jun 17 '25 20:06 sphanley