Swift中URL百分号编码转ASCII并提取查询参数的实现方法
Swift 回调URL百分号编码解码及参数提取方案
问题场景
在使用ASWebAuthenticationSession实现浏览器认证时,服务端返回的回调URL格式为自定义scheme拼接编码后的参数:
mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=
直接替换scheme后的冒号为问号后编码会被转义,无法用URLComponents正常提取queryItems;直接解析原始URL的话参数会全部放到path字段中,需要先将百分号编码的内容转为明文后再解析。
解决方法
Swift 原生字符串已经内置了百分号编码的解码能力,直接调用 removingPercentEncoding 属性即可将所有%开头的十六进制编码序列转换为对应的ASCII字符,不需要手动实现编码匹配逻辑。
完整的参数解析流程代码如下:
// 拿到拦截到的原始回调URL字符串 let rawCallbackURLString = "mycallback:un%3Dtest%26as%3D1%26token%3DeyJiYmIiOiJBc2RhIiwgImRzY3ZnIjoiYXNhc2NkIn0=" // 第一步:先做百分号解码 guard let decodedString = rawCallbackURLString.removingPercentEncoding else { // 解码异常时的处理逻辑 print("百分号解码失败") return } // 第二步:将scheme后的冒号替换为问号,构造符合URL规范的带query的格式 let standardURLString = decodedString.replacingOccurrences(of: ":", with: "?") // 第三步:用URLComponents正常解析参数 guard let urlComponents = URLComponents(string: standardURLString), let queryItems = urlComponents.queryItems else { print("URL解析失败") return } // 按需提取对应参数值 let username = queryItems.first { $0.name == "un" }?.value let authStatus = queryItems.first { $0.name == "as" }?.value let token = queryItems.first { $0.name == "token" }?.value
注意事项
- 解码操作要放在替换分隔符之前执行,避免分隔符被编码导致URL结构识别失败
removingPercentEncoding遵循RFC 3986规范,会自动处理所有合法的百分号编码序列,遇到非法编码会返回nil,做好异常判断即可
内容的提问来源于stack exchange,提问作者Zohar81
相关产品推荐
相关产品推荐

