主题
配置与凭证
文档版本 v1.0.0
本页对应 iOS SDK 1.0.0,与离线包 docs/ 目录里的同一份文档内容一致。其他版本见文档中心。
配置服务下发的内容有两块:各广告平台的应用 ID(adns)和广告位与广告源策略(units)。 改价格、调顺序、开关广告位、甚至停用一整家广告平台,都不用发版。
SDK 只和平台服务 https://api.maemi.cn 通信(拉配置 /v1/config、上报埋点 /v1/events), 地址内置,接入方无需也无法修改。
三类凭证
| 凭证 | 从哪来 | 能进安装包(APK / IPA) |
|---|---|---|
| AppID | 管理后台创建应用时生成 | 能。它只是身份标识,不是密钥 |
| App 密钥 | 管理后台「应用管理 → 接入」,每个应用各自一套 | 需要进。SDK 用它给请求签名(密钥本身不随请求发送)。逆向能拿到,它的作用是挡住抓包重放和裸爬 |
| AppSecret | 管理后台生成,只显示一次 | 绝对不能。只用于接入方服务器与平台之间(激励视频发奖回调验签等),进了安装包等于公开 |
SDK 没有任何接收 AppSecret 的入口
看到哪份文档要求把 AppSecret 填进客户端,那份文档是错的。它的用途见《服务端对接》。
凭证建议从构建配置注入(Android 用 BuildConfig 或本地 properties,iOS 用 .xcconfig 经 Info.plist 读出),不要硬编码进源码提交到公开仓库。
更换 App 密钥
同一个应用允许多把 App 密钥同时有效。怀疑泄露时按这个顺序操作,线上用户不受影响:
- 在管理后台为该应用新增一把 App 密钥(旧的先不动)
- 宿主 App 换成新密钥,发版
- 大部分用户升级后,在后台作废旧密钥 —— 作废立即生效,仍在用旧密钥的老版本会拉不到 新配置(已缓存的配置照常使用)
传输安全
签名只证明请求来源,不加密内容。SDK 内置地址全部是 HTTPS,配置里的平台广告位 ID 和底价 不会在链路上明文传输。
Android 明文流量
不要为 AdMix 放开明文流量
宿主 App 不需要为 AdMix 配置 network_security_config,也不要用 android:usesCleartextTraffic="true" —— 那会把两家广告 SDK 的全部上报和素材请求 也一起降级成明文可用,授权范围远超需要。
iOS App Transport Security
AdMix 自身的请求全部走 HTTPS,不需要为 AdMix 放开 ATS。 但两家广告平台的部分素材走明文 http,iOS 上不放开 ATS 时素材会被系统拦截、广告位出现空白, 这一项是为广告平台配置的。取舍与对照实验见《引入依赖》「网络安全配置」。
拉取行为
拉取时机:有本地缓存就先用缓存、后台再刷新;没有缓存则 start 会等这一次请求, 详见《初始化》的第二步。
- 拉到的配置会持久化到 SDK 私有的存储(Android 为 SharedPreferences, iOS 为 App 沙盒的
Library/Application Support/AdMix/),下次冷启动直接用它, 不再从包内兜底配置起步 - 请求带
If-None-Match,配置没变时服务端回 304,不传输也不解析,省流量 - 签名参数走 query、协商缓存走请求头,两者互不干扰
- 每次请求的
nonce都是新的(服务端有防重放校验),所以 URL 每次都不一样
不要在链路中间加按 URL 缓存的代理
每次请求的 nonce 不同,按 URL 做缓存的代理会让协商缓存完全失效,也可能触发防重放校验。
可选:在宿主包内放一份兜底配置 admix_config.json(只含广告位策略;Android 放 assets/, iOS 加进主 Bundle 的资源),格式见《策略配置格式》。不放也完全正常。
拉取失败的行为
远端拉取失败一律保留当前配置,绝不清空 —— 拉不到配置就没广告,比配置旧一天严重得多。
唯一的例外是装机后真正的第一次冷启动:本地一份配置都没有,这时拉取失败就意味着连广告平台的 应用 ID 都不知道,start 只能回调失败(Android onFail、iOS completion 带 error;日志:start 失败:没有拿到任何 ADN 配置)。 这是把应用 ID 从宿主包里拿掉之后必然要付的代价 —— 不这样做,就要退回到「每个开发者一个接入包」。
拉不到配置的排查
先确认两件事:start 到底调了没有、调用时机是否在「同意隐私政策」之后。没调就一定拉不到。
然后看 AdMix 标签的日志里有没有 远端配置加载完成。没有就按下表对号:
| 日志 | 原因 | 怎么办 |
|---|---|---|
远端配置鉴权失败(40101 签名错误) | AppID 与 App 密钥对不上,或该密钥已作废 | 对照管理后台逐字核对,注意别把 AppSecret 当成 App 密钥 |
远端配置拉取失败(404 code=40402):该应用尚未发布配置… | 平台运营已录入平台应用 ID 与平台广告位,但还没发布配置。新应用最常见 | 将 AppID 提供给平台运营,由平台运营在管理后台「策略配置」中发布。发布后无需改动宿主 App,下次调用 start 即可拉到 |
远端配置拉取失败(404 code=40401):应用不存在或已停止服务… | AppID 抄错,或该应用已被平台停止服务 | 先对照管理后台逐字核对 AppID;一致时联系平台运营确认应用状态 |
远端配置鉴权失败(40103 nonce 重放) | 同一请求被重发 | 检查链路上有没有会重放请求的代理 |
已按服务端时间校正时钟…重新签名重试一次 | 本机时间不准,SDK 已自动校正 | 不用处理,正常自愈 |
远端配置加载失败… | 网络异常、超时(Android SDK 连接 / 读取超时都是 3 秒,iOS 单次请求超时 6 秒) | 确认设备能访问 https://api.maemi.cn |
日志含 -1009 与「允许 App 使用无线数据」(iOS) | 国行 iPhone 首次安装,用户尚未允许 App 使用无线数据 | 用户允许后回到前台,SDK 自动重拉,见《初始化》「首次安装的网络授权」 |
start 失败:没有拿到任何 ADN 配置 | 装机后第一次冷启动且这次拉取失败(本地一份缓存都没有);iOS 上新建应用未审核启用时同样如此,见《错误码参考》「iOS 启动失败排查」 | 按无广告降级。Android 联网后再调一次 start();iOS 回到前台时若仍无配置会自动重拉 |
日志里的 code 与说明来自服务端
code= 后面的错误码与冒号后的说明都是服务端响应体({"code","msg"})的原文,SDK 原样打出来, 不需要抓包也不需要找平台运营查。取不到响应体时(例如被网关拦下、返回的不是 JSON) 退回只打状态码:远端配置响应码异常 404,继续使用当前配置。 全部错误码见《错误码参考》「配置下发接口错误码」。
配置拉到了但某家广告平台不在里面时,看日志里的 服务端按本机能力裁掉: gdt —— 说明宿主没引那家的适配器,服务端按上报的能力主动摘掉了。这是正常机制,不是故障, 见《引入依赖》「按需集成单家广告平台」。
客户端时钟校正
签名带时间戳,服务端只接受 ±5 分钟以内的请求。用户手机时间不准是常态 (手动改过时间、长期断电后未联网对时),偏差超窗后配置就再也拉不下来了, 而且表现是「一切正常,只是配置一直不更新」,没有任何报错。
SDK 的处理:收到「时间戳过期」时,用响应的 Date 头算出本机与服务端的时钟差,落盘保存, 立刻重签重试一次;下次冷启动直接带校正后的时间戳,不再浪费一个来回。
接入方不需要做任何事,也不要去改用户的系统时间。
随请求上报的客户端能力
拉配置时 SDK 会额外带三个查询参数,服务端据此裁剪下发内容(iOS 另带第四个 att):
| 参数 | 内容 |
|---|---|
sdk_ver | SDK 版本号 |
adapters | 实际发现的适配器代号,逗号分隔(运行时探测结果,不是写死清单:Android 来自 SPI,iOS 来自按类名前缀的发现) |
adn_vers | 各广告 SDK 的运行时实际版本,用于平台侧发现版本被顶 |
att(仅 iOS) | 跟踪授权状态:notDetermined / restricted / denied / authorized,iOS 14 以下为 na。只是授权结果,不是 IDFA;用于区分填充率与单价的波动原因 |
这些参数不纳入签名,签名原文仍是 app_id / nonce / ts / key 四项。 纳入签名意味着以后每加一个参数都要两端同步发版,而老版本算出来的签名会因少一个参数全部 401 —— 配置拉不到就是线上没广告。