(Swift) String 如果不能转换为 void

(Swift) String if not convertible to void

我正在尝试制作一个 http-get-request 函数,但它现在仍然有效。 http://i.stack.imgur.com/8hge2.png

但是如果我喜欢那里,函数 returns 一个空结果

http://i.stack.imgur.com/CTCt4.png

这有什么问题吗?

首先你用的是闭包,看看这个的意思:

 {()->void in 
   return // the closure returns a void
 }

您正在使用异步请求,因此您需要做一个回调函数。

如果您熟悉 javascript,我认为 this 很好地解释了异步的工作原理。

您调用的函数具有以下原型:

func dataTaskWithRequest(
    _ request: NSURLRequest, 
    completionHandler completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void
) -> NSURLSessionDataTask?

这意味着 completionHandler 闭包不必 return 某些东西。所以这很正常,它说你 String 不能转换为 Void。

您期望的是调用一个同步方法,期望它在内部异步调用完成时 return。这是可能的,但我不认为这是你想要的方式(它可能会阻止 UI)。

如果您希望此代码 运行 正如我认为您希望它起作用,您需要更改 httpGet: 以便能够传递一个 completionHandler ,它将由 dataTaskWithRequest 的 completionHandler 调用.

像这样:

func httpGet(url: String, completion: String -> Void) {
    var googleUrl = NSURL(string: url)
    var request = NSMutableURLRequest(URL: googleUrl!)

    request.HTTPMethod = "GET"
    request.addValue("text/html", forHTTPHeaderField: "Content-Type")

    var session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error in
        if error != nil {
            println(error.localizedDescription)
        }

        completion(NSString(data: data, encoding: NSUTF8StringEncoding) as! String)
    })

    task.resume()
}

请注意此代码根本不安全(强制展开和检查太少)但它总结了您应该如何构建代码。

要在某个地方使用它,您可以按照以下步骤操作:

假设您有一个标签 Outlet。

httpGet("http://someurl.com") { result in
    label.text = result
}

标签的文本属性将在异步调用完成后立即设置。