我正在尝试将Yahoo API服务集成到我的IOS应用(https://developer.yahoo.com/weather/documentation.html#oauth-swift)中。我对于android没有任何问题,但是现在我遇到了swift和Xcode11的编译器问题。我添加了Oauth pod:https://cocoapods.org/pods/OAuthSwift,以及文档中的代码:
import Foundation
/*
See https://github.com/OAuthSwift/OAuthSwift for information on
including this OAuth library in your project.
*/
import OAuthSwift
enum YahooWeatherAPIResponseType:String {
case json = "json"
case xml = "xml"
}
enum YahooWeatherAPIUnitType:String {
case imperial = "f"
case metric = "c"
}
fileprivate struct YahooWeatherAPIClientCredentials {
var appId = ""
var clientId = ""
var clientSecret = ""
}
class YahooWeatherAPI {
// Configure the following with your values.
private let credentials = YahooWeatherAPIClientCredentials(appId: "-your-app-id-", clientId: "-your-client-id-", clientSecret: "-your-client-secret-")
private let url:String = "https://weather-ydn-yql.media.yahoo.com/forecastrss"
private let oauth:OAuth1Swift?
public static let shared = YahooWeatherAPI()
private init() {
self.oauth = OAuth1Swift(consumerKey: self.credentials.clientId, consumerSecret: self.credentials.clientSecret)
}
private var headers:[String:String] {
return [
"X-Yahoo-App-Id": self.credentials.appId
]
}
/// Requests weather data by location name.
///
/// - Parameters:
/// - location: the name of the location, i.e. sunnyvale,ca
/// - failure: failure callback
/// - success: success callback
/// - responseFormat: .xml or .json. default is .json.
/// - unit: metric or imperial units. default = .imperial
public func weather(location:String, failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial) {
self.makeRequest(parameters: ["location":location, "format":responseFormat.rawValue, "u":unit.rawValue], failure: failure, success: success)
}
/// Requests weather data by woeid (Where on Earth ID)
///
/// - Parameters:
/// - woeid: The location's woeid
/// - failure: failure callback
/// - success: success callback
/// - responseFormat: .xml or .json. default is .json.
/// - unit: metric or imperial units. default = .imperial
public func weather(woeid:String, failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial) {
self.makeRequest(parameters: ["woeid":woeid, "format":responseFormat.rawValue, "u":unit.rawValue], failure: failure, success: success)
}
/// Requests weather data by latitude and longitude
///
/// - Parameters:
/// - lat: latitude
/// - lon: longiture
/// - failure: failure callback
/// - success: success callback
/// - responseFormat: .xml or .json. default is .json.
/// - unit: metric or imperial units. default = .imperial
public func weather(lat:String, lon:String, failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial) {
self.makeRequest(parameters: ["lat":lat, "lon":lon, "format":responseFormat.rawValue, "u":unit.rawValue], failure: failure, success: success)
}
/// Performs the API request with the OAuthSwift client
///
/// - Parameters:
/// - parameters: Any URL parameters to pass to the endpoint.
/// - failure: failure callback
/// - success: success callback
private func makeRequest(parameters:[String:String], failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void) {
self.oauth?.client.request(self.url, method: .GET, parameters: parameters, headers: self.headers, body: nil, checkTokenExpiration: true, success: success, failure: failure)
}
}
但是我在最后一个makerequest函数中看到了编译器错误“ Extra parameter” failure“(请参阅附件)。
private func makeRequest(parameters:[String:String], failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void) {
self.oauth?.client.request(self.url, method: .GET, parameters: parameters, headers: self.headers, body: nil, checkTokenExpiration: true, success: success, failure: **failure**)
}
有人在Oauth和此类问题上有经验吗?有人可以帮我吗?
非常感谢
我现在要得到这个
我认为问题在于UIViewController中的初始请求和完成处理程序之间的连接:
YahooWeatherAPI.shared.weather(location: "sunnyvale,ca", failure: { (error) in
print(error.localizedDescription)
}, success: { (response) in
print(response.string as Any)
}, responseFormat: .xml, unit: .metric)
self.makeRequest(参数:[“位置”:位置,“格式”:responseFormat.rawValue,“ u”:unit.rawValue],完成:)]
}
/// Performs the API request with the OAuthSwift client
///
/// - Parameters:
/// - parameters: Any URL parameters to pass to the endpoint.
/// - failure: failure callback
/// - success: success callback
private func makeRequest(parameters:[String:String], completion: @escaping OAuthSwift.TokenCompletionHandler) -> OAuthSwiftRequestHandle? {
let completionHandler: OAuthSwiftHTTPRequest.CompletionHandler = { [weak self] result in
guard let this = self else {
return
}
self.makeRequest(parameters: ["location":location, "format":responseFormat.rawValue, "u":unit.rawValue], completion: )
}
/// Performs the API request with the OAuthSwift client
///
/// - Parameters:
/// - parameters: Any URL parameters to pass to the endpoint.
/// - failure: failure callback
public func weather(location:String, failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial) {
///-成功:成功回调私有函数makeRequest(参数:[String:String],完成:@转义OAuthSwift.TokenCompletionHandler)-> OAuthSwiftRequestHandle? {
public func weather(location:String, failure: @escaping (_ error: OAuthSwiftError) -> Void, success: @escaping (_ response: OAuthSwiftResponse) -> Void, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial) {
self.makeRequest(parameters: ["location":location, "format":responseFormat.rawValue, "u":unit.rawValue], **completion**: )
}
/// Performs the API request with the OAuthSwift client
///
/// - Parameters:
/// - parameters: Any URL parameters to pass to the endpoint.
/// - failure: failure callback
/// - success: success callback
private func makeRequest(parameters:[String:String], completion: @escaping OAuthSwift.TokenCompletionHandler) -> OAuthSwiftRequestHandle? {
let completionHandler: OAuthSwiftHTTPRequest.CompletionHandler = { [weak self] result in
guard let this = self else {
return
}
switch result {
case .success(let response):
let responseJSON: Any? = try? response.jsonObject(options: .mutableContainers)
let responseParameters: OAuthSwift.Parameters
if let jsonDico = responseJSON as? [String: Any] {
responseParameters = jsonDico
} else {
}
guard let accessToken = responseParameters["access_token"] as? String else {
let message = NSLocalizedString("Could not get Access Token", comment: "Due to an error in the OAuth2 process, we couldn't get a valid token.")
completion(.failure(.serverError(message: message)))
return
}
if let refreshToken = responseParameters["refresh_token"] as? String {
}
if let expiresIn = responseParameters["expires_in"] as? String, let offset = Double(expiresIn) {
this.client!.credential.oauthTokenExpiresAt = Date(timeInterval: offset, since: Date())
} else if let expiresIn = responseParameters["expires_in"] as? Double {
this.client!.credential.oauthTokenExpiresAt = Date(timeInterval: expiresIn, since: Date())
}
completion(.success((this.client!.credential, response, responseParameters)))
case .failure(let error):
completion(.failure(error))
}
}
}
如何在此处管理完成电话:???
self.makeRequest(parameters: ["location":location, "format":responseFormat.rawValue, "u":unit.rawValue], **completion**: )
self.client.request(accessTokenUrl, method: .POST, parameters: parameters, headers: finalHeaders, checkTokenExpiration: false, completionHandler: completionHandler)
客户请求的实际参数为
func request(_ url: URLConvertible, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, body: Data? = nil, checkTokenExpiration: Bool = true, completionHandler completion: OAuthSwiftHTTPRequest.CompletionHandler?) -> OAuthSwiftRequestHandle?
使用完成处理程序代替成功失败
希望它能解决您的问题
检查此代码...您需要发送转义的完成处理程序,而不是分别发送成功或失败
fileprivate func requestOAuthAccessToken(withParameters parameters: OAuthSwift.Parameters, headers: OAuthSwift.Headers? = nil, completionHandler completion: @escaping TokenCompletionHandler) -> OAuthSwiftRequestHandle? {
let completionHandler: OAuthSwiftHTTPRequest.CompletionHandler = { [weak self] result in
guard let this = self else {
OAuthSwift.retainError(completion)
return
}
switch result {
case .success(let response):
let responseJSON: Any? = try? response.jsonObject(options: .mutableContainers)
let responseParameters: OAuthSwift.Parameters
if let jsonDico = responseJSON as? [String: Any] {
responseParameters = jsonDico
} else {
responseParameters = response.string?.parametersFromQueryString ?? [:]
}
guard let accessToken = responseParameters["access_token"] as? String else {
let message = NSLocalizedString("Could not get Access Token", comment: "Due to an error in the OAuth2 process, we couldn't get a valid token.")
completion(.failure(.serverError(message: message)))
return
}
if let refreshToken = responseParameters["refresh_token"] as? String {
this.client.credential.oauthRefreshToken = refreshToken.safeStringByRemovingPercentEncoding
}
if let expiresIn = responseParameters["expires_in"] as? String, let offset = Double(expiresIn) {
this.client.credential.oauthTokenExpiresAt = Date(timeInterval: offset, since: Date())
} else if let expiresIn = responseParameters["expires_in"] as? Double {
this.client.credential.oauthTokenExpiresAt = Date(timeInterval: expiresIn, since: Date())
}
this.client.credential.oauthToken = accessToken.safeStringByRemovingPercentEncoding
completion(.success((this.client.credential, response, responseParameters)))
case .failure(let error):
completion(.failure(error))
}
}
将方法定义更改为
private func makeRequest(parameters:[String:String], completion: @escaping TokenCompletionHandler) -> OAuthSwiftRequestHandle?)
此TokenCompletionHandler是ResultType...。您可以添加失败或成功案例的开关...让我知道是否需要进一步的帮助