使用Alamofire 5.6.2发起请求时部分设备App崩溃求助
问题场景
部分设备上,执行以下Alamofire请求代码时App发生崩溃:
AF.request(request).validate(statusCode: 200...500).responseJSON { response in // 响应处理逻辑 }
崩溃日志关键信息
来自TestFlight的崩溃栈显示,崩溃根源在NSJSONSerialization的序列化方法中:
Last Exception Backtrace:
0 CoreFoundation 0x1993badc0 __exceptionPreprocess + 220 (NSException.m:199)
1 libobjc.A.dylib 0x1adf177a8 objc_exception_throw + 60 (objc-exception.mm:565)
2 Foundation 0x19a67d61c +[NSJSONSerialization dataWithJSONObject:options:error:] + 316 (NSJSONSerialization.m:0)
3 GO_Dev 0x100c59aec closure #1 in closure #1 in AutoSyncLoginVC.callSyncLoginAPI(username:password:) + 628 (AutoSyncLoginVC.swift:343)
4 GO_Dev 0x100d9611c closure #1 in ApiManagerV2.requestWith(apiname:body:parameter:mainIP:method:success:failure:) + 2064 (ApiManager.swift:0)
5 Alamofire 0x10219a544 partial apply for specialized closure #2 in closure #2 in closure #3 in closure #1 in DownloadRequest._response(queue:responseSerializer:completionHandler:) + 48
6 Alamofire 0x10212ddd0 thunk for @escaping @callee_guaranteed () -> () + 28 (:0)
问题原因
崩溃发生在NSJSONSerialization序列化环节,说明服务器返回的响应数据不符合JSON格式规范,可能的情况包括:
- 响应数据是非JSON格式的字符串(比如HTML错误页、纯文本提示)
- JSON结构存在语法错误(比如缺少括号、引号不匹配)
- 数据包含JSON无法序列化的特殊字符或编码问题
- 部分设备/网络环境下,服务器返回了异常响应内容
解决办法
捕获序列化错误并记录原始数据
在responseJSON回调中先处理错误,避免崩溃同时排查问题:AF.request(request).validate(statusCode: 200...500).responseJSON { response in switch response.result { case .success(let json): // 正常处理JSON数据 case .failure(let error): // 捕获错误并记录日志 print("JSON序列化失败: \(error)") // 获取原始响应内容,排查服务器返回的异常数据 if let data = response.data, let rawContent = String(data: data, encoding: .utf8) { print("原始响应内容: \(rawContent)") } } }改用responseData手动处理序列化
如果服务器偶尔返回非JSON数据,先获取原始Data再手动处理,避免Alamofire内部序列化崩溃:AF.request(request).validate(statusCode: 200...500).responseData { response in switch response.result { case .success(let data): do { let json = try JSONSerialization.jsonObject(with: data) // 处理JSON数据 } catch { // 序列化失败,处理非JSON响应 if let rawContent = String(data: data, encoding: .utf8) { print("非JSON响应内容: \(rawContent)") // 这里可以根据业务做降级处理,比如提示服务器错误 } } case .failure(let error): print("请求失败: \(error)") } }排查服务器响应逻辑
根据日志中捕获的原始响应内容,和后端团队确认是否存在针对特定设备、网络场景返回非标准JSON的情况,修复服务器输出格式。升级Alamofire版本
5.6.2版本相对较旧,后续版本可能对JSON序列化的异常处理做了优化,可尝试升级到最新稳定版(升级前需做兼容性测试)。
内容的提问来源于stack exchange,提问作者Red Heart

