Skip to content

iOS 常见问题 ​

Q1:编译报 no such module 'UjuAdCore' ​

原因:SWIFT_INCLUDE_PATHS 未正确指向 xcframework 的 Headers 目录。

解决:

  1. 确认 UjuAdCore.xcframework 已添加到项目
  2. 在 Build Settings 中配置 SWIFT_INCLUDE_PATHS:
    • 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
  3. 关闭 SWIFT_ENABLE_EXPLICIT_MODULES(设为 NO)

详见 准备工作。

Q2:链接报 undefined symbol: GRPC.xxx / SwiftProtobuf.xxx ​

原因:未使用合并后的 xcframework,或重复引入了 gRPC-Swift / SwiftProtobuf 依赖。

解决:

  1. 确认使用的是 3.4.2 及以上版本的 UjuAdCore.xcframework(已合并 UjuGRPCStatic)
  2. 移除 Podfile 中的 grpc-swift / swift-protobuf 依赖
  3. 检查是否有多份 UjuAdCore 副本(如同时通过 xcframework 和 CocoaPods 引入)

Q3:SDK 初始化失败,错误码 1(initFailed) ​

排查步骤:

  1. 检查 appId / appKey(RSA 公钥)是否正确(由优聚智汇平台分配)
  2. 检查 region 是否选对(.domestic 国内 / .singapore 海外)
  3. 开启 isDebug = true,查看控制台日志中的具体失败原因
  4. 确认网络可达对应区域的服务器域名

Q4:广告加载失败,错误码 102(noFill) ​

说明:这是正常业务响应,表示本次请求无填充——优聚 ADX 无出价,或聚合预算源请求成功但无广告返回。可能原因:

  • 当前广告位无填充
  • 用户频次已达到上限
  • 设备/区域无匹配广告

3.4.3 起,所有无填充场景统一回调 code=102 / message="无填充"(此前部分聚合预算源会回调 code=100 并携带第三方原始错误信息)。

建议:可降级到其他广告源,或间隔一段时间后重试。

Q5:开屏广告 onAdDismissed 何时回调? ​

回调时机:

  • 用户主动跳过开屏(点击跳过按钮)
  • 开屏倒计时结束

建议:在 onAdDismissed 中进入主界面,不要在 onAdClosed 中进入(后者仅表示广告视图被移除)。

Q6:激励视频如何判断用户应得奖励? ​

判断逻辑:

  • onAdRewardArrived() 回调 → 应发放奖励(用户观看完整视频)
  • onAdSkippedVideo() 回调 → 不应发放奖励(用户跳过视频)
  • onAdPlayComplete() 回调 → 视频播放完成(不直接等于发奖,以 onAdRewardArrived 为准)

详见 激励视频 - 奖励判断逻辑。

Q7:如何调试 SDK 内部日志? ​

方法 1(推荐):设置 isDebug = true

swift
let config = UjuAdInitConfig.create(
    appId: "...",
    appKey: "...",
    isDebug: true,  // ★ 开启 SDK 内部日志
    // ...
)

SDK 内部通过 NSLog 输出日志,可在 Xcode 控制台或 Console.app 中查看。发布前请改为 false。

方法 2:使用系统 OSLog

swift
import os.log
let log = OSLog(subsystem: Bundle.main.bundleIdentifier ?? "your.app", category: "UjuAdCore")
os_log("custom log: %{public}@", log: log, message)

Q8:CocoaPods 集成时报部署目标不受支持(The iOS deployment target ... is set to 11.0/13.0) ​

说明:优聚智汇各组件自 3.4.3 起部署目标统一为 iOS 15.0;引入的第三方 pod(如穿山甲 Ads-CN-Beta 自带声明为 11.0)在 Xcode 27+ 下会因低于最低支持版本而报错。

解决:在 Podfile 末尾追加 post_install 钩子,统一抬升 Pods 部署目标:

ruby
post_install do |installer|
  installer.pods_project.targets.each do |t|
    t.build_configurations.each do |c|
      c.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
    end
  end
end

同时确认 Podfile 顶部的 platform :ios 不低于 '15.0'。如引入了 UjuAdExt,post_install 中还需设置 EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64(详见 准备工作 - CocoaPods 集成)。

Q9:如何在 macOS 上编译? ​

不支持。UjuAdCore.xcframework 为 iOS-only,在 macOS host 上编译会失败。SDK 仅支持 iOS 平台编译,不支持 macOS。

Q10:SDK 是否支持 bitcode? ​

