【问题标题】:(Swift) String if not convertible to void [closed](Swift)字符串,如果不能转换为 void [关闭]
【发布时间】:2015-07-28 11:52:49
【问题描述】:

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

但如果我喜欢那里,函数会返回一个空结果

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

这有什么问题?

【问题讨论】:

  • 以纯文本形式发布您的代码。

标签: swift http get request


【解决方案1】:

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

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

这意味着 completionHandler 闭包不必返回任何东西。所以说你String不能转换成Void是正常的。

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

如果您希望此代码按照我的预期运行,您需要更改 httpGet: 以便也能够传递一个completionHandler,该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
}

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

【讨论】:

  • 谢谢,我应该如何使用它?我正在尝试使用 response = httpGet(url) 等语法简化 http-request-calling
  • 你不能真正做到这一点。我将通过编辑我的 anwser 来向您展示如何使用它,请稍等。
  • 我明白了。最后一个问题:我在 ViewController.swift 的顶部声明了一个 var res:String=""。然后是 httpGet-func 然后 - viewDidload 操作,其中 Im using it httpGet2("http://my1test.ru/applejesus.php?task=getCategoryCount") { result in self.res = result } So then Im 使用 println(res) 和 its empty. But if I print result - I see the answer I need ("12"). Whats 我做错了吗?
  • @SwiftStudier 你真的应该了解更多关于异步如何工作的信息,如果你从未使用过它可能会很难理解。你做对了。如果您需要 viewDidLoad 中的值,只需将代码放入闭包中。如果您以后需要它,您可以像以前一样存储它,但它只有在异步调用结束时才可用。
【解决方案2】:

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

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

你正在使用异步请求,所以你需要做一个回调函数。

如果你熟悉 javascript,我认为this 是关于异步工作原理的一个很好的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2018-05-02
    • 2016-07-06
    • 1970-01-01
    • 2014-11-15
    相关资源
    最近更新 更多