How to use ticketmaster API in swift

197 Views Asked by At

This is the first time I have tried to use an API, I get the error "keyNotFound" Could someone point me in the right direction for understanding this better? Here is a link to their documentation: https://developer.ticketmaster.com/products-and-docs/apis/discovery-api/v2/#anchor_find

let apiKey = "************"
    
    struct EventResponse : Decodable{
        let events : [Event]
    }
    
    struct Event : Decodable{
        let id : String?
    }
    
    func fetchTMEvents() async throws -> [Event]{
        let urlTM = URL(string: "https://app.ticketmaster.com/discovery/v2/events.json?apikey=\(apiKey)")!
        let(data, _) = try await URLSession.shared.data(from: urlTM)
        let decoded = try JSONDecoder().decode(EventResponse.self, from: data)
        return decoded.events
    }
Task {
            do {
                let events = try await fetchTMEvents()
                print("API results \(events)")
            } catch {
                print("API error \(error)")
            }
        }

Full error:

keyNotFound(CodingKeys(stringValue: "events", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "events", intValue: nil) ("events").", underlyingError: nil))

1

There are 1 best solutions below

0
workingdog support Ukraine On BEST ANSWER

Try these test models to fetch then decode the events. The example code in SwiftUI shows how to display the results.

Note, you must have a valid apiKey otherwise the response will not be decodable.

To get the full set of struct models, just copy the json data (all of it) to https://app.quicktype.io/ and the bulk of the code is generated for you. Adjust that code to suit your needs.

You will have to consult the docs to determine which struct/properties are optional, then add ? to them.

struct ContentView: View {
    @State var events: [Event] = []
    
    var body: some View {
        List(events) { event in
            Text(event.name)
        }
        .task {
            do {
                if let results = try await fetchTMEvents() {
                    events = results
                }
            } catch {
                print("---> error: \(error)")
            }
        }
    }
    
    func fetchTMEvents() async throws -> [Event]? {
        let apiKey = "xxxxxxx"
        let urlTM = URL(string: "https://app.ticketmaster.com/discovery/v2/events.json?apikey=\(apiKey)")!
        let(data, _) = try await URLSession.shared.data(from: urlTM)
        // print(String(data: data, encoding: .utf8))
        let decoded = try JSONDecoder().decode(EventResponse.self, from: data)
        return decoded.embedded.events
    }
}

struct EventResponse: Codable {
    let embedded: ResponseEmbedded
    let page: Page

    enum CodingKeys: String, CodingKey {
        case page
        case embedded = "_embedded"
    }
}

struct ResponseEmbedded: Codable {
    let events: [Event]?
}

struct Event: Codable, Identifiable {
    let name, type, id, url, locale: String
}

struct Page: Codable {
    let size, totalElements, totalPages, number: Int
}