XDSDK iOS SDK distributed through Swift Package Manager.
- iOS 13.0+ for
XDSDKCNandXDSDKDouYinGame - iOS 15.0+ for
XDSDKGlobalandXDSDKGlobalCrashlytics - Real device only. Simulator is not supported.
In Xcode, choose File → Add Package Dependencies..., then enter the XDSDK SPM repository URL:
https://github.com/xindong/XDSDK-SPM.git
If GitHub is not accessible from your network, use the GitCode URL instead:
https://gitcode.com/XDSDK/XDSDK-SPM.git
Choose the dependency rule based on the release stage:
- Stable releases: use
Up to Next Major Version, with the current stable version, for example7.9.0 - RC / beta validation: use
Exact Version, with the full prerelease version, for example7.9.0-rc.1
On the Add Package product selection page, add the Product you need to the App target. Main Products include payment support.
| Use case | Product |
|---|---|
| China mainland | XDSDKCN |
| Global | XDSDKGlobal |
| Global + Firebase Crashlytics | XDSDKGlobalCrashlytics |
| Douyin mini-game add-on (optional) | XDSDKDouYinGame |
Usually choose only one of XDSDKCN, XDSDKGlobal, and XDSDKGlobalCrashlytics. XDSDKDouYinGame is an optional add-on and should only be added when needed.
After adding the Product, the App target needs two Run Script Build Phases: one to copy resources, one to auto-configure Info.plist.
Both scripts are invoked directly from the SPM checkout. Do not copy them into your repo — this way they stay in sync when you upgrade the package.
In your App target → Build Phases, add a Run Script Phase named Copy XDSDK Resources with this body:
SCRIPT_PATH="${BUILD_DIR%/Build/*}/SourcePackages/checkouts/XDSDK-SPM/Scripts/copy_xdsdk_resources.sh"
if [[ -f "$SCRIPT_PATH" ]]; then
bash "$SCRIPT_PATH"
else
echo "warning: XDSDK SPM resource script not found at $SCRIPT_PATH"
fiThe script reads region_type from XDConfig.json: CN copies the common TapSDK4 plus CN resources, while Global copies the common TapSDK4 plus Oversea resources. Resources for the other region are no longer bundled into the .app.
Requirements:
- Move this phase to the end of Build Phases (after
Embed Frameworks/[CP] Embed Pods Frameworks) - Uncheck
Based on dependency analysis - In
Build Settings, setUser Script Sandboxing(ENABLE_USER_SCRIPT_SANDBOXING) toNO - The script looks for
${SRCROOT}/${PRODUCT_NAME}/XDConfig.jsonby default. If the config lives elsewhere, setXDSDK_CONFIG_PATH=/absolute/path/XDConfig.jsonin this Run Script
Reads XDConfig.json from the App project and uses region_type to write only the current region's CFBundleURLTypes / LSApplicationQueriesSchemes, plus the required Facebook top-level keys for Global configs. Common XDSDK / TapTap entries are generated for both regions; CN configs generate only domestic platform entries such as WeChat, QQ, Weibo, XiaoHongShu, DouYin, and KuaiShou, while Global configs generate only Facebook, Line, Twitter, Google, and TikTok entries.
Add a second Run Script Phase named Configure XDSDK Info.plist:
SCRIPT_PATH="${BUILD_DIR%/Build/*}/SourcePackages/checkouts/XDSDK-SPM/Scripts/configure_xdsdk_info_plist.py"
if [[ -f "$SCRIPT_PATH" ]]; then
/usr/bin/env python3 "$SCRIPT_PATH"
else
echo "warning: XDSDK SPM info-plist script not found at $SCRIPT_PATH"
fiRequirements:
- Place this phase before
Compile Sources - Uncheck
Based on dependency analysis - Set
User Script SandboxingtoNO - The script looks for the config at
${SRCROOT}/${PRODUCT_NAME}/XDConfig.jsonby default. If it lives elsewhere, setXDSDK_CONFIG_PATH=/absolute/path/XDConfig.jsonin the Run Script env
If one App explicitly ships multiple CN / Global configs, set the same colon-separated XDSDK_EXTRA_CONFIG_PATHS value in both Run Script Phases. The scripts will merge the plist entries and regional resources required by those configs. Facebook top-level keys are resolved across all Global configs; the build fails if different configs provide conflicting FacebookAppID or FacebookClientToken values instead of silently choosing one.
Product → Clean Build Folder, then build. The build log should show Copied <BundleName>.bundle lines, and the produced .app (right-click → Show Package Contents) should contain the corresponding .bundle directories at its root.
If you use XDSDKGlobalCrashlytics, add a Run Script Phase named Upload Crashlytics Symbols:
SCRIPT_PATH="${BUILD_DIR%/Build/*}/SourcePackages/checkouts/XDSDK-SPM/Scripts/FirebaseCrashlytics/run"
if [[ -f "$SCRIPT_PATH" ]]; then
"$SCRIPT_PATH"
else
echo "warning: Firebase Crashlytics script not found at $SCRIPT_PATH"
fiRequirements:
- Place this phase after
Embed Frameworks/[CP] Embed Pods Frameworks(the script needs the dSYM produced by linking) - Uncheck
Based on dependency analysis - Set
User Script SandboxingtoNO - Add
$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)and$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)to the script's Input Files so it picks up the dSYM correctly
- Multi-target apps (App + App Clip + Extensions): every target that needs the resources / schemes must add its own copy of both Run Script Phases
- CI / Xcode Cloud need the same sandbox settings
CFBundleURLNameentries prefixed withxdsdk.are managed by the script and will be overwritten on every build — editXDConfig.jsoninstead- Binary distribution: the
.xcframework.zipfiles are downloaded from URLs declared inPackage.swift