Как добавить значения из JSON в массив? - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь получить значения из JSON и добавить их к titleArray.

func updateUI() {
        DispatchQueue.global(qos: .background).async {
            // network call to the API
            self.fetchTipsJson(completion: { (res) in
                switch res {
                case .success(let tips):
                     self.titleArray.append(tips.responseList!.values[title]) // Cannot subscript a value of type '[Value]' with an index of type 'String?'
                    print(self.titleArray)

                case .failure(let err):
                    print("Failed to fetch tips:", err)
                }

            })
            DispatchQueue.main.async {
                // Update the UI Label here

            }
        }
    }

Я получаю сообщение об ошибке, но не думаю, что именно так это и должно быть.

JSON:

{
    "$type": "DTOMapper.DTOResponseList`1[[Telemed.Dto.DTOTip, Telemed.Dto]], DTOMapper",
    "ResponseList": {
        "$type": "System.Collections.Generic.List`1[[Telemed.Dto.DTOTip, Telemed.Dto]], mscorlib",
        "$values": [
            {
                "$type": "Telemed.Dto.DTOTip, Telemed.Dto",
                "Title": "NO TE JUNTES CON LUQUITAS",
                "Text": "Porque si tenes un amigo lucas y otro amigo lucas, tenés dos lucas. Pero no te sirven para pagar nada",
                "GroupName": "TGC.Tips1",
                "ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[0]"
            },
            {
                "$type": "Telemed.Dto.DTOTip, Telemed.Dto",
                "Title": "no te emborraches en las fiestas",
                "Text": "Terminarás pateando globos",
                "GroupName": "TGC.Tips2",
                "ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[1]"
            }
        ]
    },
    "StatusCode": 200,
    "ErrorId": 0
}

Правильно ли я получаю доступ к $values? Если это поможет, titleArray будет использоваться с UILabel.

Редактировать для updateLabels():

func updateLabels() {
        self.myTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { (t) in
            self.titleLabel.text = self.titleArray[self.counter] as? String
            self.textLabel.text = self.textArray[self.counter] as? String
            self.counter += 1
            if self.counter == self.titleArray.count && self.counter == self.textArray.count{
                t.invalidate()
            }
        }
    }

Редактировать для обратного вызова:

do {
            let tips = try JSONDecoder().decode(Root.self, from: data!)
            self.titleArray = tips.responseList!.values.map { $0.title }
            self.textArray = tips.responseList!.values.map { $0.text }
            DispatchQueue.main.async {
                self.updateLabels()
            }
            completion(.success(tips))
        } catch let jsonError {
            completion(.failure(jsonError))
        }

Редактировать для viewDidLoad():

override func viewDidLoad() {
        super.viewDidLoad()

        fetchTipsJson { (res) in
            switch res {
            case .success:
                return
            case .failure(let err):
                print("Failed to fetch tips:", err)
            }
        }
    }

Ответы [ 2 ]

0 голосов
/ 13 июня 2019

Первым делом tips.responseList!.values - это Array, а не Dictionary. Так что вы не можете делать, как

self.titleArray.append(tips.responseList!.values[title])

Вы можете сделать это, перебирая все элементы внутри массива.

self.titleArray.append(contentsOf:tips.responseList!.values.compactMap { $0.title })

Пожалуйста, игнорируйте синтаксическую ошибку, потому что это справедливая идея.

0 голосов
/ 13 июня 2019

values - это массив, а не словарь, вам нужно сопоставить его со строкой title, поэтому попробуйте

let str = """

{
"$type": "DTOMapper.DTOResponseList`1[[Telemed.Dto.DTOTip, Telemed.Dto]], DTOMapper",
"ResponseList": {
"$type": "System.Collections.Generic.List`1[[Telemed.Dto.DTOTip, Telemed.Dto]], mscorlib",
"$values": [
{
"$type": "Telemed.Dto.DTOTip, Telemed.Dto",
"Title": "NO TE JUNTES CON LUQUITAS",
"Text": "Porque si tenes un amigo lucas y otro amigo lucas, tenés dos lucas. Pero no te sirven para pagar nada",
"GroupName": "TGC.Tips1",
"ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[0]"
},
{
"$type": "Telemed.Dto.DTOTip, Telemed.Dto",
"Title": "no te emborraches en las fiestas",
"Text": "Terminarás pateando globos",
"GroupName": "TGC.Tips2",
"ConfigurationPath": "TelemedGlobalConfig>Tips>Tips[1]"
}
]
},
"StatusCode": 200,
"ErrorId": 0
}
"""



do {
      let res = try JSONDecoder().decode(Root.self, from: Data(str.utf8))
      let arr = res.responseList.values.map { $0.title }
      print(arr)
   }
   catch {
        print(error)
    }
}

// MARK: - Empty
struct Root: Codable {
    let type: String
    let responseList: ResponseList
    let statusCode, errorID: Int

    enum CodingKeys: String, CodingKey {
        case type = "$type"
        case responseList = "ResponseList"
        case statusCode = "StatusCode"
        case errorID = "ErrorId"
    }
}

// MARK: - ResponseList
struct ResponseList: Codable {
    let type: String
    let values: [Value]

    enum CodingKeys: String, CodingKey {
        case type = "$type"
        case values = "$values"
    }
}

// MARK: - Value
struct Value: Codable {
    let type, title, text, groupName: String
    let configurationPath: String

    enum CodingKeys: String, CodingKey {
        case type = "$type"
        case title = "Title"
        case text = "Text"
        case groupName = "GroupName"
        case configurationPath = "ConfigurationPath"
    }
}

Edit:

var counter = 0

var myTimer:Timer!

self.myTimer =    Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { (t) in
    self.lbl.text = self.titleArr[self.counter]
    counter += 1
    if self.counter == self.titleArr.count {
        t.invalidate()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...