iOS Message Extension请求报NSURLErrorDomain DNS错误如何修复
iOS Message Extension 网络请求报主机名找不到故障排查
问题现象
开发iOS垃圾短信过滤Message Extension时,依赖服务端能力完成过滤逻辑,向服务端发起请求时返回NSURLErrorDomain错误,错误提示为「A server with the specified hostname could not be found」,堆栈指向DNS解析环节失败。
已完成配置
- 已开启Associated Domains能力,配置值:
messagefilter:mydomain.io - 已在Message Extension的
Info.plist中配置ILMessageFilterExtensionNetworkURL键,对应取值:https://mydomain.io/api/v1/sms
测试代码
let url = URL(string: "https://mydomain.io/api/v1/sms")! var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("you-value-goes-here", forHTTPHeaderField: "X-API-KEY") let task = URLSession.shared.dataTask(with: request) { data, _, error in if let data = data { print(data) } else if let error = error { print("Http failed: \(error)") } } task.resume()
错误堆栈
[0] (null) "_kCFStreamErrorCodeKey" : Int32(-72000) [1] (null) "NSUnderlyingError" : domain: "kCFErrorDomainCFNetwork" - code: 18446744073709550613 [2] (null) "_NSURLErrorFailingURLSessionTaskErrorKey" : "LocalDataTask <B496A974-7009-4FCE-BF45-FEC07BA1E8DF>.<1>" [3] (null) "_NSURLErrorRelatedURLSessionTaskErrorKey" : 1 element [4] (null) "NSLocalizedDescription" : "A server with the specified hostname could not be found."
故障根因
这个报错90%以上不是真实的公网DNS解析故障,是iOS系统对Message Extension的网络权限校验失败后,直接拦截请求返回的伪造错误:
- Message Filter Extension属于高权限受限扩展,系统不会默认给扩展开放任意网络访问权限,必须通过Associated Domains关联校验后,才会放行对应配置域名的网络请求
- 关联校验的核心是域名服务端必须部署符合苹果要求的
apple-app-site-association(简称AASA)文件,文件缺失、格式错误、访问异常都会导致校验失败,系统直接拦截所有到该域名的请求,对外表现为找不到主机名的DNS错误 - 配置不匹配:Associated Domains配置的域名和
ILMessageFilterExtensionNetworkURL的域名不一致、调试/生产模式配置错误也会触发该拦截
修复步骤
- 部署符合要求的AASA文件
- 在域名的
https://mydomain.io/.well-known/apple-app-site-association路径部署文件,文件不能加.json后缀,HTTP状态码必须返回200,不能有301/302跳转,MIME类型设置为application/json,文件大小不超过128KB,站点HTTPS证书必须为苹果信任的CA签发,不能用自签名证书 - 文件内容参考如下格式,注意替换为自己的团队ID和扩展Bundle ID:
{ "messagefilter": { "apps": ["YOUR_TEAM_ID.com.yourcompany.message-filter-extension"] } }注意:apps数组里填写的是Message Extension target的Bundle ID,不是主iOS App的Bundle ID,前缀为你苹果开发者账号的10位团队ID。
- 在域名的
- 修正Associated Domains配置
- 本地调试阶段,配置值改为
messagefilter:mydomain.io?mode=developer,允许调试模式下绕过部分缓存校验;App Store上架版本必须去掉?mode=developer后缀 - 如果接口实际部署在子域名(比如
api.mydomain.io),Associated Domains必须对应配置为messagefilter:api.mydomain.io,和ILMessageFilterExtensionNetworkURL中的域名完全一致,Message Filter扩展不支持泛域名关联配置
- 本地调试阶段,配置值改为
- 触发关联配置重新校验
- AASA文件部署完成、配置修改完毕后,卸载测试设备上的App,重新编译安装。iOS只会在App首次安装、更新时拉取AASA文件做校验,本地缓存不会实时更新,卸载重装是最快触发重新校验的方式
- 兜底校验
- 上述步骤完成后如果仍报错,在和测试设备同一网络环境下执行
nslookup mydomain.io,确认域名公网解析正常,排除真实DNS解析故障。
- 上述步骤完成后如果仍报错,在和测试设备同一网络环境下执行
内容的提问来源于stack exchange,提问作者kha
相关产品推荐
相关产品推荐

