Swift 从硬代码转换为从plist读取

Swift 从硬代码转换为从plist读取,swift,xcode,Swift,Xcode,对于xcode来说非常陌生,我正在研究如何构建一个测验应用程序,我发现了一个youtube视频可供参考,但唯一的问题是他硬编码了问题和答案。我想问,如何将QuestionBank类的这一部分更改为从plist或json文件读取?供参考的视频: 问题库类 class QuestionBank{ var list = [Question]() init() { list.append(Question(image: "flag1", questionText: "T

对于xcode来说非常陌生,我正在研究如何构建一个测验应用程序,我发现了一个youtube视频可供参考,但唯一的问题是他硬编码了问题和答案。我想问,如何将QuestionBank类的这一部分更改为从plist或json文件读取?供参考的视频:

问题库类

class QuestionBank{
    var list = [Question]()

    init() {
        list.append(Question(image: "flag1", questionText: "This British overseas territory is a popular tax haven.", choiceA: "A. Haiti", choiceB: "B. Suriname", choiceC: "C. Puerto Rico", choiceD: "D. Anguilla", answer: 4))

        list.append(Question(image: "flag2", questionText: "The highest point on this island, Mount Obama was renamed in 2009 in honor of the president.", choiceA: "A. Dominica", choiceB: "B. Bahamas", choiceC: "C. Antigua and Barbuda", choiceD: "British Virgin Islands", answer: 3))

        list.append(Question(image: "flag3", questionText: "This country produces its water from a desalination plant and the electricity on the island is a by-product of the desalination process.", choiceA: "A. Cuba", choiceB: "B. Aruba", choiceC: "C. Gaudeloupe", choiceD: "D. Cayman Islands", answer: 2))

        list.append(Question(image: "flag4", questionText: "This country has a magnificent underwater cave system.", choiceA: "A. The Bahamas", choiceB: "B. Venezuela", choiceC: "C. Matinique", choiceD: "D. Dominican Republic", answer: 1))

        list.append(Question(image: "flag5" , questionText: "This is the island of Cou-Cou and Flying Fish. The popular R&B singer Rihanna is from here.", choiceA: "A. Trinidad and Tobago" , choiceB: "B. Saint Kitts and Nevis" , choiceC: "C. Grenada" , choiceD: "D. Barbados", answer: 4))

        list.append(Question(image: "flag15" , questionText: "Rum is the national drink of this country. The fastest man in the world Usain Bolt is from here.", choiceA: "A. Jamaica" , choiceB: "B. Saint Vincent and the Grenadines" , choiceC: "C. St. Lucia" , choiceD: "D. Guyana", answer: 1))
    }
}
课堂提问:

class Question {
    let questionImage: String
    let question: String
    let optionA: String
    let optionB: String
    let optionC: String
    let optionD: String
    let correctAnswer: Int

    init(image: String, questionText: String, choiceA: String, choiceB: String, choiceC: String, choiceD: String, answer: Int){
        questionImage = image
        question = questionText
        optionA = choiceA
        optionB = choiceB
        optionC = choiceC
        optionD = choiceD
        correctAnswer = answer
    }
}

首先,您可以将
转换为
结构
,并使用协议
可编码
(两个协议的组合,
可编码
可解码
),这允许您将JSON解码为对象或对象数组

CodingKeys
允许您匹配不符合所需格式或名称的键

结构问题:可编码{ //可选的 私有枚举编码键:字符串,编码键{ case questionImage=“q_image”//示例 个案年龄,单身 } 让问题图像:字符串 让我们提问:字符串 让我们选择A:字符串 让选项B:字符串 让选项C:字符串 让我们选择:字符串 让我们回答:Int } 现在您应该解析数据了,我认为您的plist只有一个与上面声明的对象对应的问题数组,如果不创建不同的对象并匹配键的话

guard let plistPath=Bundle.main.path(forResource:“YourPlistName”,类型为:“plist”),
设plistURL=URL(字符串:plistPath),
让数据=尝试?数据(内容:plistURL)其他{
法塔莱罗(“做点什么!”)
}
让问题=尝试!PropertyListDecoder().decode([Question].self,发件人:数据)

希望这对任何人都有用。

首先,使用Xcode中的内置属性列表编辑器创建属性列表文件。它将如下所示(仅显示前两个问题):

现在将属性列表文件拖到应用程序包中,并确保它是应用程序目标的一部分

现在,当应用程序启动时,读取属性列表文件非常简单。例如:

struct QuestionBank : Codable {
    let list : [Question]
}
struct Question : Codable {
    let image: String
    let questionText: String
    let choiceA: String
    let choiceB: String
    let choiceC: String
    let choiceD: String
    let answer: Int
}
class ViewController: UIViewController {
    var questionBank : QuestionBank?
    override func viewDidLoad() {
        super.viewDidLoad()
        let url = Bundle.main.url(forResource: "questions", withExtension: "plist")
        let data = try! Data(contentsOf: url!)
        self.questionBank = try! PropertyListDecoder().decode(QuestionBank.self, from: data)
    }
}

(请注意,结构属性的名称和plist文件中键的名称之间需要匹配,我已经为此调整了名称。另一种解决方案是使用CodingKeys重新映射名称,但这样做似乎没有什么意义,因为您可以控制名称。)

看一些关于使用Swift和可编码协议解码JSON的优秀教程。