Skip to content

iOS 准备工作 ​

版本号规则 ​

适配器版本号说明

优聚智汇 SDK 的适配器版本号采用「三方 SDK 版本 + 适配器迭代版本」的命名规则:

  • 前半部分:表示适配的三方广告网络 SDK 版本。
  • 后半部分:表示适配器自身的迭代版本。

集成时请确保使用与第三方 SDK 版本匹配的适配器,避免因版本不匹配导致功能异常。

开发环境要求 ​

项目要求
iOS 部署目标iOS 13.0 及以上
Swift 版本Swift 5.9 及以上
Xcode 版本Xcode 15 及以上(推荐 Xcode 26+)
开发语言Swift 5 / Swift 6
架构arm64(真机)/ arm64 + x86_64(模拟器)
依赖工具Xcode / CocoaPods(可选)

注意:SDK 不支持 macOS 平台编译,UjuAdCore.xcframework 为 iOS-only。

注意:SDK 仅提供 Swift 公开 API(含 struct、Sendable 协议、Builder 模式等 Swift 独有特性),未提供独立的 Objective-C 兼容层。纯 Objective-C 项目需通过 Swift 混编 + 自行封装 @objc wrapper 接入,详见 FAQ Q17。

SDK 组件关系 ​

优聚智汇 iOS SDK 由两个组件构成,按需引入:

组件说明是否必选
UjuAdCore核心 SDK,提供优聚 Adx 竞价 + 5 种广告格式(开屏 / 激励视频 / 插屏 / 横幅 / 原生)必选
UjuAdExt优聚智汇预算包,扩展广告填充来源,支持更多广告源竞价必选
┌─────────────────────────────────────────┐
│            集成方 App                    │
├─────────────────────────────────────────┤
│  UjuAdExt(必选)                       │
│  └── 内部 DSP 适配器(已打包)          │
│       ↓ 依赖                            │
│  UjuAdCore(必选)                      │
│  ├── 优聚 Adx 竞价                      │
│  ├── 配置服务 / 埋点上报                │
│  └── 广告加载 / 渲染 / 展示             │
└─────────────────────────────────────────┘

当前版本能力边界

  • UjuAdCore(已提供):优聚 Adx 广告能力,5 种广告格式,通过优聚 Adx 竞价填充
  • UjuAdExt(已提供):优聚智汇预算包,扩展广告填充来源,支持更多广告源竞价
  • 聚合第三方 ADN(开发中):穿山甲 / 百度 / 优量汇 / 快手等,将在后续版本提供,上线后无需改动集成代码

集成方式 ​

提供两种集成方式,gRPC-Swift / SwiftProtobuf / SwiftNIO 等第三方依赖已静态链接进 xcframework,集成方无需也不应再引入这些依赖。

方式适用场景网络依赖推荐度
XCFramework生产环境,开箱即用无★★★
CocoaPods使用 CocoaPods 管理依赖的项目无★★

方式一:XCFramework 集成(推荐) ​

步骤 1:获取 xcframework ​

从 Gitee Release UjuAdCore-3.4.2 下载 UjuAdCore-3.4.2.xcframework.zip,解压后产物结构如下:

UjuAdCore.xcframework/
├── Info.plist                          # xcframework 元信息
├── ios-arm64/                          # 真机 slice
│   ├── libUjuAdCore-iphoneos.a         # 静态库(含 gRPC/Protobuf/NIO 静态链接)
│   └── Headers/                        # swiftmodule + C 模块(编译时需要)
│       ├── UjuAdCore.swiftmodule/      # SDK 公开 API 模块
│       │   ├── arm64-apple-ios.swiftmodule
│       │   ├── .swiftdoc
│       │   └── .swiftsourceinfo
│       ├── UjuAdCoreProtos.swiftmodule/ # Proto 模块(SDK 内部依赖,必须打包)
│       ├── GRPC.swiftmodule/           # gRPC 模块(静态链接,集成方无需引入)
│       ├── SwiftProtobuf.swiftmodule/
│       ├── NIO.swiftmodule/
│       └── _AtomicsShims/              # C 模块(swift-atomics 桥接)
├── ios-arm64_x86_64-simulator/         # 模拟器 slice(arm64 + x86_64 双架构)
│   ├── libUjuAdCore-simulator.a
│   └── Headers/
│       └── ...(同上,含 arm64 + x86_64 双架构 swiftmodule)
└── UjuAdCore.version.json              # 版本元信息

