No value associated with key CodingKeys

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

ContentView:


import SwiftUI

struct ContentView: View {
    @State private var email = ""
    @State private var password = ""
    @State private var wrongEmail = 0
    @State private var wrongPassword = 0
    @State private var showingLoginScreen = false
    @State private var userData: User? // Declare a @State property for UserData

    
    var body: some View {
        NavigationView {
            ZStack {
                Color.blue
                    .ignoresSafeArea()
                Circle()
                    .scale(1.7)
                    .foregroundColor(.white.opacity(0.15))
                Circle()
                    .scale(1.35)
                    .foregroundColor(.white)
                VStack {
                    Text("Login")
                        .font(.largeTitle)
                        .bold().padding()
                    TextField("Email", text: $email)
                        .padding()
                        .frame(width: 300, height: 50)
                        .background(Color.black.opacity(0.05))
                        .cornerRadius(10)
                        .border(.red, width: CGFloat(wrongEmail))
                    SecureField("Password", text: $password)
                        .padding()
                        .frame(width: 300, height: 50)
                        .background(Color.black.opacity(0.05))
                        .cornerRadius(10)
                        .border(.red, width: CGFloat(wrongPassword))
                    Button("Login") {
                        authenticateUser(email: email, password: password)
                    }
                    .foregroundColor(.white)
                    .frame(width: 300, height: 50)
                    .background(Color.blue)
                    .cornerRadius(10)
                    
                    NavigationLink(
                                destination: ArtworkView(user: userData),
                                isActive: $showingLoginScreen
                            ) {
                                EmptyView()
                            }
//                    NavigationLink(destination: Text("You are logged in @\(email)"), isActive: $showingLoginScreen) {
//                        EmptyView()
//                    }
                }
            }.navigationBarHidden(true)
        }
    }
    func authenticateUser(email: String, password: String) {
        guard  let url = URL(string: "https://api.hangn.art/api/login") else {
            return
        }
        
        print("making api call")
        
        var request = URLRequest(url: url)
        // method, body, headers
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        let body: [String: AnyHashable] = [
            "email": email,
            "password": password
        ]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
        //Make the request
        let task = URLSession.shared.dataTask(with: request) { data, _, error in
            guard let data = data, error == nil else {
                return
            }
            print(String(data: data, encoding: .utf8))
            let decoder = JSONDecoder()
                //decoder.keyDecodingStrategy = .convertFromSnakeCase // Configure snake case decoding
            do {
//                let response = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
                let response = try decoder.decode(LoginResponse.self, from: data)
                            self.userData = response.user
                let userData = try decoder.decode(User.self, from: data)
                print("SUCCESS: \(userData)")
                wrongEmail = 0
                wrongPassword = 0
                showingLoginScreen = true
            }
            catch {
                print("Error parsing response data: \(error)")
                    print("Response data: \(String(data: data, encoding: .utf8) ?? "")")
            }
        }
        task.resume()
    }
}

//struct Response: Codable {
//    let email: String
//    let password: String
//}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}```


ArtworkView:

import SwiftUI

struct ArtworkView: View { var user: User?

    var body: some View {
        if let user = user {
            VStack {
                Text("Name: \(user.firstName) \(user.lastName)")
                Text("Email: \(user.email)")
                Text("Description: \(user.description)")
                // ... display other properties ...
            }
        } else {
            Text("Loading...")
        }
    }

}


User:

import Foundation

struct LoginResponse: Decodable { let token: String let user: User }

struct User: Decodable { let clientId: Int let createdAt: String let description: String let email: String let emailVerifiedAt: String? let firstName: String let id: Int let image: String let lastName: String let location: String? // Make it optional let pmLastFour: String? // Make it optional let pmType: String? // Make it optional let stripeId: String let trialEndsAt: String? // Make it optional let updatedAt: String

// Define custom keys for snake case properties
private enum CodingKeys: String, CodingKey {
        case clientId = "client_id"
        case createdAt = "created_at"
        case description = "description"
        case email = "email"
        case emailVerifiedAt = "email_verified_at"
        case firstName = "first_name"
        case id = "id"
        case image = "image"
        case lastName = "last_name"
        case location = "location"
        case pmLastFour = "pm_last_four"
        case pmType = "pm_type"
        case stripeId = "stripe_id"
        case trialEndsAt = "trial_ends_at"
        case updatedAt = "updatedAt"
    // ... other properties ...
}

}


please help

Replies

Take a look at the data you are receiving from that API. The "updatedAt" property might either be missing or named differently.

You should first format completely the code.

import Foundation

struct LoginResponse: Decodable {
    let token: String
    let user: User
}
struct User: Decodable {
    let clientId: Int
    let createdAt: String
    let description: String
    let email: String
    let emailVerifiedAt: String?
    let firstName: String
    let id: Int
    let image: String
    let lastName: String
    let location: String?
    // Make it optional let pmLastFour: String?
    // Make it optional let pmType: String?
    // Make it optional let stripeId: String let trialEndsAt: String?
    // Make it optional let updatedAt: String
}

Did you really comment out let updatedAt: String

If so, that's likely the cause of error.

If not, please show the json you receive and try to decode.