如何在 Swift 5 中打印这个 JSON 值?

Posted

技术标签:

【中文标题】如何在 Swift 5 中打印这个 JSON 值?【英文标题】:How can I print this JSON value in Swift 5? 【发布时间】:2020-11-23 18:00:58 【问题描述】:

"optionChain": 
    "result": [
        
            "underlyingSymbol": "AAPL",
            "expirationDates": [
                1606435200,
                1607040000,
                1607644800,
                1608249600,
                1608768000,
                1609372800,
                1610668800,
                1613692800,
                1616112000,
                1618531200,
                1623974400,
                1626393600,
                1631836800,
                1642723200,
                1655424000,
                1663286400,
                1674172800
            ],
            "strikes": [
                55,
                60,
                65,
                70,
                75
            ],
            "hasMiniOptions": false,
            

如何在 JSON 中打印出“underlyingSymbol”或任何相关字段?我了解打印出单个 JSON 字段,但如何进入嵌入式字段?

所以我按照以下建议制作了可解码:

struct Something: Decodable

    let optionChain: OptionChain
    let error: String


struct OptionChain: Decodable

    let result: [ResultElement]


struct ResultElement: Decodable

    let underlyingSymbol: String
    let expirationDates: [Int]
    let strikes: [Int]
    let hasMiniOptions: Bool
    let quote: [quoteElement]
    let options: [optionsElement]


struct quoteElement: Decodable

    let language: String
    let region: String
    let quoteType: String
    let quoteSourceName: String
    let triggerable: Bool
    let currency: String
    let firstTradeDateMilliseconds: Int
    let priceHint: Int
    let regularMarketChange: Int
    let regularMarketChangePercent: Int
    let regularMarketTime: Int
    let regularMarketPrice: Int
    let regularMarketDayHigh: Int
    let regularMarketDayRange: String
    let regularMarketDayLow: Int
    let regularMarketVolume: Int
    let regularMarketPreviousClose: Int
    let bid: Int
    let ask: Int
    let bidSize: Int
    let askSize: Int
    let fullExchangeName: String
    let financialCurrency: String
    let regularMarketOpen: Int
    let averageDailyVolume3Month: Int
    let averageDailyVolume10Day: Int
    let fiftyTwoWeekLowChange: Int
    let fiftyTwoWeekLowChangePercent: Int
    let fiftyTwoWeekRange: String
    let fiftyTwoWeekHighChange: Int
    let fiftyTwoWeekHighChangePercent: Int
    let fiftyTwoWeekLow: Int
    let fiftyTwoWeekHigh: Int
    let dividendDate: Int
    let earningsTimestamp: Int
    let earningsTimestampStart: Int
    let earningsTimestampEnd: Int
    let trailingAnnualDividendRate: Int
    let trailingPE: Int
    let trailingAnnualDividendYield: Int
    let epsTrailingTwelveMonths: Int
    let epsForward: Int
    let epsCurrentYear: Int
    let priceEpsCurrentYear: Int
    let sharesOutstanding: Int
    let bookValue: Int
    let fiftyDayAverage: Int
    let fiftyDayAverageChange: Int
    let fiftyDayAverageChangePercent: Int
    let twoHundredDayAverage: Int
    let twoHundredDayAverageChange: Int
    let twoHundredDayAverageChangePercent: Int
    let marketCap: Int
    let forwardPE: Int
    let priceToBook: Int
    let sourceInterval: Int
    let exchangeDataDelayedBy: Int
    let tradeable: Bool
    let exchange: String
    let shortName: String
    let longName: String
    let marketState: String
    let messageBoardId: String
    let exchangeTimezoneName: String
    let exchangeTimezoneShortName: String
    let gmtOffSetMilliseconds: Int
    let market: String
    let esgPopulated: Bool
    let displayName: String
    let symbol: String


struct optionsElement: Decodable

    let expirationDate: Int
    let hasMiniOptions: Bool
    let calls: [callPutElement]
    let puts: [callPutElement]


struct callPutElement: Decodable

    let contractSymbol: String
    let strike: Int
    let currency: String
    let lastPrice: Int
    let change: Int
    let percentChange: Int
    let volume: Int
    let openInterest: Int
    let bid: Int
    let ask: Int
    let contractSize: String
    let expiration: Int
    let lastTradeDate: Int
    let impliedVolatility: Int
    let inTheMoney: Bool

但是现在我收到一个错误:

JSONSerialization 错误:dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in字符 1 周围的对象。" UserInfo=NSDebugDescription=字符 1 周围的对象中的值没有字符串键。)))

【问题讨论】:

使用 JSONDecoderJSONSerialization 解析 JSON(如何做到这一点是 SO 上最常见的问题之一).. 第一项中键 underlyingSymbol 的值数组 ([]) 用于键 result 在字典 () 中用于键 optionChain 我了解JSONSeriaIization,但我不明白JSON的关键。 【参考方案1】:

我会使用 Codable api:

struct Something: Decodable 
    let optionChain: OptionChain


struct OptionChain: Decodable 
    let result: [ResultElement]


struct ResultElement: Decodable 
    let underlyingSymbol: String
    let expirationDates: [Int]
    let strikes: [Int]
    let hasMiniOptions: Bool


let jsonString = "..."

let jsonData = jsonString.data(using: .utf8)!

let decoder = JSONDecoder()
let something = try decoder.decode(Something.self, from: jsonData)

print(something.optionChain.result.map  $0.underlyingSymbol )

【讨论】:

我知道你在那里做了什么。但是,当我尝试这个时,我得到了这个错误。 JSONSerialization错误:dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON。”,underlyingError:可选(错误域=NSCocoaErrorDomain代码=3840“字符周围的对象中没有值的字符串键1." UserInfo=NSDebugDescription=在字符 1 周围的对象中没有值的字符串键。)))

以上是关于如何在 Swift 5 中打印这个 JSON 值?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Swift 5 (iOS) 从 Firebase 数据库中获取和打印单个值

如何在 Swift 4.0 中将 JSON 输出设置为 UILabel?

Swift JSON 解析和打印数组中的指定值

如何在swift 3中解析Json对象

如何在 JSON 数组中打印数组值 [关闭]

如何使用 Alamofire swift 3 从这个 JSON 中获取值