静态库 vs 动态库

UjuAdCore.xcframework 为 静态库类型(.a + Headers),不是动态框架(.framework)。静态库在编译期链接到宿主 App,无需嵌入(Do Not Embed),不会增加启动时的 dyld 加载时间。

.a 文件名注意

真机 slice 的静态库文件名为 libUjuAdCore-iphoneos.a(带 -iphoneos 后缀),模拟器 slice 为 libUjuAdCore-simulator.a(带 -simulator 后缀)。配置 OTHER_LDFLAGS 时请使用完整文件名,不要误写为 libUjuAdCore.a。

步骤 2:添加到 Xcode 项目 ​

  1. 将 UjuAdCore.xcframework 拖入项目根目录的 Frameworks/ 子目录(如不存在则创建)
  2. 在 Xcode 中选择项目 → Target → General 标签页
  3. 滚动到 Frameworks, Libraries, and Embedded Content 区域
  4. 点击 + 按钮 → 选择 Add Other... → Add Files... → 选中 UjuAdCore.xcframework
  5. 确认 Embed 选项为 Do Not Embed(静态库无需嵌入)

步骤 3:配置 Build Settings ​

在 Target → Build Settings 中,点击 + 添加以下自定义配置。每项均为必填,缺一会导致编译错误或运行时崩溃:

