python - 如何像我目前正在使用的工作 Python 请求一样在 Swift 中发出 API 请求?
问题描述
我希望将此 Python 请求转换为 Swift 脚本。
这是我的工作 python 脚本,它返回 accessToken!
#!/usr/bin/python
import requests
import json
#MAKE THE REQUEST
URL = "http://this/is/the/url"
headers = {
'Accept': "application/json",
"Accept-Language": "en_US"
}
data = {
"grant_type": "password",
"username" : "GROUP\SITE\USERNAME",
"password" : "somepassword"
}
r = requests.get(url = URL, params = headers, data = data)
data = r.json()
accessToken = data['access_token']
print(accessToken)
当我为下面的代码运行 Swift Playground 时,没有返回任何内容!似乎脚本在守卫时退出 let data = data else { return }
我怎样才能得到与上面的 Python 脚本相同的结果。 我已经尝试使用本教程实现 URLComponents ......
import UIKit
var url = "http://just/the/url"
extension Dictionary {
func percentEncoded() -> Data? {
return map { key, value in
let escapedKey = "\(key)"
let escapedValue = "\(value)"
print(escapedKey + "=" + escapedValue)
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}
var request = URLRequest(url: URL(string:url)!)
request.httpMethod = "GET"
let parameters: [String: String] = [
"grant_type":"password",
"username":"GROUP\\SITE\\USER",
"password":"somePassword"
]
request.httpBody = parameters.percentEncoded()
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/XML", forHTTPHeaderField: "Accept")
let config = URLSessionConfiguration.default
URLSession(configuration: config).dataTask(with: request) { (data, response, err) in
guard let data = data else { return }
print(data)
guard let dataAsString = String(data: data, encoding: .utf8)else {return}
print(dataAsString)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Bad Credentials")
return
}
//HTTP Status Code!
print("HTTP RESPONSE:"+"\(httpResponse.statusCode)")
//
}.resume()
解决方案
如果我没记错的话,从 iOS 13 开始,您不能使用 httpBody 进行 GET 调用,因此您需要切换到 POST/PUT 或将参数添加到 url 字符串中(见下文)您还有不同Accept
的标题你的蟒蛇与斯威夫特。一个是xml,另一个是json。
var urlComponents = URLComponents(string: "http://this/is/the/url")
urlComponents?.queryItems = [
URLQueryItem(name: "grant_type", value: "password"),
URLQueryItem(name: "username", value: "username"),
URLQueryItem(name: "password", value: "somepassword")
]
guard let url = urlComponents?.url else { return } // You can print url here to see how it looks
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("en_US", forHTTPHeaderField: "Accept-Language")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
error == nil else {
print("error", error ?? "Unknown error")
return
}
print(response)
guard (200 ... 299) ~= response.statusCode else {
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
print(responseString)
}
task.resume()
推荐阅读
- twitter-bootstrap - 选择日期值后,引导日期选择器会引发错误?
- python - 有没有办法在维护自定义特征工程类的同时保存这个模型?
- authorization - 集成 Auth0 自定义数据库和无密码
- ruby - 获取 Ruby 中任何给定模块的嵌套层次结构
- python - 如何在特定位置将字符串添加到另一个字符串?
- excel - “不包含”的函数 (InStr()=0)
- google-cloud-storage - 将存储桶移动到其他存储类
- php - Laravel Eloquent 多重关系
- python - 我对 matplotlib.axes 的第二个参数的作用感到困惑
- java - 如何在 Android 中触发 BroadcastReceiver 之前启动服务?