Не можете понять, как получить все новые данные JSON с помощью кодируемых - PullRequest
1 голос
/ 03 октября 2019

Я пытался возиться с кодируемыми файлами и использую QuickType для форматирования всех своих структур. Тем не менее, данные для статистики будут постоянно меняться в зависимости от добавляемых новых материалов. Допустим, есть убийства и победные убийства, а затем в категорию добавлены выстрелы в голову. В настоящее время я не могу просто просмотреть эти данные и создать массив для каждой конкретной легенды. Как и сейчас, я могу получить доступ к переменной только по отдельности, и поэтому мне придется постоянно менять код, чтобы получить новый материал. Где, как и в случае с массивом, я мог бы просто установить его в tableView и оставить его в покое.

Я пытался использовать

 print(store.data.segments.map{$0.stats.carePackageKills?.displayName}[2])

Но это дает мне только один результат или если я удаляю [2], тогда я получу все для этой конкретной категории "carePackageKills". Я хочу, чтобы все статистические данные были помещены в массивы для определенных легенд, но кажется, что API этого не допустит?

Structs:

// MARK: - Store struct Store: Codable {let data: DataClass

    enum CodingKeys: String, CodingKey {
        case data = "data"
    }
}

// MARK: - DataClass
struct DataClass: Codable {
    let platformInfo: PlatformInfo
    let userInfo: UserInfo
    let metadata: DataMetadata
    let segments: [Segment]
    let availableSegments: [AvailableSegment]
    //let expiryDate: ExpiryDate

    enum CodingKeys: String, CodingKey {
        case platformInfo = "platformInfo"
        case userInfo = "userInfo"
        case metadata = "metadata"
        case segments = "segments"
        case availableSegments = "availableSegments"
        //case expiryDate = "expiryDate"
    }
}

// MARK: - AvailableSegment
struct AvailableSegment: Codable {
    let type: TypeEnum
    let attributes: MetadataClass

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

// MARK: - MetadataClass
struct MetadataClass: Codable {
}

enum TypeEnum: String, Codable {
    case legend = "legend"
    case overview = "overview"
}



// MARK: - DataMetadata
struct DataMetadata: Codable {
    let currentSeason: Int
    let activeLegend: String
    let activeLegendName: String

    enum CodingKeys: String, CodingKey {
        case currentSeason = "currentSeason"
        case activeLegend = "activeLegend"
        case activeLegendName = "activeLegendName"
    }
}

// MARK: - PlatformInfo
struct PlatformInfo: Codable {
    let platformSlug: String
    let platformUserId: String
    let platformUserHandle: String
    let platformUserIdentifier: String
    let avatarUrl: String
    let additionalParameters: JSONNull?

    enum CodingKeys: String, CodingKey {
        case platformSlug = "platformSlug"
        case platformUserId = "platformUserId"
        case platformUserHandle = "platformUserHandle"
        case platformUserIdentifier = "platformUserIdentifier"
        case avatarUrl = "avatarUrl"
        case additionalParameters = "additionalParameters"
    }
}

// MARK: - Segment
struct Segment: Codable {
    let type: TypeEnum
    let attributes: SegmentAttributes
    let metadata: SegmentMetadata
   // let expiryDate: ExpiryDate
    let stats: Stats

    enum CodingKeys: String, CodingKey {
        case type = "type"
        case attributes = "attributes"
        case metadata = "metadata"
        //case expiryDate = "expiryDate"
        case stats = "stats"
    }
}

// MARK: - SegmentAttributes
struct SegmentAttributes: Codable {
    let id: String?

    enum CodingKeys: String, CodingKey {
        case id = "id"
    }
}

// MARK: - SegmentMetadata
struct SegmentMetadata: Codable {
    let name: String
    let imageUrl: String?
    let tallImageUrl: String?
    let bgImageUrl: String?
    let isActive: Bool?

    enum CodingKeys: String, CodingKey {
        case name = "name"
        case imageUrl = "imageUrl"
        case tallImageUrl = "tallImageUrl"
        case bgImageUrl = "bgImageUrl"
        case isActive = "isActive"
    }
}

// MARK: - Stats
struct Stats: Codable {
    let level: ArKills?
    let kills: ArKills
    let damage: ArKills?
    let headshots: ArKills?
    let finishers: ArKills?
    let arKills: ArKills?
    let carePackageKills: ArKills?
    let seasonWins: ArKills?
    let seasonKills: ArKills?
    let season2Wins: ArKills?
    let rankScore: RankScore?
    let smokeGrenadeEnemiesHit: ArKills?
    let eyeEnemiesScanned: ArKills?
    let grappleTravelDistance: ArKills?