不支持。Xcode 16+ 已废弃 bitcode,SDK 也不启用 bitcode。请在 Build Settings 中关闭 ENABLE_BITCODE。

Q11:如何确认 SDK 版本? ​

swift
print(UjuAdCore.shared.getVersion())  // "3.4.5"

或查看 xcframework 内的 UjuAdCore.version.json。

Q12:运行时崩溃 EXC_BAD_ACCESS (code=1, address=0x30 / 0x50),崩溃栈在 ManagedAtomic.__allocating_init 或 NIOPosix.BaseSocketChannel.isActive.getter ​

根因:

UjuAdCore 静态链接了 swift-atomics,其中 ManagedAtomic<Value> 是一个带 @_alwaysEmitIntoClient 标记的泛型 class。该标记会让 init 等方法被内联到调用方,但泛型 class 的 type metadata accessor 函数是由静态库按需提供的。

在静态库 demand-driven 链接模式下,链接器会扫描"哪些 .o 被引用",只保留被引用的 .o。由于 @_alwaysEmitIntoClient 把 init 内联到了调用方,泛型 class 的 type metadata accessor 在调用方看来没有任何符号引用,于是被链接器判定为"未使用"而 dead-strip。

运行时 ManagedAtomic.__allocating_init 会调用 type metadata accessor 获取 metadata,被 dead-strip 后该函数返回 nil,随后访问 metadata 字段就会访问到地址 0x30/0x50 → EXC_BAD_ACCESS。

崩溃出现在 SDK 发起首次网络请求时,表现为:

  • SDK 发起首次网络请求后立即崩溃
  • 崩溃出现在 SDK 内部子线程
  • 崩溃栈顶:ManagedAtomic.__allocating_init 或 BaseSocketChannel.isActive.getter

解决:

在 Target → Build Settings → Other Linker Flags 中添加 -force_load,强制保留 UjuAdCore 静态库的全部 .o(按 SDK 条件选择对应 slice):

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

CocoaPods 集成方:优聚智汇各 podspec 已通过 user_target_xcconfig 自动注入对应 slice 的 -force_load(自 3.4.3 起真机与模拟器均正常生效),无需手动配置。若手动集成 xcframework,请按上文方式配置。

Q13:Xcode 26 运行时崩溃在主线程 objc_msgSend(SIGSEGV),崩溃栈含 __NSThreadPerformPerform ​

根因:Xcode 26 默认启用 Debug Dylib 特性(ENABLE_DEBUG_DYLIB = YES),会把 App 代码拆分到 <App>.debug.dylib(可热重载)和主二进制两部分。该拆分与 UjuAdCore 静态库的符号链接冲突:SDK 的部分符号被划到 .debug.dylib,而 type metadata accessor 被划到主二进制,跨 dylib 边界访问时元数据不一致 → objc_msgSend 访问已释放 receiver → SIGSEGV。

解决:在 Target → Build Settings 中设置:

text
ENABLE_DEBUG_DYLIB = NO

影响:仅关闭 Xcode 26 的 Swift UI 预览热重载加速特性,不影响 SDK 功能,也不影响 Debug 调试(断点、LLDB、NSLog 全部正常)。生产 Release 构建不受影响(Release 配置本就不启用 Debug Dylib)。

Q14:如何自查"符号是否被正确链接"? ​

集成完成后,可在终端执行以下命令验证关键符号是否被保留到 App 主二进制(路径替换为实际产物):

bash
# 1. _AtomicsShims 的 C 桥接函数(若缺失 → -force_load 未生效)
nm -gU <App>.app/<App> | grep "__sa_"
# 期望输出:__sa_retain_n / __sa_release_n

# 2. ManagedAtomic<Bool> 的 type metadata(若缺失 → 仍会崩溃)
nm <App>.app/<App> | grep "7Atomics13ManagedAtomicCySbG"
# 期望包含 MR(metadata accessor)符号

若以上检查不通过,请回到 准备工作 复核 OTHER_LDFLAGS 与 ENABLE_DEBUG_DYLIB 配置。

Q15:集成 UjuAdExt 后链接报 symbol(s) not found for architecture arm64,含 _OBJC_CLASS_$_*** 未定义 ​

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

解决:

在 OTHER_LDFLAGS 中追加 Vendor 目录下每个 .xcframework 内静态库的 -force_load(路径替换为实际解压后的目录结构):

text
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>

详见 准备工作 - 步骤 5。

Q16:集成 UjuAdExt 后,SDK 启动日志输出 Info.plist 反射扫描完成,成功注册 0 个第三方适配器 ​

