iOS Swift解码JWT得到__NSArray0无法操作,该如何正确处理?
__NSArray0的定义
__NSArray0是Foundation框架中NSArray类簇的私有子类,是系统针对不可变空数组做的性能优化实现。所有内容为空的不可变NSArray都会复用同一个__NSArray0全局实例,用来降低空数组的内存占用。
它支持和Swift原生Array类型的Toll-Free桥接,无法执行遍历操作的核心原因是没有做类型转换,直接把未指定类型的NSObject实例当做数组使用了。
正确解码JWT的实现方案
推荐优先使用Swift原生Codable协议做类型安全的解码,具体实现步骤如下:
- 拆分JWT字符串的三段结构,取出中间的payload段
- 对payload段做base64url格式兼容处理:补全
=填充符,替换-为+、_为/ - 定义和JWT payload结构匹配的Codable模型
- 使用JSONDecoder解码为对应的模型实例
示例代码如下:
// 匹配JWT结构的模型 struct JWTPayload: Codable { let data: [UserInfo] // 无用户数据时自动解析为空数组,支持正常遍历操作 let exp: TimeInterval // 按需添加其他JWT标准字段,如过期时间、签发时间等 } struct UserInfo: Codable { // 按实际业务定义用户数据字段,例如用户ID、昵称等 let userId: String let nickname: String } // 解码工具方法 enum JWTParseError: Error { case invalidFormat case invalidBase64 case decodeFailed } func parseJWT(token: String) throws -> JWTPayload { let segments = token.components(separatedBy: ".") guard segments.count == 3 else { throw JWTParseError.invalidFormat } // 处理base64url格式 var payloadStr = segments[1] .replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") // 补全base64填充符 let paddingCount = (4 - payloadStr.count % 4) % 4 if paddingCount > 0 { payloadStr.append(contentsOf: String(repeating: "=", count: paddingCount)) } guard let payloadData = Data(base64Encoded: payloadStr) else { throw JWTParseError.invalidBase64 } do { return try JSONDecoder().decode(JWTPayload.self, from: payloadData) } catch { throw JWTParseError.decodeFailed } }
如果要兼容现有JSONSerialization的解析逻辑,只需对返回的data字段做显式类型转换即可:
if let jsonDict = try? JSONSerialization.jsonObject(with: payloadData) as? [String: Any], let dataArray = jsonDict["data"] as? [Any] { // 此处dataArray为Swift原生数组类型,无论底层是否为__NSArray0都会自动桥接,可正常遍历 for item in dataArray { // 处理数组元素 } }
内容的提问来源于stack exchange,提问作者jwknz
相关产品推荐
相关产品推荐

