-1

I am currently using Tracker Networks Apex Legends API version 2. I am trying to get the Legend’s data for each legend and then be able to show the data for each specific legend. However, I cannot figure out an easy way of doing this. Any ideas on how I could get something like...

Pathfinder Kills - 100 Damage - 3000 Etc.

And do that for each legend.

JSON response:

      {
        "type": "legend",
        "attributes": {
          "id": "legend_8"
        },
        "metadata": {
          "name": "Pathfinder",
          "imageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/pathfinder-tile.png",
          "tallImageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/pathfinder-tall.png",
          "bgImageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/pathfinder-concept-bg-small.jpg",
          "isActive": true
        },
        "expiryDate": "2019-10-04T21:59:04.1270197Z",
        "stats": {
          "kills": {
            "rank": 208,
            "percentile": 99.9,
            "displayName": "Kills",
            "displayCategory": "Combat",
            "category": null,
            "metadata": {},
            "value": 12728,
            "displayValue": "12,728",
            "displayType": "Unspecified"
          },
          "killsAsKillLeader": {
            "rank": 22,
            "percentile": 99.9,
            "displayName": "Kills As Kill Leader",
            "displayCategory": "Combat",
            "category": null,
            "metadata": {},
            "value": 5764,
            "displayValue": "5,764",
            "displayType": "Unspecified"
          },
          "sniperKills": {
            "rank": 990,
            "percentile": 99.7,
            "displayName": "Sniper Kills",
            "displayCategory": "Weapons",
            "category": null,
            "metadata": {},
            "value": 104,
            "displayValue": "104",
            "displayType": "Unspecified"
          },
          "seasonWins": {
            "rank": 31158,
            "percentile": 92,
            "displayName": "Season 1 Wins",
            "displayCategory": "Game",
            "category": null,
            "metadata": {},
            "value": 24,
            "displayValue": "24",
            "displayType": "Unspecified"
          },
          "seasonDamage": {
            "rank": 5310,
            "percentile": 98.8,
            "displayName": "Season 1 Damage",
            "displayCategory": "Game",
            "category": null,
            "metadata": {},
            "value": 403954,
            "displayValue": "403,954",
            "displayType": "Unspecified"
          }
        }
      },

"expiryDate": "2019-10-04T21:59:04.1270197Z" }

You see I want to get this stats information for each legend and then display their name with whatever data on them is available inside a collection view or tableView. Probably collection view.

Structs used (done with QuickType):

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()
    }
}  

Code used for api call and displaying data:

    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()

        }  

I am unsure how to get this data from the above JSON. The struct only seems to let me pull, let’s say kill stats, from all then legends and doesn’t let me just pull from let’s say pathfinder.

How could I just pull stats on pathfinder?

Ron
  • 161
  • 1
  • 8

1 Answers1

0

You can achieve that as below,

do {
    let store = try JSONDecoder().decode(Store.self, from: data) as Store
    store.data.segments.map{$0.metadata.name}.forEach { legendName in
        if let stats = store.data.segments.first(where: { $0.metadata.name == legendName })?.stats {        
            let killString = stats.kills.displayName + " - " + stats.kills.displayValue
            var damageString: String = ""
            if let damage = stats.damage {
                damageString = damage.displayName + " - " + damage.displayValue
            }
            print(legendName + " " + killString + " " + damageString )
        }
    }
} catch {
    print(error.localizedDescription)
    print(error)

}

Output:

Lifetime Kills - 408 Damage - 74,053
Pathfinder Kills - 230 Damage - 59,694
Gibraltar Kills - 1 
Bangalore Kills - 116 
Octane Kills - 0 
Bloodhound Kills - 6 
Wraith Kills - 18 Damage - 6,357
Mirage Kills - 14 Damage - 5,307
Caustic Kills - 7 Damage - 2,695
Lifeline Kills - 16 
Kamran
  • 14,987
  • 4
  • 33
  • 51