简体   繁体   English

SWIFT:将变量从闭包传递给函数

[英]SWIFT: Passing variable from closure to function

I'm trying to create a function which returns an NSDictionary, which on its turn needs to be returned from a closure. 我正在尝试创建一个返回NSDictionary的函数,而该函数又需要从闭包中返回。

I'm relatively new to Swift and I'm having problems figuring this one out. 我是Swift的新手,在解决这一问题时遇到了问题。 Any help would be greatly appreciated. 任何帮助将不胜感激。

// Takes a String, needs to return a NSDictionary

func login(action: String) -> NSDictionary 
{
    let command = NSURL(string: "\(connectionType)://\(url)/includes/api.php?username=\(username)&password=\(password)&accesskey=\(apiKey)&action=\(action)&responsetype=json")
    print(command!)

    let session = NSURLSession.sharedSession()

    // Get error here when changing Void > NSDictionary
    let task = session.dataTaskWithURL(command!) {
        (data, response, error) -> Void in 

        if error != nil {

            print(error!.localizedDescription)

        } else {

            do {
                let result = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSDictionary

                print(result) // Need this returned

            } catch {
                // handle error
                print(error)
            }
        }
    }

    task.resume()

    return result As! NSDictionary // returns empty, because of -> Void??

}

The problem is dataTaskWithURL is an asynchronous function, therefore it hasnt got around to executing the block yet before it returns the function. 问题在于dataTaskWithURL是一个异步函数,因此在返回该函数之前还没有执行该块。

what you need to do is either setup a function that can be called on self that will let self know when the block has executed and can pass you the result, or setup a protocol with a delegate that you can call to notify of the result 您需要做的是设置一个可以在self上调用的函数,该函数将在模块执行后告知self并可以将结果传递给您,或者设置一个带有委托的协议,您可以调用该协议以通知结果

also, the -> Void inside the block is the return type of the block, you shouldnt really be returning anything inside that block anyway because nothing will actually happen with it since the parent function doesnt expect anything to be returned, hence why its Void 同样, -> Void在块内是块的返回类型,您实际上不应该在该块内返回任何东西,因为父函数不希望返回任何东西,因此实际上不会发生任何事情,因此为什么要返回Void

In your declaration of the closure's type 在您声明闭包的类型时

let task = session.dataTaskWithURL(command!) {
    (data, response, error) -> Void in
    /* closure body */
}

change the Void to JSONObject . Void更改为JSONObject But that's not all! 但这还不是全部! You're trying to return something from a login function that makes an asynchronous call, and that's impossible. 您试图从登录函数返回一些信息,这些信息会进行异步调用,而这是不可能的。 Instead, your login function itself needs to take a closure, and that closure will be where you do something with the result NSDictionary . 取而代之的是,您的login函数本身需要使用闭包,而闭包将是您对结果NSDictionary So change your declaration of login to 因此,将您的login声明更改为

func login(action: String, completionHandler: (NSDictionary) -> ())

and implement the completionHandler accordingly. 并相应地实现completionHandler

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM