乐闻世界logo
搜索文章和话题

What is Codable in Swift? What are the differences between CustomStringConvertible and CustomDebugStringConvertible?

2月21日 15:04

What is Codable in Swift? How to use Codable for encoding and decoding? What are the differences between CustomStringConvertible and CustomDebugStringConvertible?

Codable in Swift is a type alias that combines the Encodable and Decodable protocols, used for converting between data types and external representations (such as JSON, Property List).

Basic Usage of Codable:

swift
struct User: Codable { let id: Int let name: String let email: String } // Encoding let user = User(id: 1, name: "John Doe", email: "john@example.com") let encoder = JSONEncoder() if let jsonData = try? encoder.encode(user) { print(String(data: jsonData, encoding: .utf8)!) } // Decoding let decoder = JSONDecoder() if let decodedUser = try? decoder.decode(User.self, from: jsonData) { print(decodedUser.name) }

Custom Coding Keys:

swift
struct User: Codable { let id: Int let name: String let email: String enum CodingKeys: String, CodingKey { case id case name = "full_name" case email = "email_address" } }

Custom Encoding and Decoding:

swift
struct DateWrapper: Codable { let date: Date enum CodingKeys: String, CodingKey { case timestamp } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let timestamp = try container.decode(Double.self, forKey: .timestamp) self.date = Date(timeIntervalSince1970: timestamp) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(date.timeIntervalSince1970, forKey: .timestamp) } }

Notes on Codable:

  • All properties must be Codable types
  • Optional types automatically support Codable
  • Arrays and dictionaries automatically support Codable if elements are Codable types
  • Can use CodingKeys to customize key names

CustomStringConvertible:

  • Used to provide custom string representation
  • Implement description property
  • Used in print() and String(describing:)
  • Example:
    swift
    struct Point: CustomStringConvertible { let x: Int let y: Int var description: String { return "(\(x), \(y))" } } let point = Point(x: 3, y: 4) print(point) // (3, 4)

CustomDebugStringConvertible:

  • Used to provide string representation for debugging
  • Implement debugDescription property
  • Used for descriptions in debugger
  • Higher priority than CustomStringConvertible
  • Example:
    swift
    struct User: CustomDebugStringConvertible { let id: Int let name: String let password: String var debugDescription: String { return "User(id: \(id), name: \(name))" } } let user = User(id: 1, name: "John", password: "secret") debugPrint(user) // User(id: 1, name: John)

Differences Between CustomStringConvertible and CustomDebugStringConvertible:

  1. Different Purposes:

    • CustomStringConvertible: for regular string representation
    • CustomDebugStringConvertible: for debug string representation
  2. Different Implementation Methods:

    • CustomStringConvertible: implement description property
    • CustomDebugStringConvertible: implement debugDescription property
  3. Different Call Scenarios:

    • CustomStringConvertible: print(), String(describing:)
    • CustomDebugStringConvertible: debugPrint(), debugger
  4. Different Priorities:

    • When both implemented, CustomDebugStringConvertible has higher priority
    • Use debugDescription during debugging
    • Use description for regular use

Best Practices:

  1. Implement Codable for data models
  2. Use CodingKeys to handle key name mismatches
  3. Implement CustomStringConvertible for custom types
  4. Implement CustomDebugStringConvertible for debugging
  5. Hide sensitive information in debugDescription
标签:Swift