【问题标题】:Use callback to get JSON value from call to database使用回调从调用数据库中获取 JSON 值
【发布时间】:2017-02-24 03:49:32
【问题描述】:

我正在尝试使用 json 结果填充 UITable。我调用了一个从服务器获取 json 并将结果存储在NSDictionary 中的函数。我希望能够使用这个集合,然后填充一个表。但是我遇到了一个问题,因为对于 func numberOfRowsInSection 我需要集合的计数,并且由于我的 json 结果在 try/catch 内的另一个函数中,我似乎无法返回该值。

这就是我在ViewDidLoad() 中调用的函数:

func getSubjects() -> NSDictionary{

    let myUrl = NSURL(string: "www.mydomain.com/script.php");
    let request = NSMutableURLRequest(url:myUrl as! URL)
    let user_id = UserDetails[0]

    request.httpMethod = "POST";
    let postString = "user_id=\(user_id)";
    request.httpBody = postString.data(using: String.Encoding.utf8);

    let task = URLSession.shared.dataTask(with: request as URLRequest){

        data, response, error in

        if error != nil {
            print("error=\(error)")
            return
        }

        var err: NSError?
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

            if let parseJSON = json {

                let resultValue: NSDictionary = parseJSON["subjects"] as! NSDictionary

            }

        } catch let error as NSError {
            err = error
            print(err!);
        }
    }
    task.resume();
}

如果我打印 resultValue 我得到了我需要的东西,在这个例子中是:

{
1 =     (
    Maths,
    Lecture
);
2 =     (
    Science,
    Lecture
);
3 =     (
    English,
    Seminar
);

}

但令人困惑的是,我该如何返回这个值?在哪里?我将如何在表格中实现它?如果我在解析JSON 时尝试返回resultValue,则会收到unexpected non-void return in void function 的错误,如果我尝试在函数末尾返回值,则会收到unresolved identifier error

我觉得我执行不正确。我已经检查了很多关于此的教程,似乎没有人用POST JSON 填充表,所以我不知道如何返回值或正确的实现方法。任何帮助将不胜感激!

【问题讨论】:

  • 与为什么在 Swift 代码中使用 Objective-C 类型无关?使用 Swift 字典而不是 NSDictionary 等。
  • 注意点,谢谢

标签: json swift uitableview


【解决方案1】:

您遇到的问题是在您尝试返回字典时尚未检索到该字典。从数据库中检索字典后,您可以使用异步回调来获取字典。

func getSubjects(callback: @escaping (NSDictionary)-> Void){

let myUrl = NSURL(string: "www.mydomain.com/script.php");
let request = NSMutableURLRequest(url:myUrl as! URL)
let user_id = UserDetails[0]

request.httpMethod = "POST";
let postString = "user_id=\(user_id)";
request.httpBody = postString.data(using: String.Encoding.utf8);

let task = URLSession.shared.dataTask(with: request as URLRequest){

    data, response, error in

    if error != nil {
        print("error=\(error)")
        return
    }

    var err: NSError?
    do {
        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

        if let parseJSON = json {

            let resultValue: NSDictionary = parseJSON["subjects"] as! NSDictionary

            callback(resultValue)

        }

    } catch let error as NSError {
        err = error
        print(err!);
    }
}
task.resume();
}

然后你会调用这个函数...

getSubjects(callback: {(resultValue)-> Void in 
    print(resultValue)
    //here you could set your tableView data equal to the values in the dictionary that was just received and then call self.tableView.reloadData to update your table view
})

所以也许在你的 UITableViewController 的 viewDidLoad() 函数或 viewDidAppear(_:) 中,根据你的视图的生命周期,你会调用getSubjects(...),如我上面所示,然后当回调被调用时你调用self.tableView.reloadData() 正如我在函数调用中所解释的那样。如果您不确定如何设置 tableview 数据源和委托,那么您可能应该为此打开另一个问题

编辑 为了回应您询问如何使用从服务器检索到的值作为整个班级可用的变量的评论,您可以执行以下操作...

class: ExampleViewController {
    var resultsDictionary: [Int: [String: String]]?

    override func viewDidLoad(){
        getSubjects(callback: {(resultValue)-> Void in 
            resultsDictionary = resultValue
        })
    }

    //Use the actual getSubjects function I have already shown you above
    func getSubjects(){...}


}

【讨论】:

  • 感谢您花时间回答。我有几个疑问:(1)closure use of non escaping parameter may allow it to escape 所以我现在将函数声明为func getSubjects(callback: @escaping (NSDictionary)-> Void){(2)你的函数调用没有编译?除非我做错了什么。在ViewDidLoad() 中,我像你一样调用函数
  • 很抱歉。你是对的,我错过了函数参数之前的@escaping,我也错过了函数调用中的{。我已经编辑了上面的代码,它现在应该可以工作了
  • 嗨,迈克,谢谢。但是,虽然这会消除“错误”,但我实际上无法获得返回值?例如,我想返回字典的计数或填充我的表。我在ViewDidLoad 中运行该函数。我返回resultValue。在tableView number of rows funccellForRowAt 中,我想访问所述字典的计数并填充表格。我怎样才能?我在该函数中运行该函数,我得到Type() has no subscript members
  • 好吧,一旦回调函数被执行,那么您应该将字典中的值设置为您的表格视图的数据(取决于您想要的值),然后调用self.tableView.reloadData()。您最初的问题中有 3 个问题->“我该如何返回这个值?在哪里?我将如何在表格中实现它?”我已经回答了前两个。但是,如果您仍然不确定如何实现表格视图,那么您需要提出另一个问题,因为这是一个不同的主题
  • 要简单地获取字典中的键数,您可以使用resultValue.keys.count
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
相关资源
最近更新 更多