如何在swift 4中将JSON文件转换为字典?

如何在swift 4中将JSON文件转换为字典?,swift,Swift,我将此JSON保存在文件列表\u catalog.JSON中: [ { "idcatalog": 1, "imgbase64": "", "urlImg": "http://172.../page01.jpg", "urlPages": "http://172.../catalog_1_pages.json", "dt_from": "", "dt_to": "" }, { "idcatalog": 2, "imgbase64": "", "urlImg

我将此JSON保存在文件列表\u catalog.JSON中:

[
 {
  "idcatalog": 1,
  "imgbase64": "",
  "urlImg": "http://172.../page01.jpg",
  "urlPages": "http://172.../catalog_1_pages.json",
  "dt_from": "",
  "dt_to": ""
 },
 {
  "idcatalog": 2,
  "imgbase64": "",
  "urlImg": "http://172.../1.jpg",
  "urlPages": "http://172.../2_pages.json",
  "category": [
   {
    "id": 1,
    "lib": "lib"
   }
  ],
  "dt_to": ""
 }
]
我可以通过以下方式获取此文件:

if let url = URL(string: "http://172.../list_catalogs.json") {
        do {
            let contents = try String(contentsOf: url)
            print(contents)

        } catch {
            // contents could not be loaded
        }
    }
但我无法在字典中转换这个字符串。 对于将数据转换为字符串,我使用以下函数:

func convertToDictionary(text: String) -> [String: Any]? {
    if let data = text.data(using: .utf8) {
        do {
            return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        } catch {
            print(error.localizedDescription)
        }
    }
    return nil
}
但在这种情况下,它不起作用
有人能帮我吗?

您的代码的问题是,您正试图将数组转换为字典,正如一些人在撰写本文时在Vadian,Moritz的评论中正确指出的那样

所以,显而易见的第一步解决方案是将[String:Any]转换为[[String:Any]]一组字典,而不是转换为[String:Any]],但这仍然会给您留下任何部分的问题。要使用此词典,您需要知道/记住键及其类型,并在使用时转换每个值

最好使用Codable协议,它与解码器一起允许您基本上将JSON映射到相关的代码结构

下面是一个示例,说明如何使用在Swift平台上完成的Swift 4可编码协议解析此JSON

let jsonData = """
[{
    "idcatalog": 1,
    "imgbase64": "",
    "urlImg": "http://172.../page01.jpg",
    "urlPages": "http://172.../catalog_1_pages.json",
    "dt_from": "",
    "dt_to": ""
}, {
    "idcatalog": 2,
    "imgbase64": "",
    "urlImg": "http://172.../1.jpg",
    "urlPages": "http://172.../2_pages.json",
    "category": [{
        "id": 1,
        "lib": "lib"
    }],
"dt_to": ""
}]
""".data(using: .utf8)!

struct CatalogItem: Codable {
    let idCatalog: Int
    let imgBase64: String?
    let urlImg: URL
    let urlPages: URL
    let dtFrom: String?
    let dtTo: String?
    let category: [Category]?

    enum CodingKeys: String, CodingKey {
        case idCatalog = "idcatalog"
        case imgBase64 = "imgbase64"
        case urlImg, urlPages, category
        case dtFrom = "dt_from"
        case dtTo = "dt_to"
    }
}

struct Category: Codable {
    let id: Int
    let lib: String?

    enum CodingKeys: String, CodingKey {
        case id, lib
    }
}

do {
    let decoder = JSONDecoder()
    let result = try decoder.decode([CatalogItem].self, from: jsonData)
    print(result)
} catch {
    print(error)
}
控制台输出:

[u lldb_expr_118.CatalogItemidCatalog:1,imgBase64:Optional,urlImg:,urlPages:,dtFrom:Optional,dtTo:Optional,category:nil,uuu lldb_expr_118.CatalogItemidCatalog:2,imgBase64:Optional,urlImg:,urlPages:,dtFrom:nil,dtTo:Optional,category:Optional[u lldb_expr_u118.Categoryid:1,lib:optionallilib]]

好的方面来了,现在使用这些数据要容易得多

print(result.first?.urlImg)
输出:

可选的


这适用于您提供的示例JSON,但可能需要根据数据集的其余部分进行更多调整

欢迎来到StackOverflow。请显示错误输出是什么。另外,如果您使用Swift 4,最好使用Codable协议和字典的JSONDecoderInstead,使用Codable将其转换为结构。请看,您无法将其转换为词典,因为它不是词典。这是一个数组注释[]。将其强制转换为[[String:Any]]。由于Swift 3,选项参数是可选的。您可以省略它。请注意,如中所述,此convertToDictionary方法只是一种方便的方法,仅当您必须使用JSON字符串时才能使用。但大多数情况下,您将获得JSON数据,因此根本不需要此方法。这是正确的urlImg:http://172.../page01.jpg,或者您只是在隐藏ip地址?