Serialização de objetos em Swift (iOS/macOS): Codable, JSON e PropertyList
Serialização é o processo de converter objetos de dados em um formato adequado para armazenamento ou transmissão (por exemplo, JSON, XML, Property List). No ecossistema Apple (iOS, macOS, watchOS, tvOS), o Swift fornece um mecanismo poderoso e elegante para serialização e desserialização — o protocolo Codable. Neste artigo, vamos detalhar como usar Codable, JSONEncoder, PropertyListEncoder e seus equivalentes para trabalhar com dados.
O que é Codable?
Codable é um protocolo composto que combina Encodable (para codificar um objeto em um formato externo) e Decodable (para decodificar de um formato externo para um objeto). Se sua estrutura ou classe Swift estiver em conformidade com Codable, você automaticamente obtém a capacidade de serializá-la e desserializá-la.
Declaração básica:
struct User: Codable { let id: Int let name: String let email: String}Todos os tipos padrão do Swift (String, Int, Double, Bool, Date, Data, URL e até tipos opcionais e arrays/dicionários) já estão em conformidade com Codable.
Codificação em JSON
Para codificar um objeto em JSON, usa-se JSONEncoder. Exemplo:
let user = User(id: 1, name: "Ivan Petrov", email: "ivan@example.com")let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // para saída formatada
do { let jsonData = try encoder.encode(user) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Erro de codificação: \\(error)")}Resultado:
{ "id" : 1, "name" : "Ivan Petrov", "email" : "ivan@example.com"}Decodificação de JSON
Para a conversão inversa, usa-se JSONDecoder:
let jsonString = """{ "id": 2, "name": "Maria Sidorova", "email": "maria@example.com"}"""let jsonData = Data(jsonString.utf8)let decoder = JSONDecoder()
do { let decodedUser = try decoder.decode(User.self, from: jsonData) print("Usuário decodificado: \\(decodedUser.name)")} catch { print("Erro de decodificação: \\(error)")}Trabalhando com Property List (plist)
Para serialização no formato XML Property List, usa-se PropertyListEncoder e PropertyListDecoder. Isso é útil para armazenar dados em arquivos de configuração ou UserDefaults.
// Codificação em plistlet encoder = PropertyListEncoder()encoder.outputFormat = .xml
do { let plistData = try encoder.encode(user) // plistData pode ser salvo em um arquivo ou UserDefaults} catch { print("Erro de codificação plist: \\(error)")}
// Decodificação de plistlet decoder = PropertyListDecoder()do { let decodedUser = try decoder.decode(User.self, from: plistData) print(decodedUser)} catch { print("Erro de decodificação plist: \\(error)")}Chaves personalizadas (CodingKeys)
Às vezes, os nomes das propriedades em Swift não correspondem às chaves no JSON. Para isso, usa-se a enumeração CodingKeys:
struct Product: Codable { let productId: Int let productName: String let price: Double
enum CodingKeys: String, CodingKey { case productId = "product_id" case productName = "product_name" case price }}Agora, o JSON com as chaves product_id e product_name será processado corretamente.
Tratamento de datas e outros tipos especiais
Por padrão, JSONEncoder e JSONDecoder codificam datas como TimeInterval
Também na biblioteca
Multer para JavaScript (Node.js): guia completo com exemplos práticos
Contêiner de Injeção de Dependência para Kotlin: Koin vs Kodein vs Dagger
Envio de SMS em Java: visão geral de bibliotecas e ferramentas de API
Cliente HTTP para C++: as melhores bibliotecas para trabalhar com rede