Home > Net >  No value associated with key CodingKeys while trying to get data from GitHub API in Xcode app
No value associated with key CodingKeys while trying to get data from GitHub API in Xcode app

Time:01-07

So listening to @Larme and @JoakimDanielson (thanks a lot, guys!) I started doing some tasks on URLSessions to actually get the data I am looking for from GitHub API.

The endgame here is to create a mobile GitHub search app for repositories.

I have realised a code from this tutorial: https://blog.devgenius.io/how-to-make-http-requests-with-urlsession-in-swift-4dced0287d40

Using relevant GitHub API URL. My code looks like this:

import UIKit

class Repository: Codable {
    let id: Int
    let owner, name, full_name: String

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

    init(id: Int, owner: String, name: String, fullName: String) {
        self.id = id
        self.owner = owner
        self.name = name
        self.full_name = full_name
    }
}

(...)

        let session = URLSession.shared
                let url = URL(string: "https://api.github.com/search/repositories?q=CoreData&per_page=20")!
                let task = session.dataTask(with: url, completionHandler: { data, response, error in
                    // Check the response
                    print(response)
                    
                    // Check if an error occured
                    if error != nil {
                        // HERE you can manage the error
                        print(error)
                        return
                    }
                    
                    // Serialize the data into an object
                    do {
                        let json = try JSONDecoder().decode(Repository.self, from: data! )
                            //try JSONSerialization.jsonObject(with: data!, options: [])
                        print(json)
                    } catch {
                        print("Error during JSON serialization: \(error.localizedDescription)")
                        print(String(describing:error))
                    }
                    
                })
                task.resume()
        
        
    }
    


} 

The full error text is:

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

I tried removing some values that had this error but the others still threw the same and I used the coding keys I could find in the GitHub docs: https://docs.github.com/en/rest/reference/search#search-repositories

Please help!

CodePudding user response:

First of all you don't need CodingKeys and the init method.
Second of all use structs, not classes.

If you want to decode the repositories you have to start with the root object, the repositories are in the array for key items

struct Root : Decodable {
    let items : [Repository]
}

struct Repository: Decodable {
    let id: Int
    let name, fullName: String
    let owner : Owner
}

struct Owner : Decodable {
    let login : String
}

Another issue is that owner is also a Dictionary which becomes another struct.

To get rid of the CodingKeys add the .convertFromSnakeCase strategy which translates full_name into fullName.

let session = URLSession.shared
let url = URL(string: "https://api.github.com/search/repositories?q=CoreData&per_page=20")!
let task = session.dataTask(with: url) { data, response, error in
    // Check the response
    print(response)
    // Check if an error occured
    if let error = error {
        // HERE you can manage the error
        print(error)
        return
    }
    
    // Serialize the data into an object
    do {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let json = try decoder.decode(Root.self, from: data! )
        print(json)
    } catch {
        print("Error during JSON serialization:", error)
    }
}
task.resume()
  •  Tags:  
  • Related