🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Exemplos de Serialização macOS Swift
Exemplos de serialização macOS Swift incluindo serialização JSON, desserialização e análise XML
💻 Serialização JSON swift
🟢 simple
⭐⭐
Serializar objetos Swift para JSON usando Codable e JSONSerialization
⏱️ 25 min
🏷️ swift, macos, serialization, json
Prerequisites:
Basic Swift knowledge, Codable protocol
// macOS Swift JSON Serialization Examples
// Using Foundation framework
import Foundation
// 1. Basic JSON Serialization with Codable
struct User: Codable {
let id: Int
let username: String
let email: String
let age: Int
let isActive: Bool
}
class BasicJSONSerialization {
static func serializeUser() {
print("\n--- Basic JSON Serialization ---")
let user = User(
id: 1,
username: "john_doe",
email: "[email protected]",
age: 30,
isActive: true
)
// Serialize to JSON
do {
let jsonData = try JSONEncoder().encode(user)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Serialized JSON:")
print(jsonString)
}
// Also print as pretty JSON
let json = try JSONSerialization.jsonObject(with: jsonData)
let prettyData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
if let prettyString = String(data: prettyData, encoding: .utf8) {
print("\nPretty printed:")
print(prettyString)
}
} catch {
print("Error serializing: \(error)")
}
}
}
// 2. JSON Serialization with Options
class JSONSerializationWithOptions {
static void serializeWithOptions() {
print("\n--- JSON Serialization with Options ---")
let user = User(id: 1, username: "jane", email: "[email protected]", age: 25, isActive: false)
// Custom encoder
let encoder = JSONEncoder()
// Pretty print
encoder.outputFormatting = .prettyPrinted
// Sorted keys
encoder.outputFormatting.insert(.sortedKeys)
// Without escaping slashes
encoder.outputFormatting.insert(.withoutEscapingSlashes)
do {
let jsonData = try encoder.encode(user)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("JSON with options:")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
// Minimal encoding
encoder.outputFormatting = []
do {
let jsonData = try encoder.encode(user)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("\nMinimal JSON (no whitespace):")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
}
}
// 3. Serialize Array of Objects
class SerializeArray {
static void serializeArray() {
print("\n--- Serialize Array of Objects ---")
let users = [
User(id: 1, username: "john", email: "[email protected]", age: 30, isActive: true),
User(id: 2, username: "jane", email: "[email protected]", age: 25, isActive: true),
User(id: 3, username: "bob", email: "[email protected]", age: 35, isActive: false)
]
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(users)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Serialized array:")
print(jsonString)
}
// Get array size
print("\nArray size: \(users.count) users")
print("JSON size: \(jsonData.count) bytes")
} catch {
print("Error: \(error)")
}
}
}
// 4. Serialize Dictionary
class SerializeDictionary {
static void serializeDictionary() {
print("\n--- Serialize Dictionary ---")
let userDict: [String: Any] = [
"id": 1,
"username": "john_doe",
"email": "[email protected]",
"age": 30,
"isActive": true,
"tags": ["admin", "user"],
"metadata": [
"created": "2024-01-15",
"updated": "2024-01-20"
] as [String: Any]
]
do {
let jsonData = try JSONSerialization.data(withJSONObject: userDict, options: .prettyPrinted)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Serialized dictionary:")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
}
}
// 5. Custom Key Encoding
struct Employee: Codable {
let firstName: String
let lastName: String
let employeeId: Int
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case employeeId = "employee_id"
}
}
class CustomKeyEncoding {
static void serializeWithCustomKeys() {
print("\n--- Custom Key Encoding ---")
let employee = Employee(
firstName: "John",
lastName: "Doe",
employeeId: 12345
)
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(employee)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Serialized with custom keys:")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
}
}
// 6. Serialize with Date Encoding
struct Event: Codable {
let name: String
let date: Date
let attendees: Int
}
class DateEncoding {
static void serializeWithDate() {
print("\n--- Serialize with Date Encoding ---")
let event = Event(
name: "Conference",
date: Date(),
attendees: 150
)
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
// Default date encoding (seconds since 1970)
encoder.dateEncodingStrategy = .deferredToDate
let jsonData = try encoder.encode(event)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Default date encoding:")
print(jsonString)
}
// ISO 8601 date encoding
encoder.dateEncodingStrategy = .iso8601
let isoData = try encoder.encode(event)
if let isoString = String(data: isoData, encoding: .utf8) {
print("\nISO 8601 date encoding:")
print(isoString)
}
// Custom date formatting
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
encoder.dateEncodingStrategy = .formatted(formatter)
let customData = try encoder.encode(event)
if let customString = String(data: customData, encoding: .utf8) {
print("\nCustom date format:")
print(customString)
}
} catch {
print("Error: \(error)")
}
}
}
// 7. Serialize Nested Objects
struct Address: Codable {
let street: String
let city: String
let state: String
let zipCode: String
}
struct Person: Codable {
let name: String
let age: Int
let address: Address
let phoneNumbers: [String]
}
class NestedSerialization {
static void serializeNested() {
print("\n--- Serialize Nested Objects ---")
let person = Person(
name: "John Doe",
age: 30,
address: Address(
street: "123 Main St",
city: "New York",
state: "NY",
zipCode: "10001"
),
phoneNumbers: ["555-1234", "555-5678"]
)
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(person)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("Serialized nested object:")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
}
}
// 8. Conditional Encoding
struct Product: Codable {
let id: Int
let name: String
let price: Double
let discountPrice: Double?
// Encode only if there's a discount
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(price, forKey: .price)
if let discount = discountPrice {
try container.encode(discount, forKey: .discountPrice)
}
}
enum CodingKeys: String, CodingKey {
case id, name, price, discountPrice
}
}
class ConditionalEncoding {
static void demonstrateConditionalEncoding() {
print("\n--- Conditional Encoding ---")
let productWithDiscount = Product(id: 1, name: "Widget", price: 99.99, discountPrice: 79.99)
let productWithoutDiscount = Product(id: 2, name: "Gadget", price: 49.99, discountPrice: nil)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let data1 = try encoder.encode(productWithDiscount)
let data2 = try encoder.encode(productWithoutDiscount)
print("Product with discount:")
if let json1 = String(data: data1, encoding: .utf8) {
print(json1)
}
print("\nProduct without discount:")
if let json2 = String(data: data2, encoding: .utf8) {
print(json2)
}
} catch {
print("Error: \(error)")
}
}
}
// 9. Serialize to File
class SerializeToFile {
static void serializeToFile() {
print("\n--- Serialize to File ---")
let user = User(id: 1, username: "john_doe", email: "[email protected]", age: 30, isActive: true)
let filePath = "/tmp/user.json"
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(user)
// Write to file
try jsonData.write(to: URL(fileURLWithPath: filePath))
print("JSON written to file: \(filePath)")
// Read file size
let attributes = try FileManager.default.attributesOfItem(atPath: filePath)
if let fileSize = attributes[.size] as? UInt64 {
print("File size: \(fileSize) bytes")
}
// Read and verify
let readData = try Data(contentsOf: URL(fileURLWithPath: filePath))
if let jsonString = String(data: readData, encoding: .utf8) {
print("\nFile contents:")
print(jsonString)
}
} catch {
print("Error: \(error)")
}
}
}
// 10. Streaming JSON Serialization
class StreamingSerialization {
static void streamArrayToJSON() {
print("\n--- Streaming JSON Serialization ---")
// Create large array
let users = (1...100).map { i in
User(id: i, username: "user\(i)", email: "user\(i)@test.com", age: 20 + i % 50, isActive: i % 2 == 0)
}
print("Streaming \(users.count) users to JSON...")
do {
let encoder = JSONEncoder()
// Encode to data
let startTime = Date()
let jsonData = try encoder.encode(users)
let elapsed = Date().timeIntervalSince(startTime)
print("Encoded \(jsonData.count) bytes in \(elapsed) seconds")
// Show first 500 characters
if let jsonString = String(data: jsonData, encoding: .utf8) {
print("\nFirst 500 characters:")
print(String(jsonString.prefix(500)))
}
} catch {
print("Error: \(error)")
}
}
static void writeStreamToFile(_ items: [User], filePath: String) {
print("\n--- Write Stream to File ---")
do {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(items)
try jsonData.write(to: URL(fileURLWithPath: filePath))
print("Wrote \(items.count) items to \(filePath)")
let attributes = try FileManager.default.attributesOfItem(atPath: filePath)
if let fileSize = attributes[.size] as? UInt64 {
print("File size: \(fileSize) bytes")
}
} catch {
print("Error: \(error)")
}
}
}
// Main demonstration
func demonstrateJSONSerialization() {
print("=== macOS Swift JSON Serialization Examples ===")
BasicJSONSerialization.serializeUser()
JSONSerializationWithOptions.serializeWithOptions()
SerializeArray.serializeArray()
SerializeDictionary.serializeDictionary()
CustomKeyEncoding.serializeWithCustomKeys()
DateEncoding.serializeWithDate()
NestedSerialization.serializeNested()
ConditionalEncoding.demonstrateConditionalEncoding()
SerializeToFile.serializeToFile()
StreamingSerialization.streamArrayToJSON()
let users = (1...50).map { i in
User(id: i, username: "stream\(i)", email: "stream\(i)@test.com", age: 20 + i, isActive: true)
}
StreamingSerialization.writeStreamToFile(users, filePath: "/tmp/users_stream.json")
print("\n=== All JSON Serialization Examples Completed ===")
}
// Run demonstration
demonstrateJSONSerialization()
💻 Desserialização JSON swift
🟡 intermediate
⭐⭐⭐
Desserializar dados JSON em objetos Swift usando Codable e JSONDecoder
⏱️ 30 min
🏷️ swift, macos, serialization, json
Prerequisites:
Intermediate Swift, Codable protocol, Error handling
// macOS Swift JSON Deserialization Examples
// Using Foundation framework
import Foundation
// 1. Basic JSON Deserialization
struct User: Codable {
let id: Int
let username: String
let email: String
let age: Int
let isActive: Bool
}
class BasicJSONDeserialization {
static void deserializeUser() {
print("\n--- Basic JSON Deserialization ---")
let jsonString = """
{
"id": 1,
"username": "john_doe",
"email": "[email protected]",
"age": 30,
"isActive": true
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let user = try JSONDecoder().decode(User.self, from: jsonData)
print("Decoded user:")
print(" ID: \(user.id)")
print(" Username: \(user.username)")
print(" Email: \(user.email)")
print(" Age: \(user.age)")
print(" Active: \(user.isActive)")
} catch {
print("Error decoding: \(error)")
}
}
}
}
// 2. Deserialize Array
class DeserializeArray {
static void deserializeArray() {
print("\n--- Deserialize Array ---")
let jsonArray = """
[
{
"id": 1,
"username": "john",
"email": "[email protected]",
"age": 30,
"isActive": true
},
{
"id": 2,
"username": "jane",
"email": "[email protected]",
"age": 25,
"isActive": true
},
{
"id": 3,
"username": "bob",
"email": "[email protected]",
"age": 35,
"isActive": false
}
]
"""
if let jsonData = jsonArray.data(using: .utf8) {
do {
let users = try JSONDecoder().decode([User].self, from: jsonData)
print("Decoded \(users.count) users:")
for user in users {
print(" \(user.username) - \(user.email)")
}
} catch {
print("Error decoding: \(error)")
}
}
}
}
// 3. Deserialize from File
class DeserializeFromFile {
static void deserializeFromFile() {
print("\n--- Deserialize from File ---")
// First, create a file
let filePath = "/tmp/users_read.json"
let users = [
User(id: 1, username: "alice", email: "[email protected]", age: 28, isActive: true),
User(id: 2, username: "bob", email: "[email protected]", age: 32, isActive: false)
]
// Write to file first
if let jsonData = try? JSONEncoder().encode(users) {
try? jsonData.write(to: URL(fileURLWithPath: filePath))
print("Created test file: \(filePath)")
}
// Now read from file
if let jsonData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) {
do {
let decoder = JSONDecoder()
let decodedUsers = try decoder.decode([User].self, from: jsonData)
print("\nDecoded from file:")
for user in decodedUsers {
print(" \(user.username) (\(user.age))")
}
} catch {
print("Error: \(error)")
}
}
}
}
// 4. Custom Key Decoding
struct Employee: Codable {
let firstName: String
let lastName: String
let employeeId: Int
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case employeeId = "employee_id"
}
}
class CustomKeyDecoding {
static void deserializeWithCustomKeys() {
print("\n--- Custom Key Decoding ---")
let jsonString = """
{
"first_name": "John",
"last_name": "Doe",
"employee_id": 12345
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let employee = try JSONDecoder().decode(Employee.self, from: jsonData)
print("Decoded employee:")
print(" First Name: \(employee.firstName)")
print(" Last Name: \(employee.lastName)")
print(" Employee ID: \(employee.employeeId)")
} catch {
print("Error: \(error)")
}
}
}
}
// 5. Date Decoding
struct Event: Codable {
let name: String
let date: Date
let attendees: Int
}
class DateDecoding {
static void deserializeWithDate() {
print("\n--- Date Decoding ---")
// Default Unix timestamp
let unixJson = """
{
"name": "Conference",
"date": 1705330800,
"attendees": 150
}
"""
print("Decoding Unix timestamp:")
if let jsonData = unixJson.data(using: .utf8) {
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .deferredToDate
let event = try decoder.decode(Event.self, from: jsonData)
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
print(" Event: \(event.name)")
print(" Date: \(formatter.string(from: event.date))")
print(" Attendees: \(event.attendees)")
} catch {
print("Error: \(error)")
}
}
// ISO 8601 format
let isoJson = """
{
"name": "Meeting",
"date": "2024-01-15T10:30:00Z",
"attendees": 10
}
"""
print("\nDecoding ISO 8601:")
if let jsonData = isoJson.data(using: .utf8) {
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let event = try decoder.decode(Event.self, from: jsonData)
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
print(" Event: \(event.name)")
print(" Date: \(formatter.string(from: event.date))")
} catch {
print("Error: \(error)")
}
}
// Custom date format
let customJson = """
{
"name": "Party",
"date": "2024-01-15 22:00:00",
"attendees": 50
}
"""
print("\nDecoding custom date format:")
if let jsonData = customJson.data(using: .utf8) {
do {
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(formatter)
let event = try decoder.decode(Event.self, from: jsonData)
print(" Event: \(event.name)")
print(" Date: \(event.date)")
} catch {
print("Error: \(error)")
}
}
}
}
// 6. Nested Object Decoding
struct Address: Codable {
let street: String
let city: String
let state: String
let zipCode: String
}
struct Person: Codable {
let name: String
let age: Int
let address: Address
let phoneNumbers: [String]
}
class NestedDecoding {
static void deserializeNested() {
print("\n--- Nested Object Decoding ---")
let jsonString = """
{
"name": "John Doe",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zipCode": "10001"
},
"phoneNumbers": ["555-1234", "555-5678"]
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let person = try JSONDecoder().decode(Person.self, from: jsonData)
print("Decoded person:")
print(" Name: \(person.name)")
print(" Age: \(person.age)")
print(" Address:")
print(" Street: \(person.address.street)")
print(" City: \(person.address.city)")
print(" State: \(person.address.state)")
print(" ZIP: \(person.address.zipCode)")
print(" Phone numbers: \(person.phoneNumbers.joined(separator: ", "))")
} catch {
print("Error: \(error)")
}
}
}
}
// 7. Handling Missing Fields
struct OptionalUser: Codable {
let id: Int
let username: String
let email: String?
let age: Int?
let bio: String?
}
class OptionalFieldsDecoding {
static void deserializeOptionalFields() {
print("\n--- Handling Missing/Optional Fields ---")
let jsonString = """
{
"id": 1,
"username": "john_doe"
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let user = try JSONDecoder().decode(OptionalUser.self, from: jsonData)
print("Decoded user with optional fields:")
print(" ID: \(user.id)")
print(" Username: \(user.username)")
print(" Email: \(user.email ?? "Not provided")")
print(" Age: \(user.age?.description ?? "Not provided")")
print(" Bio: \(user.bio ?? "Not provided")")
} catch {
print("Error: \(error)")
}
}
}
}
// 8. Error Handling
class ErrorHandling {
static void handleDecodingErrors() {
print("\n--- Decoding Error Handling ---")
// Invalid JSON
let invalidJson = "{ invalid json }"
print("1. Invalid JSON:")
if let jsonData = invalidJson.data(using: .utf8) {
do {
_ = try JSONDecoder().decode(User.self, from: jsonData)
} catch let DecodingError.dataCorrupted(context) {
print(" Data corrupted: \(context)")
} catch let DecodingError.keyNotFound(key, context) {
print(" Key not found: \(key) - \(context)")
} catch let DecodingError.typeMismatch(type, context) {
print(" Type mismatch: \(type) - \(context)")
} catch let DecodingError.valueNotFound(type, context) {
print(" Value not found: \(type) - \(context)")
} catch {
print(" Other error: \(error)")
}
}
// Missing required field
let incompleteJson = """
{
"id": 1,
"username": "john"
}
"""
print("\n2. Missing required field:")
if let jsonData = incompleteJson.data(using: .utf8) {
do {
_ = try JSONDecoder().decode(User.self, from: jsonData)
} catch {
print(" Error: \(error.localizedDescription)")
}
}
// Wrong type
let wrongTypeJson = """
{
"id": "not_a_number",
"username": "john",
"email": "[email protected]",
"age": 30,
"isActive": true
}
"""
print("\n3. Wrong type:")
if let jsonData = wrongTypeJson.data(using: .utf8) {
do {
_ = try JSONDecoder().decode(User.self, from: jsonData)
} catch {
print(" Error: \(error.localizedDescription)")
}
}
}
}
// 9. Partial Decoding
class PartialDecoding {
static void partialDecode() {
print("\n--- Partial Decoding ---")
let jsonString = """
{
"id": 1,
"username": "john_doe",
"email": "[email protected]",
"age": 30,
"isActive": true,
"metadata": {
"created": "2024-01-15",
"updated": "2024-01-20"
},
"settings": {
"theme": "dark",
"notifications": true
}
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
// Decode only the User part
let user = try JSONDecoder().decode(User.self, from: jsonData)
print("Partially decoded user:")
print(" Username: \(user.username)")
print(" Email: \(user.email)")
// Decode entire JSON to dictionary
if let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {
print("\nFull JSON available for other fields:")
if let metadata = json["metadata"] as? [String: String] {
print(" Created: \(metadata["created"] ?? "")")
print(" Updated: \(metadata["updated"] ?? "")")
}
}
} catch {
print("Error: \(error)")
}
}
}
}
// 10. Streaming JSON Parsing
class StreamingParsing {
static void streamJSONArray() {
print("\n--- Streaming JSON Parsing ---")
// Simulate large JSON array
let largeArray = (1...1000).map { i in
[
"id": i,
"username": "user\(i)",
"email": "user\(i)@test.com",
"age": 20 + i % 50,
"isActive": i % 2 == 0
] as [String: Any]
}
guard let jsonData = try? JSONSerialization.data(withJSONObject: largeArray) else {
return
}
print("Parsing \(jsonData.count) bytes of JSON...")
let startTime = Date()
do {
let users = try JSONDecoder().decode([User].self, from: jsonData)
let elapsed = Date().timeIntervalSince(startTime)
print("Parsed \(users.count) users in \(elapsed) seconds")
print("First user: \(users.first?.username ?? "")")
print("Last user: \(users.last?.username ?? "")")
} catch {
print("Error: \(error)")
}
}
static void parseChunkedJSON() {
print("\n--- Parse Chunked JSON ---")
let jsonString = """
{"users": [
{"id": 1, "username": "john", "email": "[email protected]", "age": 30, "isActive": true},
{"id": 2, "username": "jane", "email": "[email protected]", "age": 25, "isActive": true},
{"id": 3, "username": "bob", "email": "[email protected]", "age": 35, "isActive": false}
]}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let decoder = JSONDecoder()
// Parse as dictionary first
if let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let usersArray = json["users"] as? [[String: Any]] {
print("Parsed \(usersArray.count) users")
// Then decode each user
for userDict in usersArray {
if let userData = try? JSONSerialization.data(withJSONObject: userDict),
let user = try? decoder.decode(User.self, from: userData) {
print(" \(user.username)")
}
}
}
} catch {
print("Error: \(error)")
}
}
}
}
// 11. Dynamic Decoding
class DynamicDecoding {
static void decodeDynamicJSON() {
print("\n--- Dynamic JSON Decoding ---")
let jsonString = """
{
"type": "user",
"data": {
"id": 1,
"username": "john_doe",
"email": "[email protected]",
"age": 30,
"isActive": true
}
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
if let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any],
let type = json["type"] as? String,
let data = json["data"] as? [String: Any] {
print("Type: \(type)")
// Decode based on type
if type == "user" {
let userData = try JSONSerialization.data(withJSONObject: data)
let user = try JSONDecoder().decode(User.self, from: userData)
print("User: \(user.username)")
}
}
} catch {
print("Error: \(error)")
}
}
}
}
// Main demonstration
func demonstrateJSONDeserialization() {
print("=== macOS Swift JSON Deserialization Examples ===")
BasicJSONDeserialization.deserializeUser()
DeserializeArray.deserializeArray()
DeserializeFromFile.deserializeFromFile()
CustomKeyDecoding.deserializeWithCustomKeys()
DateDecoding.deserializeWithDate()
NestedDecoding.deserializeNested()
OptionalFieldsDecoding.deserializeOptionalFields()
ErrorHandling.handleDecodingErrors()
PartialDecoding.partialDecode()
StreamingParsing.streamJSONArray()
StreamingParsing.parseChunkedJSON()
DynamicDecoding.decodeDynamicJSON()
print("\n=== All JSON Deserialization Examples Completed ===")
}
// Run demonstration
demonstrateJSONDeserialization()
💻 Análise XML swift
🟡 intermediate
⭐⭐⭐
Analisar documentos XML usando XMLParser e converter em objetos Swift
⏱️ 35 min
🏷️ swift, macos, serialization, xml
Prerequisites:
Intermediate Swift, XMLParser, Delegate pattern
// macOS Swift XML Parsing Examples
// Using Foundation framework
import Foundation
// 1. Basic XML Parsing
class BasicXMLParser: NSObject, XMLParserDelegate {
var currentElement: String = ""
var foundCharacters: String = ""
func parseXML(xmlString: String) {
print("\n--- Basic XML Parsing ---")
guard let data = xmlString.data(using: .utf8) else {
print("Invalid XML string")
return
}
let parser = XMLParser(data: data)
parser.delegate = self
print("Parsing XML:")
if parser.parse() {
print("XML parsed successfully")
} else {
print("XML parsing failed: \(parser.parserError?.localizedDescription ?? "")")
}
}
// Delegate methods
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
currentElement = elementName
foundCharacters = ""
print("Started element: \(elementName)")
if !attributeDict.isEmpty {
print(" Attributes: \(attributeDict)")
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
foundCharacters += string
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
let trimmed = foundCharacters.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
print(" \(elementName): \(trimmed)")
}
currentElement = ""
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print("Parse error: \(parseError)")
}
}
// 2. Parse XML to Object
struct Book {
let title: String
let author: String
let year: String
let price: Double
}
class BookParser: NSObject, XMLParserDelegate {
var books: [Book] = []
var currentElement: String = ""
var currentTitle: String = ""
var currentAuthor: String = ""
var currentYear: String = ""
var currentPrice: String = ""
func parseBooks(xmlString: String) -> [Book] {
print("\n--- Parse XML to Objects ---")
guard let data = xmlString.data(using: .utf8) else {
return []
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
print("Parsed \(books.count) books")
return books
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
currentElement = elementName
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
switch currentElement {
case "title":
currentTitle = trimmed
case "author":
currentAuthor = trimmed
case "year":
currentYear = trimmed
case "price":
currentPrice = trimmed
default:
break
}
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "book" {
let price = Double(currentPrice) ?? 0.0
let book = Book(title: currentTitle, author: currentAuthor, year: currentYear, price: price)
books.append(book)
print(" Book: \(book.title) by \(book.author) - $\(book.price)")
// Reset
currentTitle = ""
currentAuthor = ""
currentYear = ""
currentPrice = ""
}
}
}
// 3. Parse XML with Attributes
struct Product {
let id: String
let category: String
let name: String
let price: Double
}
class ProductParser: NSObject, XMLParserDelegate {
var products: [Product] = []
var currentElement: String = ""
var currentId: String = ""
var currentCategory: String = ""
var currentName: String = ""
var currentPrice: String = ""
func parseProducts(xmlString: String) -> [Product] {
print("\n--- Parse XML with Attributes ---")
guard let data = xmlString.data(using: .utf8) else {
return []
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
print("Parsed \(products.count) products")
return products
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
currentElement = elementName
if elementName == "product" {
currentId = attributeDict["id"] ?? ""
currentCategory = attributeDict["category"] ?? ""
print(" Found product: id=\(currentId), category=\(currentCategory)")
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
switch currentElement {
case "name":
currentName = trimmed
case "price":
currentPrice = trimmed
default:
break
}
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "product" {
let price = Double(currentPrice) ?? 0.0
let product = Product(id: currentId, category: currentCategory, name: currentName, price: price)
products.append(product)
// Reset
currentId = ""
currentCategory = ""
currentName = ""
currentPrice = ""
}
}
}
// 4. Parse Nested XML
struct Address {
let street: String
let city: String
let state: String
let zip: String
}
struct Person {
let name: String
let age: Int
let address: Address
}
class PersonParser: NSObject, XMLParserDelegate {
var people: [Person] = []
var currentElement: String = ""
var currentName: String = ""
var currentAge: String = ""
var currentStreet: String = ""
var currentCity: String = ""
var currentState: String = ""
var currentZip: String = ""
var inAddress = false
func parsePeople(xmlString: String) -> [Person] {
print("\n--- Parse Nested XML ---")
guard let data = xmlString.data(using: .utf8) else {
return []
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
print("Parsed \(people.count) people")
return people
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
currentElement = elementName
if elementName == "address" {
inAddress = true
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty {
if inAddress {
switch currentElement {
case "street":
currentStreet = trimmed
case "city":
currentCity = trimmed
case "state":
currentState = trimmed
case "zip":
currentZip = trimmed
default:
break
}
} else {
switch currentElement {
case "name":
currentName = trimmed
case "age":
currentAge = trimmed
default:
break
}
}
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "address" {
inAddress = false
}
if elementName == "person" {
let age = Int(currentAge) ?? 0
let address = Address(street: currentStreet, city: currentCity, state: currentState, zip: currentZip)
let person = Person(name: currentName, age: age, address: address)
people.append(person)
print(" Person: \(person.name) from \(person.address.city)")
// Reset
currentName = ""
currentAge = ""
currentStreet = ""
currentCity = ""
currentState = ""
currentZip = ""
}
}
}
// 5. Parse XML from File
class FileXMLParser {
static void parseXMLFromFile(filePath: String) {
print("\n--- Parse XML from File ---")
// First, create a sample XML file
let sampleXML = """
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book>
<title>Swift Programming</title>
<author>John Smith</author>
<year>2024</year>
<price>49.99</price>
</book>
<book>
<title>iOS Development</title>
<author>Jane Doe</author>
<year>2023</year>
<price>39.99</price>
</book>
</catalog>
"""
try? sampleXML.write(to: URL(fileURLWithPath: filePath), atomically: true, encoding: .utf8)
print("Created sample XML file: \(filePath)")
// Parse from file
guard let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
print("Could not read file")
return
}
let parser = XMLParser(data: data)
let bookParser = BookParser()
parser.delegate = bookParser
if parser.parse() {
print("\nSuccessfully parsed from file")
}
}
}
// 6. Parse XML with Namespaces
class NamespaceParser: NSObject, XMLParserDelegate {
func parseWithNamespaces(xmlString: String) {
print("\n--- Parse XML with Namespaces ---")
guard let data = xmlString.data(using: .utf8) else {
return
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.shouldProcessNamespaces = true
parser.parse()
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
print("Element: \(elementName)")
if let uri = namespaceURI {
print(" Namespace URI: \(uri)")
}
if let qname = qName {
print(" Qualified name: \(qname)")
}
}
func parser(_ parser: XMLParser, didStartMappingPrefix prefix: String, toURI namespaceURI: String) {
print("Namespace mapping: \(prefix) -> \(namespaceURI)")
}
}
// 7. Parse Large XML with Streaming
class StreamingXMLParser: NSObject, XMLParserDelegate {
var elementCount = 0
var maxElements = 0
func parseStreaming(xmlString: String, maxElements: Int = 10) {
print("\n--- Streaming XML Parsing ---")
self.maxElements = maxElements
elementCount = 0
guard let data = xmlString.data(using: .utf8) else {
return
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
print("Processed \(elementCount) elements (stopped at \(maxElements))")
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
elementCount += 1
if elementCount <= maxElements {
print(" Element \(elementCount): \(elementName)")
}
if elementCount >= maxElements {
parser.abortParsing()
}
}
}
// 8. Parse XML with CDATA
class CDATAParser: NSObject, XMLParserDelegate {
func parseWithCDATA(xmlString: String) {
print("\n--- Parse XML with CDATA ---")
guard let data = xmlString.data(using: .utf8) else {
return
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
}
func parser(_ parser: XMLParser, foundCDATA CDATABlock: Data) {
if let cdataString = String(data: CDATABlock, encoding: .utf8) {
print("Found CDATA:")
print(" \(cdataString)")
}
}
}
// 9. XML to Dictionary Conversion
class XMLToDictionary {
static void convertToDictionary(xmlString: String) -> [String: Any]? {
print("\n--- XML to Dictionary Conversion ---")
guard let data = xmlString.data(using: .utf8) else {
return nil
}
do {
let plist = try PropertyListSerialization.propertyList(from: data, options: [], format: nil)
if let dict = plist as? [String: Any] {
print("Converted to dictionary:")
print(dict)
return dict
}
} catch {
print("Error: \(error)")
}
return nil
}
}
// 10. Parse RSS Feed
struct RSSItem {
let title: String
let link: String
let description: String
let pubDate: String
}
class RSSParser: NSObject, XMLParserDelegate {
var items: [RSSItem] = []
var currentElement: String = ""
var currentTitle: String = ""
var currentLink: String = ""
var currentDescription: String = ""
var currentPubDate: String = ""
var inItem = false
func parseRSS(xmlString: String) -> [RSSItem] {
print("\n--- Parse RSS Feed ---")
guard let data = xmlString.data(using: .utf8) else {
return []
}
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
print("Parsed \(items.count) RSS items")
return items
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String] = [:]) {
currentElement = elementName
if elementName == "item" {
inItem = true
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
if !trimmed.isEmpty && inItem {
switch currentElement {
case "title":
currentTitle += trimmed
case "link":
currentLink += trimmed
case "description":
currentDescription += trimmed
case "pubDate":
currentPubDate += trimmed
default:
break
}
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "item" {
let item = RSSItem(
title: currentTitle,
link: currentLink,
description: currentDescription,
pubDate: currentPubDate
)
items.append(item)
print(" RSS Item: \(item.title)")
// Reset
currentTitle = ""
currentLink = ""
currentDescription = ""
currentPubDate = ""
inItem = false
}
}
}
// Main demonstration
func demonstrateXMLParsing() {
print("=== macOS Swift XML Parsing Examples ===")
// 1. Basic XML
let basicXML = """
<root>
<greeting>Hello, World!</greeting>
<message>Welcome to Swift XML parsing</message>
</root>
"""
let basicParser = BasicXMLParser()
basicParser.parseXML(xmlString: basicXML)
// 2. Books XML
let booksXML = """
<catalog>
<book>
<title>Swift Programming</title>
<author>John Smith</author>
<year>2024</year>
<price>49.99</price>
</book>
<book>
<title>iOS Development</title>
<author>Jane Doe</author>
<year>2023</year>
<price>39.99</price>
</book>
</catalog>
"""
let bookParser = BookParser()
bookParser.parseBooks(xmlString: booksXML)
// 3. Products with attributes
let productsXML = """
<products>
<product id="1" category="electronics">
<name>Laptop</name>
<price>999.99</price>
</product>
<product id="2" category="books">
<name>Programming Guide</name>
<price>29.99</price>
</product>
</products>
"""
let productParser = ProductParser()
productParser.parseProducts(xmlString: productsXML)
// 4. Nested XML
let peopleXML = """
<people>
<person>
<name>John Doe</name>
<age>30</age>
<address>
<street>123 Main St</street>
<city>New York</city>
<state>NY</state>
<zip>10001</zip>
</address>
</person>
<person>
<name>Jane Smith</name>
<age>25</age>
<address>
<street>456 Oak Ave</street>
<city>Los Angeles</city>
<state>CA</state>
<zip>90001</zip>
</address>
</person>
</people>
"""
let personParser = PersonParser()
personParser.parsePeople(xmlString: peopleXML)
// 5. Parse from file
FileXMLParser.parseXMLFromFile(filePath: "/tmp/books.xml")
// 6. RSS Feed
let rssXML = """
<rss>
<channel>
<title>Swift News</title>
<item>
<title>Swift 5.9 Released</title>
<link>https://swift.org/blog/swift-5.9</link>
<description>The latest version of Swift brings new features</description>
<pubDate>Mon, 15 Jan 2024 10:00:00 GMT</pubDate>
</item>
<item>
<title>iOS 17 Preview</title>
<link>https://apple.com/ios17</link>
<description>Explore the new features of iOS 17</description>
<pubDate>Tue, 16 Jan 2024 14:30:00 GMT</pubDate>
</item>
</channel>
</rss>
"""
let rssParser = RSSParser()
rssParser.parseRSS(xmlString: rssXML)
// 7. Streaming XML
let largeXML = """
<root>
\((1...20).map { "<item>Item \($0)</item>" }.joined(separator: "\n"))
</root>
"""
let streamingParser = StreamingXMLParser()
streamingParser.parseStreaming(xmlString: largeXML, maxElements: 5)
print("\n=== All XML Parsing Examples Completed ===")
}
// Run demonstration
demonstrateXMLParsing()