使用 Swift URLSession 将标头传递给 URL
Posted
技术标签:
【中文标题】使用 Swift URLSession 将标头传递给 URL【英文标题】:Passing headers to URL with Swift URLSession 【发布时间】:2019-10-23 08:19:32 【问题描述】:我不想分享实际链接,因为它可能包含一些私人信息,所以如果它不起作用,请不要感到惊讶。
我有一个如下所示的链接:www.somelink.com/stuff/searchmembers?member=John
还有一些我需要传递的标头,例如Login: Admin, Password: Admin
当我使用this site 时,一切似乎都运行良好,我放置了链接,将其设为 GET 并将标题放入 key:value 格式,结果我得到了所有成员的列表,但我该怎么做与 URLSession 一样吗?这是我目前拥有的,我什么都没有。我在那里做错了什么?
func getAllMembers(urlString: String)
guard let url = URL(string: urlString) else return
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Admin", forHTTPHeaderField: "Login")
request.setValue("Admin", forHTTPHeaderField: "Password")
request.httpBody = "member=John".data(using: .utf8)!
URLSession.shared.dataTask(with: request) (data, response, error) in
print(response)
print(data)
.resume()
【问题讨论】:
request.httpBody = "member=John".data(using: .utf8)!
,这不是在您的网址末尾添加它。我不熟悉 Reqbin,也没有赞助 POSTMAN,但后来的解决方案可以为您生成 Swift 代码(不漂亮),但理解足以发现您和他们之间的问题。
你用邮递员试过这个吗?
我不知道 Postman,但它确实有效。谢谢!
【参考方案1】:
这是你做错了:
您的member=John
实际上是一个URL 查询参数。通常,URL 请求将查询参数作为 URL 字符串本身的一部分,而不是 httpbody。
快速而肮脏的解决方案:
如果你删除,你应该很高兴
request.httpBody = "member=John".data(using: .utf8)!
而是将整个 "www.somelink.com/stuff/searchmembers?member=John"
传递给您的 getAllMembers(urlString:)
函数。
更好的解决方案:
假设 John 的用户名是 j o h n
。您的函数不会超过第一个 guard
,因为空格不是有效的 URL 字符串字符。
我喜欢使用URLComponents,因为它省去了处理空格等的麻烦。
我会这样写你的函数:
func getJohnMember(urlString: String)
//URLComponents to the rescue!
var urlBuilder = URLComponents(string: urlString)
urlBuilder?.queryItems = [
URLQueryItem(name: "member", value: "j o h n")
]
guard let url = urlBuilder?.url else return
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Admin", forHTTPHeaderField: "Login")
request.setValue("Admin", forHTTPHeaderField: "Password")
URLSession.shared.dataTask(with: request) (data, response, error) in
print(response)
print(String(data: data, encoding: .utf8)) //Try this too!
.resume()
为了清楚起见,我只会将"www.somelink.com/stuff/searchmembers"
传递给第一个参数。
现在如果我在guard let
之后到print(url)
,我会得到
www.somelink.com/stuff/searchmembers?member=j%20o%20h%20n
这样更容易,不是吗?
【讨论】:
【参考方案2】:member=John
是一个 URL 查询参数,不是请求正文的一部分。所以你需要将它添加到 URL 本身。
func getAllMembers(urlString: String)
guard let url = URL(string: "\(urlString)?member=John") else return
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Admin", forHTTPHeaderField: "Login")
request.setValue("Admin", forHTTPHeaderField: "Password")
URLSession.shared.dataTask(with: request) (data, response, error) in
print(response)
print(data)
.resume()
【讨论】:
URLQueryItem
是添加该成员名称的正确方法,而不是附加到 url。接受的答案正确地涵盖了这一点。这会起作用,但是......“这没有错,但我们只是不这样做” - Gordon。以上是关于使用 Swift URLSession 将标头传递给 URL的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 来自URLSession任务的TableView数据源
Swift 3 ObjectMapper - 将 URLSession 结果转换为 Map 对象失败
URLSession 配置的标头设置仅适用于 PUT,不适用于 POST