如何在Swift中循环遍历JSON对象?

时间:2018-10-05 20:53:06

标签: ios json swift

我是Swift的新手,我无法弄清楚。我正在创建一个简单的测验应用程序,其中的问题来自一个json文件。我能够成功解析此数据,但无法弄清楚如何循环遍历json文件以显示每个问题。当前,仅显示第一个问题,当选择答案时,它将答案显示为正确/不正确,没有其他显示。我希望在用户回答问题后从json文件中填充下一个问题,但是我不知道该怎么做。这是我到目前为止的代码。

private func parseJSON() {
    guard let path = Bundle.main.path(forResource: "quizQuestions", ofType: "txt") else { return }
    let url = URL(fileURLWithPath: path)

    do {
        let data = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

        guard let array = json as? [Any] else { return }

        for item in array {
            guard let quizObjects = item as? [String: Any] else { return }
            guard let questionNumber = quizObjects["id"] as? Int else { print("not an Int"); return }
            guard let question = quizObjects["question"] as? String else { return }
            guard let answerChoices = quizObjects["answerChoices"] as? [String] else { return }
            guard let correctAnswer = quizObjects["correctAnswer"] as? Int else { return }
        }
    }
    catch {
        print(error)
    }
}

我包含了loadNextQuestion函数,供您查看我要执行的操作。以前,我将所有问题都硬编码在一个swift对象中,因此这可行,但是现在我试图从json文件中提取。我正在努力解决的主要问题是如何确定当前的问题和位置,以使这种逻辑起作用。

func loadNextQuestion() {
    // Show next question
    if(currentQuestionPos + 1 < currentQuestion.count) {
        currentQuestionPos += 1
        currentQuestion = question
        setQuestion()

    }
    // If there are no more questions show the results
    else {

    }
}

这是我从中提取的json文件:

[
{
"id": 1,
"question": "What color is the sky?",
"answerChoices": ["Green", "White", "Blue", "Brown"],
"correctAnswer": 2
},

{
"id": 2,
"question": "What color is the grass?",
"answerChoices": ["Pink", "Green", "Purple", "Orange"],
"correctAnswer": 0
},

{
"id": 3,
"question": "Which of these has 8 legs?",
"answerChoices": ["Spider", "Lizard", "Cricket", "Snake"],
"correctAnswer": 0
},
]

2 个答案:

答案 0 :(得分:0)

首先,我将使用依赖项SwiftyJSON来管理您的JSON文件,因此遍历您的问题库要容易得多。

解决此问题的一种方法是定义一个全局变量以跟踪您的问题状态。像这样:

var questionNum : Int = 0

当用户单击以回答问题时,将1加到变量中。并使用它遍历您的JSON列表。将您的列表与UI变量相关联,以便每次用户回答问题时该列表都会更改。

func moveToNextQuestion(){
  questionNum += 1
  questionLabel.text = question[questionNum]
}

将moveToNextQuestion函数放置在按钮操作中。

答案 1 :(得分:0)

要处理json文件,swift具有 Codable 协议。请参阅下面的代码,我是如何将json创建到对象数组的,以便您可以使用索引逐一显示测验视图。 游戏代码:

typealias Model = [ModelElement]
struct ModelElement : Codable {
    let id : Int?
    let question : String?
    let answerChoices : [String]?
    let correctAnswer : Int?

    enum CodingKeys: String, CodingKey {

        case id = "id"
        case question = "question"
        case answerChoices = "answerChoices"
        case correctAnswer = "correctAnswer"
    }
}

var json = """
[
{
"id": 1,
"question": "What color is the sky?",
"answerChoices": ["Green", "White", "Blue", "Brown"],
"correctAnswer": 2
},

{
"id": 2,
"question": "What color is the grass?",
"answerChoices": ["Pink", "Green", "Purple", "Orange"],
"correctAnswer": 0
},

{
"id": 3,
"question": "Which of these has 8 legs?",
"answerChoices": ["Spider", "Lizard", "Cricket", "Snake"],
"correctAnswer": 0
}
]
""".data(using: .utf8)

let jsonDecoder = JSONDecoder()
let responseModels = try jsonDecoder.decode(Model.self, from: json!)

for item in responseModels {
    print(item.id)
}