iOS 常见问题
Q1:编译报 no such module 'UjuAdCore'
原因:SWIFT_INCLUDE_PATHS 未正确指向 xcframework 的 Headers 目录。
解决:
- 确认
UjuAdCore.xcframework已添加到项目 - 在 Build Settings 中配置
SWIFT_INCLUDE_PATHS:SWIFT_INCLUDE_PATHS[sdk=iphoneos*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64/HeadersSWIFT_INCLUDE_PATHS[sdk=iphonesimulator*] = $(inherited) $(SRCROOT)/Frameworks/UjuAdCore.xcframework/ios-arm64_x86_64-simulator/Headers
- 关闭
SWIFT_ENABLE_EXPLICIT_MODULES(设为NO)
详见 准备工作。
Q2:链接报 undefined symbol: GRPC.xxx / SwiftProtobuf.xxx
原因:未使用合并后的 xcframework,或重复引入了 gRPC-Swift / SwiftProtobuf 依赖。
解决:
- 确认使用的是 3.4.2 及以上版本的
UjuAdCore.xcframework(已合并 UjuGRPCStatic) - 移除 Podfile 中的
grpc-swift/swift-protobuf依赖 - 检查是否有多份 UjuAdCore 副本(如同时通过 xcframework 和 CocoaPods 引入)
Q3:SDK 初始化失败,错误码 1(initFailed)
排查步骤:
- 检查
appId/appKey(RSA 公钥)是否正确(由优聚智汇平台分配) - 检查
region是否选对(.domestic国内 /.singapore海外) - 开启
isDebug = true,查看控制台日志中的具体失败原因 - 确认网络可达对应区域的服务器域名
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
let config = UjuAdInitConfig.create(
appId: "...",
appKey: "...",
isDebug: true, // ★ 开启 SDK 内部日志
// ...
)SDK 内部通过 NSLog 输出日志,可在 Xcode 控制台或 Console.app 中查看。发布前请改为 false。
方法 2:使用系统 OSLog
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 部署目标:
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 版本?
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):
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.aCocoaPods 集成方:优聚智汇各 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 中设置:
ENABLE_DEBUG_DYLIB = NO影响:仅关闭 Xcode 26 的 Swift UI 预览热重载加速特性,不影响 SDK 功能,也不影响 Debug 调试(断点、LLDB、NSLog 全部正常)。生产 Release 构建不受影响(Release 配置本就不启用 Debug Dylib)。
Q14:如何自查"符号是否被正确链接"?
集成完成后,可在终端执行以下命令验证关键符号是否被保留到 App 主二进制(路径替换为实际产物):
# 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(路径替换为实际解压后的目录结构):
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 适配器,具体开通的适配器以优聚智汇平台分配为准):
<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 接入。
接入步骤:
开启 Swift 混编:在 Xcode 项目中新建一个
.swift文件(可仅写一行import UjuAdCore),Xcode 会提示创建 Bridging Header,选择 Create Bridging Header 即可开启 Swift 编译支持。封装
@objcWrapper:由于UjuAdCore、UjuAdObject等公开类未继承NSObject,且UjuAdInitConfig为struct+ 静态 builder,OC 无法直接调用,需在 Swift 文件中编写继承NSObject的 wrapper 类并用@objc暴露给 OC。示例:
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()
}
}- OC 调用:在 OC 代码中通过
#import "<ProductName>-Swift.h"调用 wrapper:
#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 中用@objcprotocol 或 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 中残留旧版依赖未清理
解决:
- 移除集成方自有的同名 SDK 引入(必须):
- Podfile:删除对应的
pod '***'依赖,执行pod install - 手动引入:删除 Frameworks、Embed Frameworks、Copy Bundle Resources 中对应的
.framework与.bundle - Build Settings → Search Paths → Framework Search Paths / Header Search Paths 中删除指向旧 SDK 的路径
- Podfile:删除对应的
- 清理 Build Settings:
OTHER_LDFLAGS删除-framework ***、-force_load ***中指向旧 SDK 的条目(保留 UjuAdExt 自带的-force_load UjuAdExt.xcframework)- 如果之前用过
-ObjC,保留即可(UjuAdExt 自身的 OC category 也需要它)
- Clean Build Folder:Xcode 菜单 Product → Clean Build Folder(⇧⌘K),删除
~/Library/Developer/Xcode/DerivedData/<项目>-*缓存目录 - 重新编译验证:
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。该类报错不影响构建与提交本身。
处理方式:
- 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目录粘贴)后重新上传;
- CocoaPods 集成:将补发包内
- 或升级到 UjuAdExt ≥ 3.5.10:随包即为完整 dSYM,CocoaPods 集成归档自动包含,手动集成按第 1 条方式拷入随包
.dSYMs目录; - 或本次提审临时不上传符号:上传对话框取消勾选 "Upload your app's symbols"。第三方框架的符号上传并非提审硬性要求,仅放弃 Apple 侧对该框架的符号化报告,主 App 自身 dSYM 不受影响;
- 排查孤儿 dSYM:曾按本条旧版指引手动拷贝过 dSYM 的工程,请检查归档
dSYMs目录是否残留Adx22_SSL的 dSYM——3.5.8 起 Adx22 已剔除,其 UUID 在包内已无对应二进制,会持续触发 "Invalid dSYM"。可在归档目录(.xcarchive)内执行以下命令比对,dSYM 侧 UUID 不在任何二进制侧结果里的即为孤儿,删除后重传:
# 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/nullQ20: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 集成:
pod update UjuAdExt(≥ 3.5.8)即可,Podfile 无需改动——podspec 已收缩 vendored / resources 清单,pod install自动移除 Adx22 相关产物;- 曾在 Podfile / target 配置里手写过
Adx22相关-force_load、framework 路径的,删除对应行(残留会报file not found链接错误); - 检查工程内是否残留手动引入的 Adx22 系 framework 与同名基座库(如接入方自行集成的 LiteMob 系库与 UjuAdExt 同时在包会恢复 duplicate symbol,保留一份即可,推荐保留接入方自有版本并升级 UjuAdExt)。
手动集成:
- 用新 zip 整体替换
Vendor/目录(Adx22 子目录已不存在,旧目录务必删除); - Build Settings → Other Linker Flags:删除所有
Adx22相关-force_load; - General → Frameworks, Libraries, and Embedded Content:删除
Adx22_SSL.framework及其 Embed 项; - Build Phases → Copy Bundle Resources:删除 Adx22 相关 bundle 引用;
- Info.plist:删除
uju_adapter_adx22key; - 清理后重建(⇧⌘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 中替换为(二选一,严禁同时引入):
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。
联系技术支持
如果您遇到本文未覆盖的问题,可以通过以下方式获取支持:
- 邮件:marco@ujuad.com
- 官网:https://www.ujuad.com
