Я пытался возиться с кодируемыми файлами и использую 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 в массивы, чтобы я мог назначить их различным легендам. Затем, если данные когда-либо будут добавлены, у массивов будет просто больше данных и добавит их в связанную легенду.