🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Sérialisation macOS Swift
Exemples de sérialisation macOS Swift incluant la sérialisation JSON, la désérialisation et l'analyse XML
💻 Sérialisation JSON swift
🟢 simple
⭐⭐
Sérialiser les objets Swift en JSON en utilisant Codable et 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()
💻 Désérialisation JSON swift
🟡 intermediate
⭐⭐⭐
Désérialiser les données JSON en objets Swift en utilisant Codable et 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()
💻 Analyse XML swift
🟡 intermediate
⭐⭐⭐
Analyser les documents XML en utilisant XMLParser et convertir en objets 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()