如何在 Swift 4 中将 NSmutableURLRequest 转换为 URLRequest?
how to convert NSmutableURLRequest to URLRequest in Swift 4?
func requestForAccessToken(authorizationCode: String) {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
// Set the POST parameters.
var postParams = "grant_type=\(grantType)&"
postParams += "code=\(authorizationCode)&"
postParams += "redirect_uri=\(String(describing: redirectURL))&"
postParams += "client_id=\(linkedInKey)&"
postParams += "client_secret=\(linkedInSecret)"
let postData = postParams.data(using: String.Encoding.utf8)
let request = NSMutableURLRequest(url: NSURL(string: accessTokenEndPoint)! as URL)
request.httpMethod = "POST"
//http body
request.httpBody = postData
//headerfield
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// init the session
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
// Throwing and error it needs a URLRequest at session.dataTask("Here")
// Below is the error Xcode yells
// Ambiguous reference to member 'dataTask(with:completionHandler:)
}
}
使用如下
let task: URLSessionDataTask = session.dataTask(with: request as URLRequest ) { (data, response, error) in
}
我想补充几点:
1. 正确解包可选,使用if-let/guard-let
。
2. NS大部分时间来自Objective-C,所以去掉NS就是swift(大部分时间)
func requestForAccessToken(authorizationCode: String) {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
var postParams = "grant_type=\(grantType)&"
postParams += "code=\(authorizationCode)&"
postParams += "redirect_uri=\(String(describing: redirectURL))&"
postParams += "client_id=\(linkedInKey)&"
postParams += "client_secret=\(linkedInSecret)"
guard let url = URL(string: accessTokenEndPoint) else {
return
}
let postData = postParams.data(using: .utf8) // Suggested by rmaddy
var request = URLRequest(url: url)
//let request = NSMutableURLRequest(url: NSURL(string: accessTokenEndPoint)! as URL)
request.httpMethod = "POST"
request.httpBody = postData
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
}
task.resume()
}
您可以使用此功能创建 http 正文:
private let linkedInKey = ""
private let linkedInSecret = ""
func postBody(authorizationCode: String) -> String {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth"
return [
"grant_type":grantType,
"code":authorizationCode,
"redirect_uri":redirectURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed),
"client_id":linkedInKey,
"client_secret":linkedInSecret
].enumerated().compactMap {
if let valueForKey = .value {
return .key + "=" + valueForKey
}
return nil
}.joined(separator: "&")
}
现在函数 requestForAccessToken(authorizationCode:)
会更短:
func requestForAccessToken(authorizationCode: String) {
if var urlComponents = URLComponents(string: "https://com.appcoda.linkedin.oauth") {
urlComponents.path = "/oauth"
if let urlComponentsURL = urlComponents.url {
var request = URLRequest(url: urlComponentsURL)
request.httpMethod = "POST"
request.httpBody = self.postBody(authorizationCode: authorizationCode).data(using: .utf8)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
}
task.resume()
}
}
}
func requestForAccessToken(authorizationCode: String) {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
// Set the POST parameters.
var postParams = "grant_type=\(grantType)&"
postParams += "code=\(authorizationCode)&"
postParams += "redirect_uri=\(String(describing: redirectURL))&"
postParams += "client_id=\(linkedInKey)&"
postParams += "client_secret=\(linkedInSecret)"
let postData = postParams.data(using: String.Encoding.utf8)
let request = NSMutableURLRequest(url: NSURL(string: accessTokenEndPoint)! as URL)
request.httpMethod = "POST"
//http body
request.httpBody = postData
//headerfield
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// init the session
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
// Throwing and error it needs a URLRequest at session.dataTask("Here")
// Below is the error Xcode yells
// Ambiguous reference to member 'dataTask(with:completionHandler:)
}
}
使用如下
let task: URLSessionDataTask = session.dataTask(with: request as URLRequest ) { (data, response, error) in
}
我想补充几点:
1. 正确解包可选,使用if-let/guard-let
。
2. NS大部分时间来自Objective-C,所以去掉NS就是swift(大部分时间)
func requestForAccessToken(authorizationCode: String) {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
var postParams = "grant_type=\(grantType)&"
postParams += "code=\(authorizationCode)&"
postParams += "redirect_uri=\(String(describing: redirectURL))&"
postParams += "client_id=\(linkedInKey)&"
postParams += "client_secret=\(linkedInSecret)"
guard let url = URL(string: accessTokenEndPoint) else {
return
}
let postData = postParams.data(using: .utf8) // Suggested by rmaddy
var request = URLRequest(url: url)
//let request = NSMutableURLRequest(url: NSURL(string: accessTokenEndPoint)! as URL)
request.httpMethod = "POST"
request.httpBody = postData
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
}
task.resume()
}
您可以使用此功能创建 http 正文:
private let linkedInKey = ""
private let linkedInSecret = ""
func postBody(authorizationCode: String) -> String {
let grantType = "authorization_code"
let redirectURL = "https://com.appcoda.linkedin.oauth/oauth"
return [
"grant_type":grantType,
"code":authorizationCode,
"redirect_uri":redirectURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed),
"client_id":linkedInKey,
"client_secret":linkedInSecret
].enumerated().compactMap {
if let valueForKey = .value {
return .key + "=" + valueForKey
}
return nil
}.joined(separator: "&")
}
现在函数 requestForAccessToken(authorizationCode:)
会更短:
func requestForAccessToken(authorizationCode: String) {
if var urlComponents = URLComponents(string: "https://com.appcoda.linkedin.oauth") {
urlComponents.path = "/oauth"
if let urlComponentsURL = urlComponents.url {
var request = URLRequest(url: urlComponentsURL)
request.httpMethod = "POST"
request.httpBody = self.postBody(authorizationCode: authorizationCode).data(using: .utf8)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: URLSessionConfiguration.default)
let task: URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
}
task.resume()
}
}
}