首页 > 解决方案 > 如何像我目前正在使用的工作 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()

标签: pythonswifturlrequest

解决方案


如果我没记错的话,从 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()

推荐阅读