как я могу получить твит с JSONDecoder - PullRequest
0 голосов
/ 16 января 2020

Я использовал веб-сайт Json4Swift.

Root Модель:

struct Json4Swift_Base : Codable {
    let trends : [Trends]?
    let as_of : String?
    let created_at : String?
    let locations : [Locations]?

    enum CodingKeys: String, CodingKey {

        case trends = "trends"
        case as_of = "as_of"
        case created_at = "created_at"
        case locations = "locations"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        trends = try values.decodeIfPresent([Trends].self, forKey: .trends)
        as_of = try values.decodeIfPresent(String.self, forKey: .as_of)
        created_at = try values.decodeIfPresent(String.self, forKey: .created_at)
        locations = try values.decodeIfPresent([Locations].self, forKey: .locations)
    }

}

Модель местоположения:

struct Locations : Codable {
    let name : String?
    let woeid : Int?

    enum CodingKeys: String, CodingKey {

        case name = "name"
        case woeid = "woeid"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        woeid = try values.decodeIfPresent(Int.self, forKey: .woeid)
    }
}

Модель тренда:

struct Trends : Codable {
    let name : String?
    let url : String?
    let promoted_content : String?
    let query : String?
    let tweet_volume : Int?

    enum CodingKeys: String, CodingKey {

        case name = "name"
        case url = "url"
        case promoted_content = "promoted_content"
        case query = "query"
        case tweet_volume = "tweet_volume"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        url = try values.decodeIfPresent(String.self, forKey: .url)
        promoted_content = try values.decodeIfPresent(String.self, forKey: .promoted_content)
        query = try values.decodeIfPresent(String.self, forKey: .query)
        tweet_volume = try values.decodeIfPresent(Int.self, forKey: .tweet_volume)
    }
}

Код запроса Twitter:

    let request = client.urlRequest(withMethod: "GET", urlString: statusesShowEndpoint, parameters: params, error: &clientError)

        client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
            if connectionError != nil {
                print("Error: \(String(describing: connectionError))")
            }
            do {
//                let json = try JSONSerialization.jsonObject(with: data!, options: [])
//                print(json)
//                -> How do I get the data without using this code.
                let rssFeed = try JSONDecoder().decode(Json4Swift_Base.self, from: data!)

                    self.trends = rssFeed.trends!

            } catch let jsonError as NSError {
                print("json error: \(jsonError.localizedDescription)")
            }
        }
        print("Trend: \(trends)")
    }
}

Как получить твит с помощью JSONDecoder (). Decode (), как получить данные без использования этого кода. JSONSerialization.jsonObject ()

Я получаю сообщение об ошибке при использовании этого кода.

let rssFeed = try JSONDecoder().decode(Json4Swift_Base.self, from: data!)

Twitter Api находится здесь: https://developer.twitter.com/en/docs/trends/trends-for-location/api-reference/get-trends-place

Как я могу декодировать JSON данных. Извините за мой Engli sh. Я знаю маленький английский sh.

1 Ответ

0 голосов
/ 16 января 2020

JSON

Итак, это ваша JSON

