iOS UrlSession.shared.dataTask 删除 utf-8“+”字符并用“”替换它

iOS UrlSession.shared.dataTask removes utf-8 "+" character and replaces it with " "

我正在使用 x-www-form-endoded 数据创建对 API 的登录调用。我在 Postman 中创建了一个 POST 并收到了 200 响应。我使用 Postman 的导出功能为 Android 生成了 OKHTTP 代码,为 iOS 生成了 NSURL 代码。 Android 代码工作正常,但 iOS 代码收到 401 响应。我使用 Charles Web 调试代理来查看实际为有效负载发送的内容。对于 android,用户名正确表示为 "username=james+jypsee@jypsee.com",但在 iOS 中,它显示为 "username=james jypsee@jypsee.com"。我的 iOS 代码如下:

let headers = [
  "accept": "application/json",
  "cache-control": "no-cache",
  "content-type": "application/x-www-form-urlencoded"
]

let postData = NSMutableData(data: "username=james+jypsee@jypsee.com".data(using: .utf8)!)
postData.append("&password=redacted".data(using: .utf8)!)
postData.append("&grant_type=password".data(using: .utf8)!)
postData.append("&client_id=redacted".data(using: .utf8)!)
postData.append("&client_secret=redacted".data(using: .utf8)!)

    let request = NSMutableURLRequest(url: NSURL(string: "https://redacted.com/api/oauth2/token/")! as URL,
                                      cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data
    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
        if (error != nil) {
            print(error)
        } else {
            let httpResponse = response as? HTTPURLResponse
            print(httpResponse)
        }
    })

当我单步执行 iOS 代码时,NSMutableData 和 Data 对象都正确地将用户名显示为 "username=james+jypsee@jypsee.com",只是留下 URLSession.shared 作为潜在的错误原因。但是我不能进入 URLSession.shared.dataTask() 因为它是一个私有方法。感谢任何帮助。

“+”字符的编码存在一些问题。您可以试试这个:

let postData = NSMutableData(data: "username=james%2Bjypsee@jypsee.com".data(using: .utf8)!)