如何使用init()解析JSON

时间:2019-05-21 07:27:14

标签: ios json swift

我无法使用其对象显示json Array

显示此错误:

  

“线程1:致命错误:展开包装时意外发现nil   可选值”

class sample{

    var jarray:[[String:Any]]!

    init(url: String) {


        let urll = URL(string: url)
        var request              = URLRequest(url: urll!)
        request.httpMethod        = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        let task                 = URLSession.shared.dataTask(with: request, completionHandler: {(Data,response,Error) in
            do
            {
                let jsonresponse = try  JSONSerialization.jsonObject(with: Data!, options: [])
                let jsonarray    = jsonresponse as? [[String:Any]]
                self.jarray       = jsonarray!
                print(self.jarray)
                DispatchQueue.main.async {

                }

            }
            catch let parsingerror
            {
                print("error",parsingerror)
            }
        })
        task.resume()
    }

}

3 个答案:

答案 0 :(得分:1)

首先:始终处理错误并安全包装可选项。

所有DataError(大写)中的第二个都是保留字,请在闭包中始终使用小写的参数标签(以及大写的类名)。

代码中的许多行都是多余的。

class Sample {

    var jarray  = [[String:Any]]()

    init(url: String) {
        guard let urll = URL(string: url) else { return }

        let task = URLSession.shared.dataTask(with: urll) { data, _ , error in
            if let error = error { print(error); return }
            do
            {
                // if error is nil then data is guaranteed to be non-nil
                if let jsonarray = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
                    self.jarray = jsonarray
                    print(self.jarray)
                    DispatchQueue.main.async {

                    }
                }
            }
            catch {
                print("error", error)
            }
        }
        task.resume()
    }
}

注意:在init方法中运行异步任务是不明智的做法

答案 1 :(得分:0)

避免不必要地使用force unwrapping 。我可能会导致您的应用程序意外崩溃。在您的代码中,

检查Data是否为nil。如果是这样,则以下行将导致运行时异常。

let jsonresponse = try  JSONSerialization.jsonObject(with: Data!, options: [])

在下面的代码行中,检查jsonarray是否为nil。

self.jarray = jsonarray!

否则,请添加您的应用崩溃所在的行。

尝试将代码替换为:

class sample {
    var jarray: [[String:Any]]?

    init(url: String) {
        if let urll = URL(string: url) {
            URLSession.shared.dataTask(with: urll) { (data, response, error) in
                do {
                    if let data = data {
                        let jsonresponse = try JSONSerialization.jsonObject(with: data, options: [])
                        self.jarray = jsonresponse as? [[String:Any]]
                        print(self.jarray)
                        DispatchQueue.main.async {
                        }
                    }
                } catch {
                    print("error",error)
                }
            }.resume()
        }
    }
}

另外,不要像使用reserved wordsData那样使用Error作为变量名。

最重要的是-切勿在服务器响应中使用forced unwrapping (!)。 API响应可能并非总是如预期的那样。尝试处理该问题。

答案 2 :(得分:0)

JSONSerialization现在是老式的方式。 Apple引入了Codable协议,可为您处理对象的序列化和反序列化。

Example

struct Photo: Codable
{
    //String, URL, Bool and Date conform to Codable.
    var title: String
    var url: URL
    var isSample: Bool

    //The Dictionary is of type [String:String] and String already conforms to Codable.
    var metaData: [String:String]

    //PhotoType and Size are also Codable types
    var type: PhotoType
    var size: Size
}

在服务器的响应中:

if let jsonData = jsonString.data(using: .utf8)
{
    let photoObject = try? JSONDecoder().decode(Photo.self, from: jsonData)
}