使用循环从 plist 的根级别获取字典数组并将其放入变量中

Posted

技术标签:

【中文标题】使用循环从 plist 的根级别获取字典数组并将其放入变量中【英文标题】:Using loops to get and put an array of dictionaries from the Root level of a plist into a variable 【发布时间】:2019-11-08 15:50:40 【问题描述】:

(发布后编辑标题是字典数组,不是字典字典)

我在 Root 词典中有很多词典的 .plist。所有字典都有相同的键(“image”和“text”)。

如何从 .plist 中获取键和值以放入一个变量,如字典字典(包含更多项目,例如多达 100 个图像和文本),如下所示?

var imageTextDict = [["image":"1-image", "text":"Text for 1"], ["image":"2-image", "text":"Text for 2"] , ["image":"3-image", "text":"Text for 3"], ["image":"4-image", "text":"Text for 4"]]

我发现的大多数代码要么很旧,要么没有回答我的问题...我能得到的最接近的方法是打印 Root 字典中特定字典的键和值,而不是 Root 中的完整列表.

在 .plist (Key)Root、(Type)Dictionary、(Value)eg 中。 100 件商品(我的声望低于 10,所以无法上传图片)。

.plist 作为源代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>1</key>
        <dict>
            <key>image</key>
            <string>1-image</string>
            <key>text</key>
            <string>Text for 1</string>
        </dict>
        <key>2</key>
        <dict>
            <key>image</key>
            <string>2-image</string>
            <key>text</key>
            <string>Text for 2</string>
        </dict>
        <key>3</key>
        <dict>
            <key>image</key>
            <string>3-image</string>
            <key>text</key>
            <string>Text for 3</string>
        </dict>
        .
        .
        .
    </dict>
</plist>

下面的代码基于a tutorial on YouTube,这是我能找到的最新最简单的代码,但不是我想要的......

在 Combo.plist 文件中

struct dict: Decodable 
    let image: String
    let text: String


struct Config: Decodable 
    let dict: dict


struct ConfigValues 
    static func get() -> Config 
        guard let url = Bundle.main.url(forResource: "Combo", withExtension: "plist") else 
            fatalError("Could not find Combo.plist in your Bundle")
        
        do 
            let data = try Data(contentsOf: url)
            let decoder = PropertyListDecoder()
            return try decoder.decode(Config.self, from: data)
         catch let err 
            fatalError(err.localizedDescription)
        
    

在 ViewController.swift 文件中 我尝试打印不同的东西,但无法从根目录打印整个字典数组。

override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        print("Print \(ConfigValues.get().dict)")
        print("Print \(ConfigValues.get().dict.image)")
        print("Print \(ConfigValues.get().dict.text)")
        print("Print \(ConfigValues.get().self)")
        //using a closed range operator ... to create a range that goes from 1 to 100
        for i in 1...100
            print(i)
        
    

赞赏任何方向。我应该使用数字 1,2,3... 作为字典中的键吗?如何获取代码中根字典项的总数以使用循环或映射进行迭代?谢谢。

【问题讨论】:

如果你真的拥有所有的数字,那么在顶层(根级别)使用数组怎么样? 在看到有人在类似情况下使用数组后,我从使用根级别的数组更改为字典。是 var imageTextDict = [["image":"1-image", "text":"Text for 1"], ["image":"2-image", "text":"Text for 2"], [ "image":"3-image", "text":"Text for 3"], ["image":"4-image", "text":"Text for 4"]] 表示一个或多个字典中的字典在一个数组中?谢谢。 你给的代码是一个字典数组 我只是按照建议将 Root 更改为数组。从xml来看,我猜如果翻译成一个变量, var imageTextDict = [["image":"1-image", "text":"Text for 1"], ["image":"2-image", "text":"Text for 2"], ["image":"3-image", "text":"Text for 3"]] 表示数组中的字典(不是字典中的字典)? 非常感谢。这是一个开始。 【参考方案1】:

按照 cmets 的建议,将根对象更改为字典数组

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>image</key>
        <string>1-image</string>
        <key>text</key>
        <string>Text for 1</string>
    </dict>
    <dict>
        <key>image</key>
        <string>2-image</string>
        <key>text</key>
        <string>Text for 2</string>
    </dict>
    <dict>
        <key>image</key>
        <string>3-image</string>
        <key>text</key>
        <string>Text for 3</string>
    </dict>
       .
       .
       .
</array>
</plist>

删除Config,只使用一个结构体

struct Combo : Decodable 
    let image: String
    let text: String



struct ConfigValues 
    static func get() throws -> Config 
        guard let url = Bundle.main.url(forResource: "Combo", withExtension: "plist") else 
            fatalError("Could not find Combo.plist in your Bundle")
        

        let data = try Data(contentsOf: url)
        return try PropertyListDecoder().decode([Combo].self, from: data)
    

并迭代结果

override func viewDidLoad() 
    super.viewDidLoad()
    do 
       let combos = ConfigValues.get()
       for combo in combos 
           print(combo.image, combo.text)
       
     catch  print(error) 
 

【讨论】:

以上是关于使用循环从 plist 的根级别获取字典数组并将其放入变量中的主要内容,如果未能解决你的问题,请参考以下文章

从 plist 中获取数组中的字典对象的问题

想要从 iPhone 的 plist 中的字典数组中获取数据? [复制]

如何从返回的 plist 数组中获取字符串

Info.plist 字典到 Enum:String 类型的字典

如何将图像从 plist 加载到 UITableView?

使用 Xcode 读取和写入具有字典数组的 Plist