Как пройти через объекты JSON в Swift? - PullRequest
0 голосов
/ 05 октября 2018

Я новичок в 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, чтобы вы увидели, что я пытаюсь сделать.Раньше у меня были все вопросы, жестко запрограммированные в быстром объекте, так что это работало, но сейчас я пытаюсь извлечь из файла 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 голосов
/ 06 октября 2018

Для обработки файла 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)
}
0 голосов
/ 06 октября 2018

Перво-наперво, я бы использовал зависимость SwiftyJSON для управления вашим файлом JSON, так что цикл по вашему банку вопросов гораздо проще.

Один из способов решить эту проблему - определитьглобальная переменная для отслеживания состояния вашего вопроса.Что-то вроде:

var questionNum : Int = 0

Когда пользователь нажимает, чтобы ответить на вопрос, добавьте 1 к переменной.И используйте это для перемещения по списку JSON.Соедините ваш список с переменной UI, чтобы он менялся каждый раз, когда пользователь отвечает на вопрос.

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

Поместите функцию moveToNextQuestion в действие вашей кнопки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...