Как получить результат (используемой struct:codable) строки синтаксического анализа в окне выбора

Я попал в API и успешно получил ответ. Я использовал кодировку здесь для синтаксического анализа. 1. Но не смог получить конкретное значение. я бы? 2. Сборщик вызывается первым и не загружается со строками, которые мы проанализировали.

Разбор из кодируемого немного липкий. Как получить внутри него содержимое массива, например, значение id.
кодируемая часть: struct Reasons: Codable{ let Reason_and_whom_meet: обе? }

struct both :Codable{
   let reason_list : [reasonlist]?
   let whom_meet : [nameList]?
}

struct reasonlist :Codable{
  let id: Int?    //This "id" i couldnt access. 
  let reason : String?
  enum CodingKeys: String, CodingKey {

  case reason
  case id
  }
}

struct nameList :Codable{
    let name : String?
    enum CodingKeys: String, CodingKey{
        case name
    }
}

Кодируемая структура, которую я сделал по структуре json, которую я получаю. Должен ли я изменить структуру структуры, которую я использовал.

Если вам нужно значение json, я также могу предоставить, но структура является точной иерархией json.

Часть кода:

do {
    let gotData = try JSONDecoder().decode(Reasons.self, from: data!)
    let persons = gotData.reason_and_whom_meet?.whom_meet

    self.wtmArray.add(persons)
    print(self.wtmArray)

    let reasons = gotData.reason_and_whom_meet?.reason_list
    self.reasonArray.add(reasons)
    print(self.reasonArray)

    let reasonID = gotData.reason_and_whom_meet?.reason_list![self.reasonID]
    print(reasons)
} catch let err {
    print("Error", err)
}

Также сначала вызываются методы делегата сборщика, но в это время ответ пуст. Как это решить? Мой выборщик показывает пустым. И ответ такой:

"GoogleClassroomPoC.nameList(name: Optional(\"Teacher\"))"

Но мне нужен только этот Учитель и Директор в моем массиве. Должен ли я преобразовать это в любой формат или мы можем показать его прямо в окне выбора.

Борюсь с этим разбором, помогите пожалуйста!


person NiranjanB    schedule 20.03.2018    source источник
comment
Пожалуйста, добавьте JSON, который вы анализируете, и код, который вы используете для выбора.   -  person PGDev    schedule 20.03.2018
comment
@PGDev. Но как получить идентификатор, если он в массиве?   -  person NiranjanB    schedule 20.03.2018
comment
Вы можете получить идентификатор для каждого элемента массива следующим образом: self.data?.reason_list?[row].id   -  person PGDev    schedule 20.03.2018
comment
{ Reason_and_whom_meet: { Reason_list: [{id: 1, Reason: Вне очереди оставить запрос для моего ребенка}, { id: 2, Reason: Отзыв, связанный с учителями}, { id: 3, Reason: Отзыв, связанный с преподавателями}, {id : 4, причина: связанные с почтовым идентификатором и классом Google }, {id: 5, причина: связанные с транспортом}, {id: 6, причина: связанные с детьми}, { id: 7 причина: другие}], who_meet: [{ id: 1, имя: Учитель}, {id: 2, имя: Директор} ]}} Это json, который я получил. Пожалуйста, отформатируйте с помощью форматтера. Не разрешается редактировать часть вопроса. Тем не менее я не могу видеть, что мой выборщик заполнен.   -  person NiranjanB    schedule 21.03.2018


Ответы (1)


Я создал простой код, похожий на ваш сценарий, как заставить это работать.

1. Простой UIPickerView с одним компонентом, который отображает reason из reason_list из both.

var data: both?

@IBOutlet weak var picker: UIPickerView!

override func viewDidLoad()
{
    super.viewDidLoad()
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
    return self.data?.reason_list?.count ?? 0
}

func numberOfComponents(in pickerView: UIPickerView) -> Int
{
    return 1
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
    return self.data?.reason_list?[row].reason
}

Изначально, когда загружается ViewController, data это nil, поэтому UIPickerView ничего не показывает.

2. Я создал UIButton, который загружает data, а UIPickerView перезагружается. Я использовал некоторые жестко запрограммированные данные. Вы можете получить эти данные из своего API.