let data = """
[
  {
    "trends": [
      {
        "name": "#ChainedToTheRhythm",
        "url": "http://twitter.com/search?q=%23ChainedToTheRhythm",
        "promoted_content": null,
        "query": "%23ChainedToTheRhythm",
        "tweet_volume": 48857
      },
      {
        "name": "#اليوم_العالمي_للعتبان",
        "url": "http://twitter.com/search?q=%23%D8%A7%D9%84%D9%8A%D9%88%D9%85_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%84%D9%84%D8%B9%D8%AA%D8%A8%D8%A7%D9%86",
        "promoted_content": null,
        "query": "%23%D8%A7%D9%84%D9%8A%D9%88%D9%85_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%84%D9%84%D8%B9%D8%AA%D8%A8%D8%A7%D9%86",
        "tweet_volume": null
      },
      {
        "name": "George Lopez",
        "url": "http://twitter.com/search?q=%22George+Lopez%22",
        "promoted_content": null,
        "query": "%22George+Lopez%22",
        "tweet_volume": 90590
      },
      {
        "name": "#قل_كلمه_للي_يتابعك",
        "url": "http://twitter.com/search?q=%23%D9%82%D9%84_%D9%83%D9%84%D9%85%D9%87_%D9%84%D9%84%D9%8A_%D9%8A%D8%AA%D8%A7%D8%A8%D8%B9%D9%83",
        "promoted_content": null,
        "query": "%23%D9%82%D9%84_%D9%83%D9%84%D9%85%D9%87_%D9%84%D9%84%D9%8A_%D9%8A%D8%AA%D8%A7%D8%A8%D8%B9%D9%83",
        "tweet_volume": null
      },
      {
        "name": "#FelizMiercoles",
        "url": "http://twitter.com/search?q=%23FelizMiercoles",
        "promoted_content": null,
        "query": "%23FelizMiercoles",
        "tweet_volume": 36103
      },
      {
        "name": "#wednesdaywisdom",
        "url": "http://twitter.com/search?q=%23wednesdaywisdom",
        "promoted_content": null,
        "query": "%23wednesdaywisdom",
        "tweet_volume": 42916
      },
      {
        "name": "Tara Palmer-Tomkinson",
        "url": "http://twitter.com/search?q=%22Tara+Palmer-Tomkinson%22",
        "promoted_content": null,
        "query": "%22Tara+Palmer-Tomkinson%22",
        "tweet_volume": null
      },
      {
        "name": "呪いチョコ",
        "url": "http://twitter.com/search?q=%E5%91%AA%E3%81%84%E3%83%81%E3%83%A7%E3%82%B3",
        "promoted_content": null,
        "query": "%E5%91%AA%E3%81%84%E3%83%81%E3%83%A7%E3%82%B3",
        "tweet_volume": 15704
      },
      {
        "name": "メンテ",
        "url": "http://twitter.com/search?q=%E3%83%A1%E3%83%B3%E3%83%86",
        "promoted_content": null,
        "query": "%E3%83%A1%E3%83%B3%E3%83%86",
        "tweet_volume": 344416
      },
      {
        "name": "SLAY CAMILIZERS",
        "url": "http://twitter.com/search?q=%22SLAY+CAMILIZERS%22",
        "promoted_content": null,
        "query": "%22SLAY+CAMILIZERS%22",
        "tweet_volume": 707166
      },
      {
        "name": "あなたの精神年齢",
        "url": "http://twitter.com/search?q=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E7%B2%BE%E7%A5%9E%E5%B9%B4%E9%BD%A2",
        "promoted_content": null,
        "query": "%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E7%B2%BE%E7%A5%9E%E5%B9%B4%E9%BD%A2",
        "tweet_volume": null
      },
      {
        "name": "WORK FROM 5H",
        "url": "http://twitter.com/search?q=%22WORK+FROM+5H%22",
        "promoted_content": null,
        "query": "%22WORK+FROM+5H%22",
        "tweet_volume": 54061
      },
      {
        "name": "Leyla Zana",
        "url": "http://twitter.com/search?q=%22Leyla+Zana%22",
        "promoted_content": null,
        "query": "%22Leyla+Zana%22",
        "tweet_volume": null
      },
      {
        "name": "#TwoJustin",
        "url": "http://twitter.com/search?q=%23TwoJustin",
        "promoted_content": null,
        "query": "%23TwoJustin",
        "tweet_volume": null
      },
      {
        "name": "#MyFirstAndLast",
        "url": "http://twitter.com/search?q=%23MyFirstAndLast",
        "promoted_content": null,
        "query": "%23MyFirstAndLast",
        "tweet_volume": 63844
      },
      {
        "name": "#ValentinesDayIn3Words",
        "url": "http://twitter.com/search?q=%23ValentinesDayIn3Words",
        "promoted_content": null,
        "query": "%23ValentinesDayIn3Words",
        "tweet_volume": null
      },
      {
        "name": "#ShePersisted",
        "url": "http://twitter.com/search?q=%23ShePersisted",
        "promoted_content": null,
        "query": "%23ShePersisted",
        "tweet_volume": 45624
      },
      {
        "name": "#HappyJohnnyDay",
        "url": "http://twitter.com/search?q=%23HappyJohnnyDay",
        "promoted_content": null,
        "query": "%23HappyJohnnyDay",
        "tweet_volume": 28560
      },
      {
        "name": "#QuartaDetremuraSDV",
        "url": "http://twitter.com/search?q=%23QuartaDetremuraSDV",
        "promoted_content": null,
        "query": "%23QuartaDetremuraSDV",
        "tweet_volume": 10481
      },
      {
        "name": "#ترحيل_الاجانب_مطلب_وطني",
        "url": "http://twitter.com/search?q=%23%D8%AA%D8%B1%D8%AD%D9%8A%D9%84_%D8%A7%D9%84%D8%A7%D8%AC%D8%A7%D9%86%D8%A8_%D9%85%D8%B7%D9%84%D8%A8_%D9%88%D8%B7%D9%86%D9%8A",
        "promoted_content": null,
        "query": "%23%D8%AA%D8%B1%D8%AD%D9%8A%D9%84_%D8%A7%D9%84%D8%A7%D8%AC%D8%A7%D9%86%D8%A8_%D9%85%D8%B7%D9%84%D8%A8_%D9%88%D8%B7%D9%86%D9%8A",
        "tweet_volume": null
      },
      {
        "name": "#TapperDirtFile",
        "url": "http://twitter.com/search?q=%23TapperDirtFile",
        "promoted_content": null,
        "query": "%23TapperDirtFile",
        "tweet_volume": null
      },
      {
        "name": "#FelizCumplePresidente",
        "url": "http://twitter.com/search?q=%23FelizCumplePresidente",
        "promoted_content": null,
        "query": "%23FelizCumplePresidente",
        "tweet_volume": 15276
      },
      {
        "name": "#MeCasoSiMeDices",
        "url": "http://twitter.com/search?q=%23MeCasoSiMeDices",
        "promoted_content": null,
        "query": "%23MeCasoSiMeDices",
        "tweet_volume": null
      },
      {
        "name": "#FebreroZamorista",
        "url": "http://twitter.com/search?q=%23FebreroZamorista",
        "promoted_content": null,
        "query": "%23FebreroZamorista",
        "tweet_volume": null
      },
      {
        "name": "#NãoSuportoQuando",
        "url": "http://twitter.com/search?q=%23N%C3%A3oSuportoQuando",
        "promoted_content": null,
        "query": "%23N%C3%A3oSuportoQuando",
        "tweet_volume": 14327
      },
      {
        "name": "#NinguemSabeMasEuJa",
        "url": "http://twitter.com/search?q=%23NinguemSabeMasEuJa",
        "promoted_content": null,
        "query": "%23NinguemSabeMasEuJa",
        "tweet_volume": 12856
      },
      {
        "name": "#وش_شعورك_اول_يوم_دوام",
        "url": "http://twitter.com/search?q=%23%D9%88%D8%B4_%D8%B4%D8%B9%D9%88%D8%B1%D9%83_%D8%A7%D9%88%D9%84_%D9%8A%D9%88%D9%85_%D8%AF%D9%88%D8%A7%D9%85",
        "promoted_content": null,
        "query": "%23%D9%88%D8%B4_%D8%B4%D8%B9%D9%88%D8%B1%D9%83_%D8%A7%D9%88%D9%84_%D9%8A%D9%88%D9%85_%D8%AF%D9%88%D8%A7%D9%85",
        "tweet_volume": null
      },
      {
        "name": "#HappyChunghaDay",
        "url": "http://twitter.com/search?q=%23HappyChunghaDay",
        "promoted_content": null,
        "query": "%23HappyChunghaDay",
        "tweet_volume": 16480
      },
      {
        "name": "#DiaDeLaPiscola",
        "url": "http://twitter.com/search?q=%23DiaDeLaPiscola",
        "promoted_content": null,
        "query": "%23DiaDeLaPiscola",
        "tweet_volume": null
      },
      {
        "name": "#زواج_الامير_بدر_بن_عبدالله",
        "url": "http://twitter.com/search?q=%23%D8%B2%D9%88%D8%A7%D8%AC_%D8%A7%D9%84%D8%A7%D9%85%D9%8A%D8%B1_%D8%A8%D8%AF%D8%B1_%D8%A8%D9%86_%D8%B9%D8%A8%D8%AF%D8%A7%D9%84%D9%84%D9%87",
        "promoted_content": null,
        "query": "%23%D8%B2%D9%88%D8%A7%D8%AC_%D8%A7%D9%84%D8%A7%D9%85%D9%8A%D8%B1_%D8%A8%D8%AF%D8%B1_%D8%A8%D9%86_%D8%B9%D8%A8%D8%AF%D8%A7%D9%84%D9%84%D9%87",
        "tweet_volume": null
      },
      {
        "name": "#UnBuenTaco",
        "url": "http://twitter.com/search?q=%23UnBuenTaco",
        "promoted_content": null,
        "query": "%23UnBuenTaco",
        "tweet_volume": null
      },
      {
        "name": "#PMQs",
        "url": "http://twitter.com/search?q=%23PMQs",
        "promoted_content": null,
        "query": "%23PMQs",
        "tweet_volume": 20406
      },
      {
        "name": "#InteractFalando",
        "url": "http://twitter.com/search?q=%23InteractFalando",
        "promoted_content": null,
        "query": "%23InteractFalando",
        "tweet_volume": null
      },
      {
        "name": "#ナカイの窓",
        "url": "http://twitter.com/search?q=%23%E3%83%8A%E3%82%AB%E3%82%A4%E3%81%AE%E7%AA%93",
        "promoted_content": null,
        "query": "%23%E3%83%8A%E3%82%AB%E3%82%A4%E3%81%AE%E7%AA%93",
        "tweet_volume": 14835
      },
      {
        "name": "#حزب_اللي_ما_يحبون_دانكن",
        "url": "http://twitter.com/search?q=%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D9%84%D9%8A_%D9%85%D8%A7_%D9%8A%D8%AD%D8%A8%D9%88%D9%86_%D8%AF%D8%A7%D9%86%D9%83%D9%86",
        "promoted_content": null,
        "query": "%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D9%84%D9%8A_%D9%85%D8%A7_%D9%8A%D8%AD%D8%A8%D9%88%D9%86_%D8%AF%D8%A7%D9%86%D9%83%D9%86",
        "tweet_volume": 18170
      },
      {
        "name": "#LIZAonTWBA",
        "url": "http://twitter.com/search?q=%23LIZAonTWBA",
        "promoted_content": null,
        "query": "%23LIZAonTWBA",
        "tweet_volume": 68066
      },
      {
        "name": "#nldebat",
        "url": "http://twitter.com/search?q=%23nldebat",
        "promoted_content": null,
        "query": "%23nldebat",
        "tweet_volume": null
      },
      {
        "name": "#ConselhosDeUmTrouxa",
        "url": "http://twitter.com/search?q=%23ConselhosDeUmTrouxa",
        "promoted_content": null,
        "query": "%23ConselhosDeUmTrouxa",
        "tweet_volume": 11419
      },
      {
        "name": "#PBBKiligOverload",
        "url": "http://twitter.com/search?q=%23PBBKiligOverload",
        "promoted_content": null,
        "query": "%23PBBKiligOverload",
        "tweet_volume": 70766
      },
      {
        "name": "#MiMejorPiropoParaTi",
        "url": "http://twitter.com/search?q=%23MiMejorPiropoParaTi",
        "promoted_content": null,
        "query": "%23MiMejorPiropoParaTi",
        "tweet_volume": null
      },
      {
        "name": "#8Feb",
        "url": "http://twitter.com/search?q=%238Feb",
        "promoted_content": null,
        "query": "%238Feb",
        "tweet_volume": null
      },
      {
        "name": "#عوده_منصور_البلوي",
        "url": "http://twitter.com/search?q=%23%D8%B9%D9%88%D8%AF%D9%87_%D9%85%D9%86%D8%B5%D9%88%D8%B1_%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%8A",
        "promoted_content": null,
        "query": "%23%D8%B9%D9%88%D8%AF%D9%87_%D9%85%D9%86%D8%B5%D9%88%D8%B1_%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%8A",
        "tweet_volume": null
      },
      {
        "name": "#LoveBeyondFlags",
        "url": "http://twitter.com/search?q=%23LoveBeyondFlags",
        "promoted_content": null,
        "query": "%23LoveBeyondFlags",
        "tweet_volume": null
      },
      {
        "name": "#EscándaloOdebrecht",
        "url": "http://twitter.com/search?q=%23Esc%C3%A1ndaloOdebrecht",
        "promoted_content": null,
        "query": "%23Esc%C3%A1ndaloOdebrecht",
        "tweet_volume": null
      },
      {
        "name": "#PregúntaleAPedro",
        "url": "http://twitter.com/search?q=%23Preg%C3%BAntaleAPedro",
        "promoted_content": null,
        "query": "%23Preg%C3%BAntaleAPedro",
        "tweet_volume": null
      },
      {
        "name": "#بذاءه_مصري_في_كريم",
        "url": "http://twitter.com/search?q=%23%D8%A8%D8%B0%D8%A7%D8%A1%D9%87_%D9%85%D8%B5%D8%B1%D9%8A_%D9%81%D9%8A_%D9%83%D8%B1%D9%8A%D9%85",
        "promoted_content": null,
        "query": "%23%D8%A8%D8%B0%D8%A7%D8%A1%D9%87_%D9%85%D8%B5%D8%B1%D9%8A_%D9%81%D9%8A_%D9%83%D8%B1%D9%8A%D9%85",
        "tweet_volume": 38019
      },
      {
        "name": "#MSWL",
        "url": "http://twitter.com/search?q=%23MSWL",
        "promoted_content": null,
        "query": "%23MSWL",
        "tweet_volume": null
      },
      {
        "name": "#WhatsappÇöktü",
        "url": "http://twitter.com/search?q=%23Whatsapp%C3%87%C3%B6kt%C3%BC",
        "promoted_content": null,
        "query": "%23Whatsapp%C3%87%C3%B6kt%C3%BC",
        "tweet_volume": null
      },
      {
        "name": "#SoMeArrependoDe",
        "url": "http://twitter.com/search?q=%23SoMeArrependoDe",
        "promoted_content": null,
        "query": "%23SoMeArrependoDe",
        "tweet_volume": null
      },
      {
        "name": "#حزب_العاطلين_بتويتر",
        "url": "http://twitter.com/search?q=%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D8%B9%D8%A7%D8%B7%D9%84%D9%8A%D9%86_%D8%A8%D8%AA%D9%88%D9%8A%D8%AA%D8%B1",
        "promoted_content": null,
        "query": "%23%D8%AD%D8%B2%D8%A8_%D8%A7%D9%84%D8%B9%D8%A7%D8%B7%D9%84%D9%8A%D9%86_%D8%A8%D8%AA%D9%88%D9%8A%D8%AA%D8%B1",
        "tweet_volume": null
      }
    ],
    "as_of": "2017-02-08T16:18:18Z",
    "created_at": "2017-02-08T16:10:33Z",
    "locations": [
      {
        "name": "Worldwide",
        "woeid": 1
      }
    ]
  }
]
""".data(using: .utf8)!