原因:UjuAdExt 适配器不会自动注册,必须在 Info.plist 中配置 uju_adapter_* key 才能被 SDK 反射发现。

解决:

在 Info.plist 中添加适配器注册 key(当前 UjuAdExt 3.5.10 内置 5 个 DSP 适配器,具体开通的适配器以优聚智汇平台分配为准):

xml
<key>uju_adapter_adx21</key>
<string>Adx21Adapter.Adx21AdapterFactory</string>
<key>uju_adapter_adx24</key>
<string>Adx24Adapter.Adx24AdapterFactory</string>
<key>uju_adapter_adx28</key>
<string>Adx28Adapter.Adx28AdapterFactory</string>
<key>uju_adapter_adx32</key>
<string>Adx32Adapter.Adx32AdapterFactory</string>
<key>uju_adapter_adx33</key>
<string>Adx33Adapter.Adx33AdapterFactory</string>

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

详见 准备工作 - 步骤 5。

Q17:Objective-C 项目如何接入? ​

说明:优聚智汇 SDK 使用 Swift 开发,公开 API 包含 struct、Sendable 协议、Builder 模式等 Swift 独有特性,未提供独立的 Objective-C 兼容层。纯 Objective-C 项目需通过 Swift 混编 + 自行封装 @objc wrapper 接入。

接入步骤:

  1. 开启 Swift 混编:在 Xcode 项目中新建一个 .swift 文件(可仅写一行 import UjuAdCore),Xcode 会提示创建 Bridging Header,选择 Create Bridging Header 即可开启 Swift 编译支持。

  2. 封装 @objc Wrapper:由于 UjuAdCore、UjuAdObject 等公开类未继承 NSObject,且 UjuAdInitConfig 为 struct + 静态 builder,OC 无法直接调用,需在 Swift 文件中编写继承 NSObject 的 wrapper 类并用 @objc 暴露给 OC。示例:

swift
import UjuAdCore

@objc(UjuAdBridge)
final class UjuAdBridge: NSObject {

    @objc static func initialize(appId: String,
                                  appKey: String,
                                  isDebug: Bool,
                                  rsaPublicKey: String) {
        let config = UjuAdInitConfig.create(
            appId: appId,
            appKey: appKey,
            isDebug: isDebug,
            rsaPublicKey: rsaPublicKey
        )
        UjuAdCore.shared.initialize(nil, config: config)
    }

    @objc static func start() {
        UjuAdCore.shared.start(nil)
    }

    @objc static func version() -> String {
        return UjuAdCore.shared.getVersion()
    }
}
  1. OC 调用:在 OC 代码中通过 #import "<ProductName>-Swift.h" 调用 wrapper:
objc
#import "YourApp-Swift.h"

[UjuAdBridge initializeWithAppId:@"YOUR_APP_ID"
                          appKey:@"YOUR_APP_KEY"
                          isDebug:YES
                     rsaPublicKey:@"YOUR_RSA_PUBLIC_KEY"];
[UjuAdBridge start];
NSLog(@"SDK version: %@", [UjuAdBridge version]);

注意事项:

  • BaseInitListener、广告监听器等协议含 Sendable 约束,无法用 @objc 直接暴露,需在 wrapper 中用 @objc protocol 或 block 桥接回调。
  • UjuAdRegion 等 enum 需在 wrapper 中转为 NSInteger 暴露给 OC。
  • 5 种广告对象(UjuAdObject)的工厂方法和监听器都建议在 wrapper 中封装为 OC 友好接口。
  • 详细 Wrapper 设计可参考 官方 ExternalApp Demo 中的 Swift 桥接实现。

Q18:集成 UjuAdExt 后报 duplicate symbol 错误(OC 类/协议重复定义) ​

原因:UjuAdExt 3.5.5 已在 Vendor/ 子目录内置当前支持的全部第三方 DSP SDK(含对应的 .framework 与 .bundle 资源)。如果集成方工程已通过 CocoaPods 或手动方式接入了同名第三方 SDK,链接器会发现 OC 类、协议、category 等重复定义,触发 duplicate symbol 报错。

常见冲突来源:

  • 集成方已有其他聚合 SDK(如穿山甲 GroMore、优量汇 GDT 聚合等),这些聚合自带相同 DSP SDK
  • 集成方有独立业务直接接入了同款 SDK
  • Podfile 中残留旧版依赖未清理

