Black November

ATÉ 50% OFF

TÁ ACABANDO!

0 dias

0 horas

0 min

0 seg

2
respostas

[Dúvida] Erro ao cadastrar usuário

Quando eu clico no botão de cadastrar o paciente, o catch retorna um erro:

Houve um erro ao cadastrar paciente keyNotFound(CodingKeys(stringValue: "nome", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"nome\", intValue: nil) (\"nome\").", underlyingError: nil))

Já verifiquei se minhas CodingKeys estão de acordo com o retorno da API, mas não sei mais o que pode estar causando esse erro

struct Paciente

//
//  Patient.swift
//  Vollmed
//
//  Created by Juan Carlos Parizotto da Silva  on 24/11/25.
//

import Foundation

struct Patient: Identifiable, Codable {
    let id: String?
    let name: String
    let email: String
    let password: String
    let cpf: String
    let phoneNumber: String
    let healthPlan: String
    
    enum CodingKeys : String, CodingKey {
        case id
        case name = "nome"
        case email
        case password = "senha"
        case cpf
        case phoneNumber = "telefone"
        case healthPlan = "planoSaude"
    }
}

WebService

struct WebService {
    
    private let baseURL = "http://localhost:3000"
    private let imageCache = NSCache<NSString, UIImage>()
    
    func registerPatient(_ patient: Patient) async throws -> Patient? {
        let endpoint = baseURL + "/paciente"
        
        guard let url = URL(string: endpoint) else {
            print("Erro ao buscar URL")
            return nil
        }
        
        let jsonData = try JSONEncoder().encode(patient)

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData
        
        let (data, _) = try await URLSession.shared.data(for: request)
        
        let patient = try JSONDecoder().decode(Patient.self, from: data)
        
        return patient
    }
    [...]

Matricule-se agora e aproveite até 50% OFF

O maior desconto do ano para você evoluir com a maior escola de tecnologia

QUERO APROVEITAR
2 respostas

Olá Juan.
Vou dar algumas sugestões que podem ajudar.
Confere ai:
O erro diz:

keyNotFound(CodingKeys(stringValue: "nome", intValue: nil)
"No value associated with key 'nome'"

Isso significa que a resposta da sua API NO POST não contém o campo nome.
Mas seu modelo Patient OBRIGA esse campo (let name: String).
Então na hora de decodificar o retorno da API, o Swift tenta achar "nome" (porque seu CodingKeys mapeia name = "nome") ,mas a chave não existe na resposta JSON, e aí o decode falha.
Antes do decode, coloque:

print(String(data: data, encoding: .utf8)!)

Isso vai mostrar a resposta exata que sua API está retornando.
MUITO provavelmente vai ser algo assim:

{
  "id": "123"
}

Ou:

{
  "message": "Paciente criado com sucesso"
}

Ou outro JSON sem o campo nome.

Como corrigir

  • Ajustar o modelo de retorno (recomendado)
    A resposta do backend após um POST normalmente não retorna o mesmo objeto completo.
    Então crie um modelo APENAS para a resposta:
struct PatientResponse: Codable {
    let id: String?
    let message: String?
}

E no registerPatient decodifique assim:

let response = try JSONDecoder().decode(PatientResponse.self, from: data)
return nil  // ou retorne response, caso precise
  • Deixar campos opcionais
    Se quiser continuar usando Patient, torne as propriedades opcionais para permitir decodificação parcial:
struct Patient: Identifiable, Codable {
    let id: String?
    let name: String?
    let email: String?
    let password: String?
    let cpf: String?
    let phoneNumber: String?
    let healthPlan: String?
}

Mas isso não é ideal, pois agora seu modelo fica “fraco”.

  • Não tentar decodificar nada (se não precisar)
    Se você só quer saber se deu certo:
_ = try await URLSession.shared.data(for: request)
return nil

Ou:

let (_, response) = try await URLSession.shared.data(for: request)

if let httpResponse = response as? HTTPURLResponse {
    print("Status: \(httpResponse.statusCode)")
}

Você está enviando corretamente o JSON no POST.
O PROBLEMA está no JSON que a API devolve, não no que você envia.
O decode falha porque o retorno NÃO possui a chave "nome".
Teste ai e avise o resultado.
Bons estudos.

Opa Ronaldo, obrigado por responder. Ainda não testei suas recomendações, mas vou fazer
Tu disse que a API não retorna a chave "nome", mas isso que me causa mais dúvida, porque quando eu testo registrar um novo paciente pelo Postman a API devolve o JSON:

{
    "cpf": "11111111111",
    "nome": "Juan 2",        // <----- o campo "nome"
    "email": "juan2@email.com",
    "senha": "9e9c2945e5bf948581961943a0c4a1fe:c6d915b2e4b481d6b60348a3f173c9c5",
    "telefone": 99999999,
    "planoSaude": "Unimed",
    "id": "ff09e37f-f784-4afa-8b31-c7d6014bdc12"
}

Por isso acho estranho, porque a API retorna sim o campo "nome". porém continua retornando como se estivesse errado. Você teria alguma recomendação sabendo disso agora?