Модель

Теперь вы можете упростить вашу модель

struct Location: Codable {
    let name: String?
    let woeid: Int?
}

struct Trend: Codable {
    let name: String?
    let url: URL?
    let promotedContent: String?
    let query: String?
    let tweetVolume: Int?
}

struct Element: Codable {
    let trends: [Trend]?
    let asOf: String?
    let createdAt: String?
    let locations: [Location]?
}

Декодирование с snake_case_notation

Далее вы можете создать свой JSONDecoder () и правильно установить key decoding strategy.

let jsonDecoder = JSONDecoder()
jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase

Декодирование !!

И, наконец, помните, что ваш JSON - это массив элементов, поэтому при декодировании используйте [Element].self вместо, если Element.self.

do {
    let response = try JSONDecoder().decode([Element].self, from: data)
    print(response)
} catch {
    print(error)
}

Вот и все.

ОБНОВЛЕНИЕ

О вашем comment

Как получить тренды из массива Elements?

Это способ доступа к значениям тренда.

do {
    let response = try JSONDecoder().decode([Element].self, from: data)


    for element in response {

        for trend in element.trends ?? [] {
            print(trend)
        }
    }

} catch {
    print(error)
}

Вы также можете сохранить все Trend(s) в один массив

let allTrends = response.compactMap { $0.trends }.flatMap { $0 }
print(allTrends)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...