@IBAction func loadData(_ sender: UIButton)
{
    let jsonString = """
    {
        "reason_list": [
            {"id": 1, "reason": "ABCD"},
            {"id": 2, "reason": "WXYZ"}
        ]
    }
    """

    if let data = jsonString.data(using: .utf8)
    {
        self.data = try? JSONDecoder().decode(both.self, from: data)
         DispatchQueue.main.async {[weak self] in
               self?.picker.reloadComponent(0) //HERE..!!!
         }
    }
}

Дайте мне знать, если вы все еще сталкиваетесь с какими-либо проблемами.

person PGDev    schedule 20.03.2018
comment
Если я использую reloadallcomponents() после ответа. Он выдает ошибку, как будто вы должны вызывать ее из основного потока. - person NiranjanB; 20.03.2018
comment
Я отредактировал ответ. Любое обновление пользовательского интерфейса должно выполняться в потоке main. Используйте DispatchQueue.main.async. - person PGDev; 20.03.2018
comment
Я добавил Json в раздел комментариев. @PGDev - person NiranjanB; 21.03.2018
comment
Вы перезагрузили свой контент после получения ответа API? Что именно вы хотите показать в UIPickerView? - person PGDev; 21.03.2018
comment
Здесь я столкнулся с другой проблемой. Я получил разделенную строку: who_meet (имя: необязательно (учитель)) в цикле for из этого необязательного ([GoogleClassroomPoC.whom_meet (имя: необязательно (учитель)), GoogleClassroomPoC.whom_meet (имя: необязательно (начальник))]). Но я столкнулся с проблемой при обрезке, чтобы получить от этого Учителя. Потому что это не String? Чтобы мой массив выглядел как имена = [Учитель, Директор] - person NiranjanB; 21.03.2018
comment
Добавьте обновленный код, который вы использовали для получения данных, а затем расшифруйте их. - person PGDev; 21.03.2018
comment
Только после декодирования я получаю это значение, если я не ошибаюсь? Эта строка должна быть обрезана? если он обрезан, мы можем легко добавить его в наш массив и показать этот массив. Извините, что углубляю. - person NiranjanB; 21.03.2018
comment
Вы про Факультатив? - person PGDev; 21.03.2018
comment
Понял . По let gotData = try JSONDecoder().decode(Reasons.self, from: data!) let person = gotData.reason_and_whom_meet?.whom_meet print(persons) for person in person!{ self.wtmArray.append(person.name!) } print(self.wtmArray) Теперь этот массив дает мне именно то, что я хочу. Спасибо за помощь в том, как звонить из основного потока, это действительно хорошо сыграло. - person NiranjanB; 21.03.2018
comment
Но если я попытаюсь запустить это на устройстве, оно ничего не покажет в сборщике, запутавшись ?? - person NiranjanB; 21.03.2018
comment
Вы установили делегата UIPickerView и источник данных? - person PGDev; 21.03.2018
comment
Да. Он работает в симуляторе, вот и путаница. Во время работы на устройстве он показывает: индекс вне диапазона в функции didselectrow, но содержимое не отображается. - person NiranjanB; 21.03.2018
comment
Добавьте код didselectrow и проверьте количество элементов в массиве, который вы используете в качестве источника данных, в UIPickerView - person PGDev; 21.03.2018
comment
Кажется, это была ошибка порта, потому что я передал правильные значения. Теперь все в порядке. Я хочу связаться с вами, могу ли я получить ваши контакты, пожалуйста? - person NiranjanB; 21.03.2018
comment
Вы можете спросить меня, есть ли у вас какие-либо проблемы. Примите и поддержите ответ, если он сработал. Удачного кодирования..????. Для получения дополнительной информации о Codable вы можете обратиться к: hackernoon.com/everything-about -codable-in-swift-4-97d0e18a2999 - person PGDev; 21.03.2018
comment
Привет. Я использую запрос Alamofire, я столкнулся с проблемой, что: методы делегата табличного представления выполняются первыми перед запросом alamofire, где я получу ответ и сохраню его в массивах. я также вызвал метод dispatch_async внутри запроса, но код не смог этого достичь. - person NiranjanB; 23.03.2018