配置项值作用
SWIFT_ENABLE_EXPLICIT_MODULESNO关闭 Xcode 26+ 的 explicit modules,确保能读取 xcframework 中的 .swiftmodule 二进制文件
SWIFT_INCLUDE_PATHS[sdk=iphoneos*]$(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/Headers指定真机编译时的 swiftmodule 搜索路径
SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]$(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/Headers指定模拟器编译时的 swiftmodule 搜索路径
OTHER_LDFLAGS[sdk=iphoneos*]-force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/libUjuAdCore-iphoneos.a强制加载静态库全部 .o,防止泛型类型元数据被 dead-strip
OTHER_LDFLAGS[sdk=iphonesimulator*]-force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/libUjuAdCore-simulator.a同上,模拟器 slice
ENABLE_DEBUG_DYLIBNO关闭 Xcode 26 的 Debug Dylib 特性,避免符号跨 dylib 边界冲突

为什么需要 -force_load?

SDK 静态链接了 swift-atomics,其中 ManagedAtomic<Value> 是带 @_alwaysEmitIntoClient 标记的泛型 class。该标记导致类型元数据访问器在静态库按需链接模式下被误判为"未引用"而 dead-strip,运行时 __allocating_init 拿到 nil metadata → EXC_BAD_ACCESS 崩溃。-force_load 强制保留全部 .o,是当前唯一可靠的修复手段(详见 FAQ Q12)。

为什么需要 SWIFT_INCLUDE_PATHS?

UjuAdCore.xcframework 为 library 类型(.a + Headers),Xcode 不会自动将 Headers 目录加入 swiftmodule 搜索路径。必须显式指定,否则编译报 no such module 'UjuAdCore'。

xcconfig 文件配置(推荐)

建议将 Build Settings 配置写入 .xcconfig 文件,便于版本管理和多 Target 复用:

text
// UjuAdCore.xcconfig
SWIFT_ENABLE_EXPLICIT_MODULES = NO
ENABLE_DEBUG_DYLIB = NO

SWIFT_INCLUDE_PATHS[sdk=iphoneos*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/Headers
SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/Headers

OTHER_LDFLAGS[sdk=iphoneos*] = $(inherited) -force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/libUjuAdCore-iphoneos.a
OTHER_LDFLAGS[sdk=iphonesimulator*] = $(inherited) -force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/libUjuAdCore-simulator.a

在 Target → Build Settings → Configuration Set 中引用此 xcconfig 文件即可。

步骤 4:验证集成 ​

swift
import UjuAdCore

print("SDK 版本: \(UjuAdCore.shared.getVersion())")
// 输出: SDK 版本: 3.4.2

编译运行,确认无 no such module / undefined symbol 错误即集成成功。

集成验证清单:

  • [ ] UjuAdCore.xcframework 已添加到 Frameworks, Libraries, and Embedded Content
  • [ ] Embed 选项为 Do Not Embed
  • [ ] SWIFT_ENABLE_EXPLICIT_MODULES 设为 NO
  • [ ] SWIFT_INCLUDE_PATHS 已配置真机和模拟器两个 slice
  • [ ] OTHER_LDFLAGS 已配置 -force_load(真机用 libUjuAdCore-iphoneos.a,模拟器用 libUjuAdCore-simulator.a)
  • [ ] ENABLE_DEBUG_DYLIB 设为 NO
  • [ ] import UjuAdCore 编译通过
  • [ ] UjuAdCore.shared.getVersion() 输出 3.4.2

步骤 5:集成 UjuAdExt 预算包 ​

如需扩展广告填充来源(额外 DSP 适配器),引入 UjuAdExt:

  1. 从 Gitee Release UjuAdExt-3.4.2 下载 UjuAdExt-3.4.2.xcframework.zip
  2. 解压后,将 UjuAdExt.xcframework 及其内部包含的所有第三方 SDK 和资源按 zip 中的目录结构拖入项目 Frameworks/ 目录
  3. 在 Build Settings 中追加(不是覆盖)UjuAdExt 的 swiftmodule 路径和 force_load:
text
// SWIFT_INCLUDE_PATHS 追加 UjuAdExt 的 Headers 目录
SWIFT_INCLUDE_PATHS[sdk=iphoneos*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/Headers $(SRCROOT)/Frameworks/UjuAdExt.xcframework/ios-arm64/Headers
SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/Headers $(SRCROOT)/Frameworks/UjuAdExt.xcframework/ios-arm64_x86_64-simulator/Headers

// OTHER_LDFLAGS 追加 UjuAdExt 的 -force_load
OTHER_LDFLAGS[sdk=iphoneos*] = $(inherited) -force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/libUjuAdCore-iphoneos.a -force_load $(SRCROOT)/Frameworks/UjuAdExt.xcframework/ios-arm64/libUjuAdExt-iphoneos.a
OTHER_LDFLAGS[sdk=iphonesimulator*] = $(inherited) -force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/libUjuAdCore-simulator.a -force_load $(SRCROOT)/Frameworks/UjuAdExt.xcframework/ios-arm64_x86_64-simulator/libUjuAdExt-simulator.a
  1. 追加 Vendor 目录下第三方 DSP SDK 的 -force_load(关键,缺一会导致链接错误 symbol(s) not found):

UjuAdExt zip 内 Vendor/ 目录下的第三方 DSP SDK 为静态库(.framework 内含 .a),其 OC 类符号在默认链接模式下会被 dead-strip,必须显式 -force_load:

text
// 示例:Vendor 目录下两个 DSP 子目录(Adx24 / Adx28)的静态库
// 实际路径以解压后的目录结构为准,逐个 -force_load 每个 .framework 内的二进制
OTHER_LDFLAGS[sdk=iphoneos*] = $(inherited) \
  -force_load $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/libUjuAdCore-iphoneos.a \
  -force_load $(SRCROOT)/Frameworks/UjuAdExt.xcframework/ios-arm64/libUjuAdExt-iphoneos.a \
  -force_load $(SRCROOT)/Frameworks/Vendor/Adx24/<SDKName>.xcframework/ios-arm64*/<SDKName>.framework/<SDKName> \
  -force_load $(SRCROOT)/Frameworks/Vendor/Adx28/<SDKName>.xcframework/ios-arm64*/<SDKName>.framework/<SDKName>

必须逐个 force_load Vendor 下每个 SDK

Vendor/ 目录下每个 .xcframework 内的静态库都必须单独 -force_load,缺一会导致对应 DSP 的 OC 类符号找不到(_OBJC_CLASS_$_*** 未定义)。<SDKName> 为 zip 内实际的 framework 名称,请按解压后的目录结构替换。

  1. 在 Info.plist 中注册适配器(关键,缺一会导致 SDK 无法发现适配器):

UjuAdExt 内部的 DSP 适配器通过 Info.plist 反射机制注册。集成方需在 Info.plist 中添加 uju_adapter_* key,value 为工厂类全名(格式:UjuAdExt.<FactoryClassName>)。

当前 UjuAdExt 3.4.2 内置 2 个 DSP 适配器,按需将以下 key 加入 Info.plist:

xml
<!-- 适配器注册(SDK 启动时通过 Info.plist 反射发现并加载) -->
<key>uju_adapter_adx24</key>
<string>Adx24Adapter.Adx24AdapterFactory</string>
<key>uju_adapter_adx28</key>
<string>Adx28Adapter.Adx28AdapterFactory</string>

必须配置 Info.plist 适配器注册 key

UjuAdExt 适配器不会自动注册,必须在 Info.plist 中配置 uju_adapter_* key 才能被 SDK 反射发现。缺少配置会导致 SDK 启动后日志输出 Info.plist 反射扫描完成,成功注册 0 个第三方适配器,对应 DSP 无法竞价。

  1. 验证集成:
swift
import UjuAdCore
print("UjuAdExt 集成成功,版本: \(UjuAdCore.shared.getVersion())")

开启 isDebug = true 后,SDK 启动日志中应出现 Info.plist 反射扫描完成,成功注册 N 个第三方适配器(N 为您配置的适配器数量)。

说明:UjuAdExt 依赖 UjuAdCore,必须先完成步骤 1-4 的 UjuAdCore 集成。UjuAdExt 的 swiftmodule 路径需追加到 SWIFT_INCLUDE_PATHS(不是覆盖),否则会找不到 UjuAdCore 模块。UjuAdExt 内部集成的第三方 DSP SDK 及资源已打包在 zip 中,集成方按目录结构拖入即可,无需单独获取。

方式二:CocoaPods 集成 ​

步骤 1:添加私有 spec repo ​

优聚智汇 SDK 通过私有 CocoaPods 源分发,首次接入需添加 spec repo:

bash
pod repo add UjuAdSpecs https://gitee.com/ujuad/iossdk.git

步骤 2:创建 Podfile ​

在项目根目录创建 Podfile:

ruby
source 'https://gitee.com/ujuad/iossdk.git'
source 'https://cdn.cocoapods.org/'

platform :ios, '13.0'
use_frameworks!

target 'YourApp' do
  # 优聚智汇核心 SDK(必选,静态库模式,所有依赖已静态链接)
  pod 'UjuAdCore', '~> 3.4.2'

  # 优聚智汇预算包(必选,扩展广告填充来源)
  pod 'UjuAdExt', '~> 3.4.2'
end

source 说明

  • source 'https://gitee.com/ujuad/iossdk.git' 必须在 Podfile 顶部声明,用于拉取私有 podspec
  • source 'https://cdn.cocoapods.org/' 用于拉取其他公共依赖
  • SDK 内部已静态链接 gRPC-Swift / SwiftProtobuf / SwiftNIO,不要重复 pod 这些库
  • UjuAdExt 会自动依赖 UjuAdCore,无需重复声明(但建议显式声明以便控制版本)

步骤 3:安装依赖 ​

bash
pod install
open YourApp.xcworkspace

podspec 自动配置 Build Settings

CocoaPods 集成模式下,podspec 会自动配置 SWIFT_INCLUDE_PATHS、OTHER_LDFLAGS(含 -force_load)、ENABLE_DEBUG_DYLIB 等 Build Settings,集成方无需手动设置。

步骤 4:验证集成 ​

swift
import UjuAdCore
print(UjuAdCore.shared.getVersion())  // 3.4.2

适配器架构 ​

iOS SDK 采用与 Android 对齐的独立适配器架构。各适配器需实现 BaseAdapterFactory 协议,并通过 UjuAdCore.shared.registerAdapterFactory(_:) 注册,或通过 Info.plist 反射发现机制自动注册。

ADX 自有广告源

ADX 自有广告源已内置在核心库中,无需额外注册。通过 UjuAdInfo.platformId 获取到的 ADX 广告平台 ID 统一为 100。

Info.plist 权限与配置 ​

App Transport Security(ATS) ​

SDK 默认使用 HTTPS,无需特殊 ATS 配置。如需调试 HTTP 明文:

xml
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

生产环境建议:移除 NSAllowsArbitraryLoads,仅允许 HTTPS。

App Tracking Transparency(ATT) ​

iOS 14+ 获取 IDFA 需用户授权。在 Info.plist 添加使用说明:

xml
<key>NSUserTrackingUsageDescription</key>
<string>我们需要您的许可来提供更精准的广告体验</string>

SDK 在 start() 阶段会异步请求 ATT 授权;开发者也可自行调用 ATTrackingManager.requestTrackingAuthorization 后再 start。用户授权后 UjuAdCore.shared.getIDFA() 才会返回真实 IDFA,未授权时返回空字符串(SDK 使用 IDFV 替代,仍可正常工作)。

SKAdNetwork(可选) ​

如需支持 SKAdNetwork 归因:

xml
<key>SKAdNetworkItems</key>
<array>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>优聚智汇提供的 SKAdNetwork ID</string>
    </dict>
</array>

具体 SKAdNetwork ID 列表请联系优聚智汇平台获取。

宿主 App 引入注意事项 ​

引入 UjuAdCore 或 UjuAdExt 时,宿主 App 需按下表配置对应的依赖、系统框架与 Info.plist。以下内容参照官方 DemoApp 的真实配置,集成方可直接对照。

UjuAdCore(核心 SDK,必选) ​

UjuAdCore 已静态链接 gRPC-Swift / SwiftProtobuf / SwiftNIO 等第三方依赖,无需引入任何额外包。

依赖类型内容是否需要集成方引入
第三方库gRPC-Swift / SwiftProtobuf / SwiftNIO / swift-atomics / swift-crypto❌ 已静态链接,禁止重复引入
系统框架UIKit / Foundation / AVFoundation / CoreMedia / AdSupport / AppTrackingTransparency / StoreKit / CoreLocation✅ Xcode 自动链接,无需手动添加
系统库libz.tbd / libresolv.tbd✅ Xcode 自动链接
Bundle 资源无—

UjuAdCore 的 Build Settings 必填项:

详见上方 方式一:步骤 3 或 方式二:CocoaPods 集成(podspec 自动配置)。

UjuAdExt(优聚智汇预算包,必选) ​

UjuAdExt 依赖 UjuAdCore,必须先完成 UjuAdCore 集成。引入 UjuAdExt 后,其内部集成的第三方 DSP SDK 及资源会自动随 zip 打包分发,集成方无需单独获取或配置第三方 SDK。

Info.plist 必要配置 ​

引入 UjuAdExt 后,需在 Info.plist 中补充以下配置(由内部 DSP SDK 要求):

配置项原因示例
NSAppTransportSecurity.NSAllowsArbitraryLoads内部 DSP SDK 使用 HTTP 明文请求广告,iOS 默认强制 HTTPS 会报 -1022true
NSMotionUsageDescription内部 DSP SDK 读取 CoreMotion 设备信息"用于向您提供更优质的广告服务"
LSApplicationQueriesSchemes内部 DSP SDK 广告跳转目标 App 的 URL Scheme 白名单见下方完整列表
SKAdNetworkItems内部 DSP SDK 广告归因所需的 SKAdNetwork ID 列表见下方完整列表

LSApplicationQueriesSchemes 完整列表:

xml
<key>LSApplicationQueriesSchemes</key>
<array>
    <!-- 微信 -->
    <string>wechat</string>
    <string>weixin</string>
    <!-- 拼多多 -->
    <string>pinduoduo</string>
    <string>pddopen</string>
    <!-- 新浪微博 -->
    <string>sinaweibohd</string>
    <string>sinaweibo</string>
    <string>sinaweibosso</string>
    <string>weibosdk</string>
    <string>weibosdk2.5</string>
    <!-- QQ、Qzone -->
    <string>mqqapi</string>
    <string>mqq</string>
    <string>mqqOpensdkSSoLogin</string>
    <string>mqqconnect</string>
    <string>mqqopensdkdataline</string>
    <string>mqqopensdkgrouptribeshare</string>
    <string>mqqopensdkfriend</string>
    <string>mqqopensdkapi</string>
    <string>mqqopensdkapiV2</string>
    <string>mqqopensdkapiV3</string>
    <string>mqzoneopensdk</string>
    <string>wtloginmqq</string>
    <string>wtloginmqq2</string>
    <string>mqqwpa</string>
    <string>mqzone</string>
    <string>mqzonev2</string>
    <string>mqzoneshare</string>
    <string>wtloginqzone</string>
    <string>mqzonewx</string>
    <string>mqzoneopensdkapiV2</string>
    <string>mqzoneopensdkapi19</string>
    <string>mqzoneopensdkapi</string>
    <!-- 支付宝 淘宝 -->
    <string>alipay</string>
    <string>alipays</string>
    <string>alipayshare</string>
    <string>taobao</string>
    <string>tbopen</string>
    <string>itaobao</string>
    <!-- 天猫 -->
    <string>tmall</string>
    <string>itmall</string>
    <!-- 京东 -->
    <string>openapp.jdmobile</string>
    <!-- 高德 -->
    <string>amapuri</string>
    <!-- 大众点评 -->
    <string>dianping</string>
    <!-- 美团 -->
    <string>meituan0000</string>
    <string>iMeituan</string>
    <!-- 抖音 -->
    <string>snssdk1128</string>
    <!-- 快手 -->
    <string>kwai</string>
    <!-- 哔哩哔哩 -->
    <string>bilibili</string>
    <!-- 今日头条 -->
    <string>snssdk141</string>
    <!-- 携程 -->
    <string>ctrip</string>
    <!-- 百度地图 -->
    <string>baidumap</string>
    <!-- 手机百度 -->
    <string>baiduboxapp</string>
    <!-- UC浏览器 -->
    <string>ucbrowser</string>
    <string>uclink</string>
    <!-- 优酷 -->
    <string>youku</string>
    <!-- 知乎 -->
    <string>zhihu</string>
    <!-- 爱奇艺 -->
    <string>qiyi-iphone</string>
    <string>iqiyi</string>
</array>

SKAdNetworkItems 完整列表:

xml
<key>SKAdNetworkItems</key>
<array>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>f7s53z58qe.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>r3y5dwb26t.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>238da6jt44.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>x2jnk7ly8j.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>22mmun2rn5.skadnetwork</string>
    </dict>
</array>

特殊注意事项 ​

不支持 Apple Silicon 模拟器

UjuAdExt 内部集成的部分 DSP SDK 不包含 arm64 simulator slice,在 Apple Silicon Mac 上运行模拟器会报架构不匹配错误。

解决方案:在 Build Settings 中设置 EXCLUDED_ARCHS[sdk=iphonesimulator] = arm64,模拟器编译时排除 arm64 架构,自动使用 x86_64(Rosetta 运行)。真机编译不受影响。

-ObjC 链接标志

UjuAdExt 内部集成的 DSP SDK 为 Objective-C 静态库,含 Category 扩展。XCFramework 集成时需在 OTHER_LDFLAGS 添加 -ObjC 以正确加载 OC Category:

text
OTHER_LDFLAGS = $(inherited) -ObjC

CocoaPods 集成时 podspec 已自动配置,无需手动添加。

UjuAdExt 的 Build Settings 追加

引入 UjuAdExt 后,SWIFT_INCLUDE_PATHS 和 OTHER_LDFLAGS 需追加(不是覆盖)UjuAdExt 的 Headers 路径和 force_load。详见上方 步骤 5:集成 UjuAdExt 预算包。

依赖关系总览 ​

宿主 App
  │
  ├── UjuAdExt(必选)
  │     └── 内部 DSP 适配器(第三方 SDK 已打包,集成方无需单独获取)
  │           ↓ 依赖
  │     UjuAdCore(必选)
  │           ├── 优聚 Adx 竞价引擎
  │           ├── 配置服务 / 埋点上报
  │           └── 广告加载 / 渲染 / 展示
  │           (gRPC-Swift / SwiftProtobuf / SwiftNIO 已静态链接,无需引入)
  │
  └── Info.plist 配置
        ├── UjuAdCore:ATT / ATS / SKAdNetwork(可选)
        └── UjuAdExt:+ NSAllowsArbitraryLoads / NSMotionUsageDescription / LSApplicationQueriesSchemes / SKAdNetworkItems

appKey 说明 ​

UjuAdInitConfig.appKey 实际是优聚智汇后台分配的 RSA 公钥(与 Android 一致),用于服务端通信加密与验签。

  • 请从优聚智汇开发者后台获取 RSA 公钥
  • 原样传入,不要自行修改或截断
  • 误用为普通字符串会影响加密链路

下一步 ​

完成准备工作后,请继续阅读: