While Salesforce are retooling their CI/CD to produce SPM compatible versions of their iOS frameworks, we will try to maintain a compatible setup ourselves.
This repo contains a SPM Package.swift manifest and repackaged versions of the frameworks.
They are downloaded from the download link on the official page as
.zip archive (e.g. for the first version we added 238.0.0 https://dfc-data-production.s3.amazonaws.com/files/service_sdk_ios/238.0.0/ServiceSDK-238.0.0.zip).
In general, a framework should easily be wrapped as a SPM binary target, however ServiceSDK frameworks are umbrella frameworks that have dependency to other internal frameworks, which is discouraged by Apple and lead to inability to submit apps to App Store Connect.
For example, if we pack the frameworks directly as binary targets, we get the following errors:
The first error is caused by the
prepare-framework binary being included in the framework itself, because this binary is actually a perl script.
Just removing the
prepare-framework fixes the first error.
The second error, however is caused because there are subframeworks referenced within the ubmrella frameworks, for example
ServiceCore.framework has a subfolder
Frameworks where there is a
ServiceCommon.framework subframework dependency.
The official SalesForce documentation, says that we should run the
prepare-framework script after Embedding the frameworks in order to solve that problem.
What this script does it to
Frameworkssubfolder from each framework - fixing the second issue
However running that script as last run script build phase does not work, because when using SPM binary targets, the embed build phase is implicit and runs after all other xcode build pahses, which leads to inability to run the script at the right time.
Well, the solution might sounds easy - just remove the
prepare-framework script and the
Frameworks folder from each framework in advance, directly in the package.
Actually this is the right direction, however it is causing another issue. Because the subframework headers were removed, when compiling your app, it gets a build error that these headers are missing.
Fortunately, when declaring target dependencies in SPM, all dependent submodules are automatically exposed, we can create wrapper targets for each framework and include all the nececary headers.
Even better, we can directly mimic the umbrella frameowork structure by including the
Frameworks folders and the
Then we can remove the
Frameworks folder from the actual xcframework for
ios-arm64 architecture, zip it and use it as binary dependency.
Now, each time there is a new version of ServiceSDK, we have to solve the above problems. This can be done manually or automatically (see below for instructions).
ServiceCore.xcframework- remove the
ServiceCases.xcframework- remove the
ServiceKnowledge.xcframework- change the
@import ServiceCore;in the
ios-arm64architecture to the
ServiceSDK-iOSfor each wrapper target
update_frameworks.sh with a version argument, eg.
This will perform the steps described above by generating the wrappers and the package description.
Don't forget to test the package to make sure everything is working correcty, because there could be new individual cases, that has to be handled, like the need to modify another header's import.
At the end, when everytihng works correctly, commit, push and tag the updates.