ios - swift 中的雅虎天气 API oauth 请求中的额外参数

标签 ios swift arguments yahoo weather

我正在尝试将 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 函数中收到编译器错误“额外参数“失败”(参见附件)。

  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**)
    }

[编译器错误][1]

有人有 Oauth 和此类问题的经验吗?有人可以帮助我吗?

提前非常感谢

这就是 Yahooweather Oauth 请求的调用方式(感谢 jamadAli):

  public func weather(lat:String, lon:String, responseFormat:YahooWeatherAPIResponseType = .json, unit:YahooWeatherAPIUnitType = .imperial,completion: OAuthSwiftHTTPRequest.CompletionHandler?) {

         self.makeRequest(parameters: ["lat":lat, "lon":lon, "format":responseFormat.rawValue, "u":unit.rawValue], completion: completion)
    }

    private func makeRequest(parameters:[String:String], completion: OAuthSwiftHTTPRequest.CompletionHandler?) {

        self.oauth?.client.request(self.url, method: .GET, parameters: parameters, headers: self.headers, body: nil, checkTokenExpiration: true, completionHandler: completion)}

最佳答案

enter image description here使用OAuth2Swift函数

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?

它采用 Completion 处理程序而不是 success Failure

希望能解决您的问题

查看此代码...您需要发送转义完成处理程序,而不是单独发送成功或失败

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 ....您可以添加失败或成功案例的开关...如果您需要进一步帮助,请告诉我

关于ios - swift 中的雅虎天气 API oauth 请求中的额外参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59767456/

相关文章:

ios - 无法设置绑定(bind)(到 : UITableView) with RxSwift Variable asObservable()

linux - shell函数和参数传递问题

c - 向 Rsync 中的选项添加参数

iphone - 如何在防火墙后面的 iPhone 上设置 http 服务器

iphone - 本地通知没有显示,只有声音/振动

swift - Alamofire Swift 3 仅上传数组中的最后一张图片

ios - 在 UITableViewController 上设置背景

ios - Swift 4 - 带选项卡栏和导航 Controller 的 3D Touch 快速操作

ios - Unwind segue 从 View 中删除原始 VC,为什么?

Python将字典传递给多处理中的进程