首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Swift中从web调用中获取值

在Swift中从web调用中获取值
EN

Stack Overflow用户
提问于 2018-08-21 08:50:29
回答 3查看 131关注 0票数 0

我正在尝试从Swift中的PHP脚本获取返回值。然而,我似乎一直收到这个错误:

在展开可选值时意外发现nil

下面是这个类:

代码语言:javascript
复制
var value: String!

func run(idNumber: Int) {
    let request = NSMutableURLRequest(url: URL(string: "https://mywebsite.com/file.php")!)
    request.httpMethod = "POST"
    let postString = "a=Hello"
    request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

        if error != nil {
            //answer = error;
        }

        let answerString = String(data: data!, encoding: String.Encoding.utf8)
        self.value = answerString
    }
    task.resume()
}

func getValue() -> String{
    return value
}

调用getValue()函数时出现错误。但是,当我一创建"answerString“就将其打印出来时,它就成功地打印出来了!

这些函数在这里调用:

代码语言:javascript
复制
let access = ApiAccess()
access.run(idNumber: 0)
print(access.getValue())
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-21 09:00:04

发出请求是一个异步任务。调用getValue之前,需要等待闭包回调被调用。

您可以向run方法添加闭包回调。这样,您就可以知道请求何时完成,并且可以打印结果:

代码语言:javascript
复制
var value: String!

func run(idNumber: Int, @escaping callback: () -> Void) {

    let request = NSMutableURLRequest(url: URL(string: "https://mywebsite.com/file.php")!)
    request.httpMethod = "POST"
    let postString = "a=Hello"
    request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

        if error != nil {
            //answer = error;
        }


        let answerString = String(data: data!, encoding: String.Encoding.utf8)
        self.value = answerString
        callback()

    }
    task.resume()

}

func getValue() -> String{
    return value
}

let access = ApiAccess()
access.run(idNumber: 0) {
   print(access.getValue())
}
票数 1
EN

Stack Overflow用户

发布于 2018-08-21 09:01:19

问题是URLSession.shared.dataTask()的回调是异步发生的,所以在设置var value之前,您最终将执行access.getValue()。这意味着value在具有值之前被强制解包,这会导致此错误。

要解决此问题,请考虑使用promises、RxSwift或类似的异步工具,以便仅在可用时访问值。

票数 1
EN

Stack Overflow用户

发布于 2018-08-21 09:10:25

重构您的run(idNumber:)函数以获取完成处理程序:

代码语言:javascript
复制
func run(idNumber: Int, completion: (String?, Error?)-> Void ) {
    let request = NSMutableURLRequest(url: URL(string: "https://mywebsite.com/file.php")!)
    request.httpMethod = "POST"
    let postString = "a=Hello"
    request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

        if error != nil {
           completion(nil, error)
        }
        let answerString = String(data: data!, encoding: String.Encoding.utf8)
        self.value = answerString
        completion(answerString, nil)
    }
    task.resume()
}

然后这样叫它:

代码语言:javascript
复制
let access = ApiAccess()
access.run(idNumber: 0) { result, error in
    guard let result = result else {
      print("No result. Error = \(error)")
      return
    }
    print("result = \(result)")
}

(或者使用Futures或Promises,@JohnEllmore在他的回答中提到)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51940202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档