解决:

  1. 移除集成方自有的同名 SDK 引入(必须):
    • Podfile:删除对应的 pod '***' 依赖,执行 pod install
    • 手动引入:删除 Frameworks、Embed Frameworks、Copy Bundle Resources 中对应的 .framework 与 .bundle
    • Build Settings → Search Paths → Framework Search Paths / Header Search Paths 中删除指向旧 SDK 的路径
  2. 清理 Build Settings:
    • OTHER_LDFLAGS 删除 -framework ***、-force_load *** 中指向旧 SDK 的条目(保留 UjuAdExt 自带的 -force_load UjuAdExt.xcframework)
    • 如果之前用过 -ObjC,保留即可(UjuAdExt 自身的 OC category 也需要它)
  3. Clean Build Folder:Xcode 菜单 Product → Clean Build Folder(⇧⌘K),删除 ~/Library/Developer/Xcode/DerivedData/<项目>-* 缓存目录
  4. 重新编译验证:nm -gU Pods/UjuAdExt/Vendor/**/*.framework/* | grep <冲突类名> 应只在 UjuAdExt 自带的 Vendor 中出现一次

为何不提供 UjuAdExt/Core subspec 让集成方自己选?

UjuAdExt 的设计目标是"集成方只需引入优聚隐私政策即可使用全部广告源"——第三方 DSP SDK 由优聚统一打包、签名、版本管理,避免集成方自行接入导致版本不一致。如果集成方有强烈的独立版本管理需求,请联系优聚技术支持评估定制方案。

详见 准备工作 - 集成 UjuAdExt 中的「请勿重复接入」警示。

Q19:上传 App Store 时提示 "Upload Symbols Failed — The archive did not include a dSYM for the Adx22_SSL.framework / Adx33_Core.framework" ​

2026-10-30 重要更正:经接入方反馈核查,3.5.4~3.5.9 随包的 Adx22_SSL / Adx33_Core dSYM 是用二进制本体构造的 UUID 匹配壳——UUID 正确、保留符号表可做函数级符号化,但不含 DWARF 调试信息(编译单元数为 0),无法行级符号化,也不能作为有效符号通过 App Store Connect 校验。本条旧版"升级 ≥ 3.5.4 即解决"的表述是错误的,已删除。UjuAdExt 3.5.10 起随包 DSP 原厂完整 dSYM(含 DWARF,可行级符号化),且打包期新增 dSYM 内容审计(UUID 匹配 + 编译单元 > 0,不通过即阻断发版),此类问题不会再随包流出。

背景:UjuAdExt 中 Adx33_Core 以动态库形式分发(3.5.8 前还有 Adx22_SSL),在 App 内是独立可执行镜像;勾选 "Upload your app's symbols" 上传符号时,Xcode 会在归档的 dSYMs 目录内寻找同 UUID 的 dSYM。该类报错不影响构建与提交本身。

处理方式:

  1. 3.5.4~3.5.9:使用补发的完整 dSYM(推荐,无需升级):DSP 原厂 dSYM 已按中性名打好补发包(下载,sha256 见发版说明),UUID 与 3.5.4~3.5.9 全部随包的 Adx33_Core 二进制一致(真机 arm64 F54DC8B9-9071-33E3-82EC-BF0BAEDEF09D,281 个编译单元;模拟器切片双架构 562 个):
    • CocoaPods 集成:将补发包内 Adx33_Core.dSYMs/ 整个目录覆盖 Pods/UjuAdExt/Vendor/Adx33/Adx33_Core.dSYMs/,重新归档即可(归档 dSYMs 目录内即为完整 dSYM);
    • 手动集成:把补发包内两个 .dSYM 拷入归档包的 dSYMs 目录(Organizer → 右键归档 → Show in Finder → 打开 dSYMs 目录粘贴)后重新上传;
  2. 或升级到 UjuAdExt ≥ 3.5.10:随包即为完整 dSYM,CocoaPods 集成归档自动包含,手动集成按第 1 条方式拷入随包 .dSYMs 目录;
  3. 或本次提审临时不上传符号:上传对话框取消勾选 "Upload your app's symbols"。第三方框架的符号上传并非提审硬性要求,仅放弃 Apple 侧对该框架的符号化报告,主 App 自身 dSYM 不受影响;
  4. 排查孤儿 dSYM:曾按本条旧版指引手动拷贝过 dSYM 的工程,请检查归档 dSYMs 目录是否残留 Adx22_SSL 的 dSYM——3.5.8 起 Adx22 已剔除,其 UUID 在包内已无对应二进制,会持续触发 "Invalid dSYM"。可在归档目录(.xcarchive)内执行以下命令比对,dSYM 侧 UUID 不在任何二进制侧结果里的即为孤儿,删除后重传:
bash
# dSYM 侧 UUID
find . -name "*.dSYM" -exec dwarfdump --uuid {} \;
# 二进制侧 UUID(嵌入的 framework + 主 App 二进制)
find . -name "*.framework" -exec sh -c 'dwarfdump --uuid "$1/$(basename "$1" .framework)" 2>/dev/null' _ {} \;
find Products/Applications -maxdepth 2 -type f -exec dwarfdump --uuid {} \; 2>/dev/null

Q20:SDK 是否支持 iOS 27? ​

支持。SDK 部署目标为 iOS 15.0,向上兼容最新系统(含 iOS 26 / iOS 27),已使用 Xcode 27 + iOS 27 SDK 完成构建与真机验证;真机安装、运行与 App Store 分发均不受系统版本影响。

注意(仅模拟器):Xcode 27 起 iOS 模拟器运行时不再支持 Rosetta(仅可运行 arm64),而 UjuAdExt 内部分第三方 DSP 组件(Adx28 / Adx32 相关库;UjuAdExt ≤ 3.5.7 还包括 Adx22 Adapter,3.5.8 起该组件已不再打包)暂缺可用的 arm64 模拟器切片,因此:

  • 在 iOS 26.5 / iOS 27 等新模拟器运行时上安装 App 会失败,提示「此 App 需要开发者更新以在此 iOS 版本上运行」(x86_64 包不再被新运行时接受);
  • 强制构建 arm64 模拟器包会在链接阶段报错(如 building for 'iOS-simulator', but linking in object file ... built for 'iOS')。

该限制仅影响模拟器调试,不影响真机与线上分发;模拟器场景请暂用仍支持 Rosetta 的旧版 Xcode 及配套运行时,或优先使用真机验证。

Q21:SDK 是否支持 iOS 27.1 与 iPhone Duo 折叠屏?折叠/展开后广告尺寸如何处理? ​

支持。UjuAdCore 3.4.6(配套 UjuAdExt 3.5.6)起按 iOS 27.1 折叠屏技术方案完成适配:

  • 尺寸来源:SDK 不再在初始化时一次性读取屏幕尺寸,而是以宿主 App 当前窗口场景(UIWindowScene)为准,折叠 / 展开、分屏、旋转后竞价请求的 slot 尺寸与各预算源的模版加载尺寸都随窗口实时变化;内屏多窗口场景按广告所在窗口取值。
  • 全屏广告(开屏 / 插屏 / 激励):全部基于 Auto Layout 与 size class,外屏(compact 宽)铺满窗口;内屏 / 大屏(regular 宽)下插屏卡片限宽 420pt、激励页内容列居中限宽,折叠 / 展开过程中随窗口重排,不会溢出屏幕。
  • 横幅 / 原生广告:宽度始终跟随集成方传入的 container;优聚 Adx 模版与预算源模版都会随容器宽度重新排版 / 等比缩放。渲染后尺寸发生变化时通过 FeedAdObjectListener.onAdSizeChanged(width:height:) 回调(3.4.6 新增,默认空实现),列表类宿主请在此回调中刷新行高。
  • 期望尺寸:UjuAdConfig.adViewSize(单位逻辑点)可显式指定横幅 / 原生的期望尺寸,SDK 以此作为竞价 slot 与模版加载尺寸(宽度不超过宿主窗口当前宽度);未设置时按窗口当前宽度推导。
  • 构建要求:SDK 自身不要求 Xcode 27.1,但宿主 App 需用 Xcode 27.1 SDK 重新构建才能获得 iPhone Duo 的边到边与竖向工具栏布局(由宿主构建 SDK 决定,与广告 SDK 无关)。
  • 已知限制:Xcode 27.x 的 iPhone Duo 模拟器仅 arm64,含 UjuAdExt 的 App 受 Q20 所述第三方组件切片限制无法在该模拟器安装,折叠屏验证请使用真机;部分预算源的模版广告(Adx24 / Adx33)在容器变宽后由其 SDK 内部决定是否重排,高度保持首次渲染值。

Q22:从 UjuAdExt ≤ 3.5.7 升级到 ≥ 3.5.8(Adx22 预算源剔除)如何迁移? ​

UjuAdExt 3.5.8 起剔除 Adx22 预算源:其第三方 SDK 静态归档导出未加前缀的全局符号(含整份基座库与若干视图类),与接入方 App 直连同基座三方库时产生 duplicate symbol 链接失败。SDK 侧对 Adx22 适配器为反射加载,缺失即自动跳过,不影响其余预算源。迁移清单:

CocoaPods 集成:

  1. pod update UjuAdExt(≥ 3.5.8)即可,Podfile 无需改动——podspec 已收缩 vendored / resources 清单,pod install 自动移除 Adx22 相关产物;
  2. 曾在 Podfile / target 配置里手写过 Adx22 相关 -force_load、framework 路径的,删除对应行(残留会报 file not found 链接错误);
  3. 检查工程内是否残留手动引入的 Adx22 系 framework 与同名基座库(如接入方自行集成的 LiteMob 系库与 UjuAdExt 同时在包会恢复 duplicate symbol,保留一份即可,推荐保留接入方自有版本并升级 UjuAdExt)。

手动集成:

  1. 用新 zip 整体替换 Vendor/ 目录(Adx22 子目录已不存在,旧目录务必删除);
  2. Build Settings → Other Linker Flags:删除所有 Adx22 相关 -force_load;
  3. General → Frameworks, Libraries, and Embedded Content:删除 Adx22_SSL.framework 及其 Embed 项;
  4. Build Phases → Copy Bundle Resources:删除 Adx22 相关 bundle 引用;
  5. Info.plist:删除 uju_adapter_adx22 key;
  6. 清理后重建(⇧⌘K → Build)。

广告位配置:仍配置 Adx22 预算源的广告位,请在优聚智汇平台改配其他预算源(Adx21 / Adx24 / Adx28 / Adx32 / Adx33);无法立即改配的,可暂留 UjuAdExt 3.5.7(不再维护,仅作过渡)。

迁移后验证:链接零 duplicate symbol、零 file not found;各广告位请求正常返回。若仍有 Adx22 报错,全局搜索工程与 Podfile.lock 中 Adx22、Menta、Litemob 关键字确认清理干净。

Q23:旧版 Xcode 编译报 "module compiled with Swift 6.4 cannot be imported by the Swift 6.3.3 compiler"? ​

现象:Xcode 26.x(Swift 6.2.x / 6.3.x)下编译含 import UjuAdCore 的 Swift 文件直接报此错,业务代码无关。

原因:主线 UjuAdCore 的 Swift 模块由 Xcode 27(Swift 6.4)工具链编译,而 Swift 二进制模块(swiftmodule)跨编译器版本不兼容——旧编译器无法导入新版本编译器产出的模块。这是 Swift 生态的普遍约束,非 SDK 缺陷;已发布的历届主线包(3.4.2~3.4.9)均为 Swift 6.4 编译,降级 pod 版本无法绕开。

解决:改用 Compat 兼容线(内容与主线同版本一致,Swift 模块以 Swift 6.3 工具链编译,业务代码零改动,模块名仍为 UjuAdCore)。Podfile 中替换为(二选一,严禁同时引入):

ruby
pod 'UjuAdCoreCompat',      '~> 3.4.9'   # 替换 UjuAdCore
pod 'UjuAdExtCompat',       '~> 3.5.10'  # 替换 UjuAdExt(必选组件)
pod 'UjuCsjAdapterCompat',  '~> 1.0.0'   # 如接入穿山甲,替换 UjuCsjAdapter

版本边界:

您的 Xcode使用的 SDK 包
Xcode 27+(Swift 6.4)主线(UjuAdCore / UjuAdExt / UjuCsjAdapter)
Xcode 26.4 ~ 26.6(Swift 6.3.x)Compat 线(本条)
Xcode ≤ 26.3(Swift 6.2.x 及更早)暂未提供,请联系技术支持

⚠️ 边界:

  • Swift 模块跨版本双向不兼容:Compat 线仅供 Swift 6.3.x 宿主使用。日后升级 Xcode 27 时,把 Podfile 三行换回主线 pod 名即可(模块名相同,业务代码无需改动)。
  • 业务代码请只 import UjuAdCore(标准接入方式本就如此):UjuAdExtCompat / UjuCsjAdapterCompat 复用主线同一二进制,其内置适配器模块(AdxNNAdapter 等)为 Xcode 27(Swift 6.4)编译,直接 import 会触发同类版本报错;它们经 Info.plist 反射注册、由 SDK 内部调用,宿主无需也不应 import。

联系技术支持 ​

如果您遇到本文未覆盖的问题,可以通过以下方式获取支持:

相关链接 ​