    enum CodingKeys: String, CodingKey {
        case level = "level"
        case kills = "kills"
        case damage = "damage"
        case headshots = "headshots"
        case finishers = "finishers"
        case arKills = "arKills"
        case carePackageKills = "carePackageKills"
        case seasonWins = "seasonWins"
        case seasonKills = "seasonKills"
        case season2Wins = "season2Wins"
        case rankScore = "rankScore"
        case smokeGrenadeEnemiesHit = "smokeGrenadeEnemiesHit"
        case eyeEnemiesScanned = "eyeEnemiesScanned"
        case grappleTravelDistance = "grappleTravelDistance"
    }
}

// MARK: - ArKills
struct ArKills: Codable {
    let rank: Int?
    let percentile: Double?
    let displayName: String
    let displayCategory: DisplayCategory
    let category: JSONNull?
    let metadata: MetadataClass
    let value: Double
    let displayValue: String
    let displayType: DisplayType

    enum CodingKeys: String, CodingKey {
        case rank = "rank"
        case percentile = "percentile"
        case displayName = "displayName"
        case displayCategory = "displayCategory"
        case category = "category"
        case metadata = "metadata"
        case value = "value"
        case displayValue = "displayValue"
        case displayType = "displayType"
    }
}

enum DisplayCategory: String, Codable {
    case combat = "Combat"
    case game = "Game"
    case weapons = "Weapons"
}

enum DisplayType: String, Codable {
    case unspecified = "Unspecified"
}

// MARK: - RankScore
struct RankScore: Codable {
    let rank: JSONNull?
    let percentile: Int
    let displayName: String
    let displayCategory: DisplayCategory
    let category: JSONNull?
    let metadata: RankScoreMetadata
    let value: Int
    let displayValue: String
    let displayType: DisplayType

    enum CodingKeys: String, CodingKey {
        case rank = "rank"
        case percentile = "percentile"
        case displayName = "displayName"
        case displayCategory = "displayCategory"
        case category = "category"
        case metadata = "metadata"
        case value = "value"
        case displayValue = "displayValue"
        case displayType = "displayType"
    }
}

// MARK: - RankScoreMetadata
struct RankScoreMetadata: Codable {
    let iconUrl: String

    enum CodingKeys: String, CodingKey {
        case iconUrl = "iconUrl"
    }
}

// MARK: - UserInfo
struct UserInfo: Codable {
    let isPremium: Bool
    let isVerified: Bool
    let isInfluencer: Bool
    let countryCode: String
    let customAvatarUrl: JSONNull?
    let socialAccounts: JSONNull?

    enum CodingKeys: String, CodingKey {
        case isPremium = "isPremium"
        case isVerified = "isVerified"
        case isInfluencer = "isInfluencer"
        case countryCode = "countryCode"
        case customAvatarUrl = "customAvatarUrl"
        case socialAccounts = "socialAccounts"
    }
}

// MARK: - Encode/decode helpers

class JSONNull: Codable, Hashable {

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
        return true
    }

    public var hashValue: Int {
        return 0
    }

    public func hash(into hasher: inout Hasher) {
        // No-op
    }

    public init() {}

    public required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() {
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    }
} 

API-интерфейс вызова

let PlayerStatURL = URL(string: "https://public-api.tracker.gg/v2/apex/standard/profile/origin/itsspress")

        if let unwrappedURL = PlayerStatURL {
            var request = URLRequest(url: unwrappedURL)
            request.addValue("db833c37-1f45-4be4-a670-38272dba7504", forHTTPHeaderField: "TRN-Api-Key")
            let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
                // you should put in error handling code, too
                if let data = data {
                    do {


                        let store = try JSONDecoder().decode(Store.self, from: data) as Store

                        print(store.data.platformInfo.avatarUrl)
                        print(store.data.platformInfo.platformUserHandle)
                        print("Level: \(store.data.segments[0].stats.level!.displayValue)")

                        print("lifetime Kills: \(store.data.segments.map{$0.stats.kills.displayValue}[0])")

                        print(store.data.segments.map{$0.metadata.name})
                        print(store.data.segments.map{$0.stats.carePackageKills?.displayName}[2])


                    } catch {
                        print(error.localizedDescription)
                        print(error)

                        }
                    }
                }
            dataTask.resume()

        } 

Я хочу иметь возможность печатать имена легенд вместе с каждым "stats" diplayName и DisplayValue. В настоящее время я могу получить только отдельные имена и значения, и мне придется назначать их индивидуально. Что было бы небрежно.

Я хотел бы иметь возможность поместить DisplayName и DisplayValue в массивы, чтобы я мог назначить их различным легендам. Затем, если данные когда-либо будут добавлены, у массивов будет просто больше данных и добавит их в связанную легенду.

...