使用按钮在Swift中调用嵌套函数

时间:2017-11-13 23:44:57

标签: ios swift oauth-2.0

我试图在用户按下按钮时调用retrieveData()。

extension ViewController {

    func doOAuthFitbit2() {

        let oauthswift = OAuth2Swift(
            consumerKey:    "*****",
            consumerSecret: "*****",
            authorizeUrl:   "https://www.fitbit.com/oauth2/authorize",
            accessTokenUrl: "https://api.fitbit.com/oauth2/token",
            responseType:   "code"
        )

        oauthswift.accessTokenBasicAuthentification = true
        oauthswift.authorizeURLHandler = getURLHandler()
        let state = generateState(withLength: 20)

        let _ = oauthswift.authorize(
            withCallbackURL: URL(string: "smart://oauth-callback")!,
            scope: "profile nutrition",
            state: state,
            success: { credential, response, parameters in
                self.retrieveData(oauthswift)
        },
            failure: { error in
                print(error.description)
        }
        )
    }

    func retrieveData(_ oauthswift: OAuth2Swift) {
        print("retrieveData")
        let _ = oauthswift.client.get(
            "https://api.fitbit.com/1/user/-/profile.json",
            parameters: [:],
            success: { response in
                let jsonDict = try? response.jsonObject()
                print(jsonDict as Any)
        },
            failure: { error in
                print(error.description)
        }
        )
    }
}

我在ViewController.swift中有以下内容

@IBAction func btnRetrieveData(_ sender: Any) {
    retrieveData(oauthswift)
}

我收到以下错误:

  

无法转换类型' OAuthSwift的价值?'预期的参数类型   ' OAuth2Swift'

我认为是因为" oauthswift"在doOAuthFitbit2()函数内声明。

我是否需要重构代码以使retrieveData()函数嵌套在doOAuthFitbit2()函数中?我将如何在ViewController.swift中调用它?

1 个答案:

答案 0 :(得分:0)

您的oauthswift属性是doOAuthFitbit2()函数的本地属性,因此您无法通过按钮方法(或任何其他方法)访问它。我建议首先,您可以将其添加为doOAuthFitbit2()更新的全局属性,例如:

var oauthswift: OAuth2Swift!
// ^ declare global variable

func doOAuthFitbit2() {

    oauthswift = OAuth2Swift(
    // ^ reference the global variable and set it up here
        consumerKey:    "*****",
        consumerSecret: "*****",
        authorizeUrl:   "https://www.fitbit.com/oauth2/authorize",
        accessTokenUrl: "https://api.fitbit.com/oauth2/token",
        responseType:   "code"
    )

    oauthswift.accessTokenBasicAuthentification = true
    oauthswift.authorizeURLHandler = getURLHandler()
    let state = generateState(withLength: 20)

    let _ = oauthswift.authorize(
        withCallbackURL: URL(string: "smart://oauth-callback")!,
        scope: "profile nutrition",
        state: state,
        success: { credential, response, parameters in
            self.retrieveData(oauthswift)
    },
        failure: { error in
            print(error.description)
    }
    )
}

然后你可以这样做:

func retrieveData() {
//                ^ you don't need to pass an arg here, since it's globally accessible
    print("retrieveData")
    let _ = oauthswift.client.get(
        "https://api.fitbit.com/1/user/-/profile.json",
        parameters: [:],
        success: { response in
            let jsonDict = try? response.jsonObject()
            print(jsonDict as Any)
    },
        failure: { error in
            print(error.description)
    }
    )
}

也就是说,有更稳定的方法可以实现这一点 - 例如shared instance (singleton)可以在整个应用程序中全局访问,shared delegates/protocolsiOS keychain APIs。我不会进入那些 - 你需要在那里学习和阅读。