Trabalhando com JSON em Swift: Análise e Serialização
JSON (JavaScript Object Notation) tornou-se o padrão de facto para troca de dados entre cliente e servidor em aplicativos móveis e desktop. No ecossistema Swift (iOS/macOS), o trabalho com JSON é implementado no mais alto nível — desde o simples JSONSerialization até o poderoso protocolo Codable. Neste artigo, abordaremos todas as principais formas de análise e serialização de JSON em Swift, forneceremos exemplos práticos e mostraremos como evitar erros comuns.
1. Fundamentos do Trabalho com JSON em Swift: JSONSerialization
Antes do Swift 4, a principal ferramenta para trabalhar com JSON era a classe JSONSerialization, que faz parte do Foundation. Ela permite converter dados JSON em objetos Swift (dicionários, arrays, strings, números) e vice-versa. Este método continua relevante se você precisar de controle total sobre o processo ou estiver trabalhando com código legado.
Análise de JSON com JSONSerialization
Suponha que recebemos uma string JSON do servidor:
let jsonString = """{ "name": "Ivan", "age": 30, "isPremium": true, "hobbies": ["reading", "running", "programming"]}"""
guard let jsonData = jsonString.data(using: .utf8) else { fatalError("Error encoding string to Data")}
do { if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] { let name = jsonObject["name"] as? String ?? "" let age = jsonObject["age"] as? Int ?? 0 let isPremium = jsonObject["isPremium"] as? Bool ?? false let hobbies = jsonObject["hobbies"] as? [String] ?? [] print("Name: \\(name), Age: \\(age), Premium: \\(isPremium), Hobbies: \\(hobbies)") }} catch { print("JSON parsing error: \\(error.localizedDescription)")}A desvantagem desta abordagem é a necessidade de fazer casting manual de tipos e lidar com valores opcionais. O código se torna verboso e propenso a erros.
Serialização para JSON com JSONSerialization
O processo inverso — converter um dicionário Swift em dados JSON:
let personDict: [String: Any] = [ "name": "Maria", "age": 25, "isPremium": false, "hobbies": ["drawing", "yoga"]]
do { let jsonData = try JSONSerialization.data(withJSONObject: personDict, options: .prettyPrinted) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Serialization error: \\(error.localizedDescription)")}A opção .prettyPrinted torna a saída legível para humanos. Para produção, normalmente se usa [] (sem formatação) para economizar largura de banda.
2. Abordagem Moderna: Protocolo Codable e JSONDecoder
A partir do Swift 4, trabalhar com JSON ficou muito mais fácil graças ao protocolo Codable (que combina Encodable e Decodable). Basta descrever a estrutura de dados, e o compilador gera automaticamente o código para codificação/decodificação.
Análise de JSON com JSONDecoder
Vamos definir um modelo para nosso JSON:
struct Person: Codable { let name: String let age: Int let isPremium: Bool let hobbies: [String]}
let jsonString = """{ "name": "Ivan", "age": 30, "isPremium": true, "hobbies": ["reading", "running", "programming"]}"""
guard let jsonData = jsonString.data(using: .utf8) else { fatalError("Error encoding string")}
do { let person = try JSONDecoder().decode(Person.self, from: jsonData) print("Name: \\(person.name), Age: \\(person.age), Premium: \\(person.isPremium), Hobbies: \\(person.hobbies)")} catch { print("Decoding error: \\(error.localizedDescription)")}Como você pode ver, o código ficou muito mais limpo. Toda a conversão de tipos e verificações