【问题标题】:iOS Swift 3 CompletionHandler not workingiOS Swift 3 CompletionHandler 不起作用
【发布时间】:2017-08-14 15:08:29
【问题描述】:

我正在尝试在 Swift 中编写完成处理函数,这是我在 Swift 中的代码,其中包含一个名为 NBObject 的类

typealias CompletionHandler = (_ success: Bool, _ data: [String:Any]) -> Void

// FIND OBJECTS IN BACKGROUND
func findObjectInBackground(completionHandler: CompletionHandler) {
    let tbNameStr = "table=" + theTableName
    var rStr = ""
    var theData = [String:Any]()

    for i in 0..<columns.count {
        rStr += "&c" + "\(i)" + "=" + columns[i] +
            "&r" + "\(i)" + "=" + records[i]
    }
    recordString = tbNameStr + rStr
    print("RECORD STRING: \(recordString)")

    let requestURL = URL(string: PATH_TO_API_FOLDER + "queryWhereKeyContains.php?" + recordString)

    //create the session object
    let session = URLSession.shared

    //now create the URLRequest object using the url object
    let request = URLRequest(url: requestURL!)

    //create dataTask using the session object to send data to the server
    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

        //exiting if there is some error
        if error != nil {
            print("Error is: \(error!.localizedDescription)")
            return
        } else {

        }

        do {
            if let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any] {
                theData = json
                print("JSON: \(json)")
            }
        } catch let error { print("ERROR IN PARSING JSON: \(error.localizedDescription)") }

    })

    task.resume()


    let flag = true
    completionHandler(flag, theData)
}

我在 ViewController.swift 中调用该函数,如下所示:

let query = NJObject(tableName: HOTEL_TABLE_NAME)
query.whereKeyContains(columnName: HOTEL_NAME, record: "Hotel")
query.findObjectInBackground { (succ, objects) in
    print("OBJECTS: \(objects)")
    print("SUCCESS: \(succ)")
}

因此,在 Xcode 控制台中,我正确获取了 JSON 数据,但在打印完成处理程序时,data(打印为 OBJECTS)为空。

OBJECTS: [:]
SUCCESS: true
JSON: ["objects": <__NSArrayM 0x17004b4c0>(
{
    address = "<null>";
    createdAt = "2017-08-12 23:08:48";
    description = "lorem ipsec dolor sit";
    email = "<null>";
},
{
    address = "<null>";
    createdAt = "2017-08-14 06:19:10";
    description = "lorem ipsec dolor sit";
    email = "<null>";
})
]

我注意到的一件事是控制台首先将 OBJECTS 打印为空 [:] 和 SUCCESS 日志,然后是 JSON 数据。

所以我确定我的 findObjectInBackground() 函数有问题,我就是不知道问题出在哪里。

【问题讨论】:

  • “它不能正确打印对象”是什么意思?如果您的意思是 NSArray 部分,那是因为您的 Dictionary 类型是 [String:Any] 并且当您解析 JSON 对象时,您不会将其向下转换为任何显式类型。
  • 是的,我的意思是 OBJECTS: [:] 部分,那么我应该在 ViewController.swift 中调用的函数中做什么?
  • 所以问题不在于打印,而在于完成处理程序为空。看看我的回答。

标签: json swift3 completionhandler


【解决方案1】:

您必须将完成处理程序放入数据任务的完成处理程序

你可以省略URLRequest的创建,GET是默认的,只是传递URL:

let task = session.dataTask(with: requestURL!, completionHandler: { data, response, error in

    //exiting if there is some error
    if error != nil {
        print("Error is: \(error!.localizedDescription)")
        completionHandler(false, [:])
        return
    } 

    do {
        if let json = try JSONSerialization.jsonObject(with: data!) as? [String: Any] {
            print("JSON: \(json)")
            completionHandler(true, json) // the variable `theData` is not needed.
        }
    } catch let error { print("ERROR IN PARSING JSON: \(error.localizedDescription)") }
      completionHandler(false, [:])
})

task.resume()

并且不要传递.mutableContainers,它在 Swift 中没有意义

旁注:在 Swift 3 中,这个闭包声明就足够了:

typealias CompletionHandler = (Bool, [String:Any]) -> Void

【讨论】:

    【解决方案2】:

    问题是您在网络请求的完成处理程序之外调用完成处理程序,因此您的函数的完成处理程序在异步网络请求返回之前返回。您需要将其移动到请求的完成处理程序中。

    do {
        if let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any] {
            theData = json
            print("JSON: \(json)")
            completionHandler(true, theData)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 2017-03-22
      相关资源
      最近更新 更多