Bird
Raised Fist0
iOS Swiftmobile~20 mins

Custom decoder configuration in iOS Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Custom Decoder Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
📝 Syntax
intermediate
2:00remaining
Correct syntax for custom decoder init
Which option correctly implements a custom initializer for decoding a Swift struct with a nested container?
iOS Swift
struct User: Decodable {
  let name: String
  let age: Int

  enum CodingKeys: String, CodingKey {
    case info
  }

  enum InfoKeys: String, CodingKey {
    case name
    case age
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    let infoContainer = try container.nestedContainer(keyedBy: InfoKeys.self, forKey: .info)
    name = try infoContainer.decode(String.self, forKey: .name)
    age = try infoContainer.decode(Int.self, forKey: .age)
  }
}
A
init(from decoder: Decoder) throws {
  let container = try decoder.unkeyedContainer()
  name = try container.decode(String.self)
  age = try container.decode(Int.self)
}
B
init(from decoder: Decoder) throws {
  let container = try decoder.container(keyedBy: InfoKeys.self)
  name = try container.decode(String.self, forKey: .name)
  age = try container.decode(Int.self, forKey: .age)
}
C
init(from decoder: Decoder) throws {
  let container = try decoder.container(keyedBy: CodingKeys.self)
  name = try container.decode(String.self, forKey: .name)
  age = try container.decode(Int.self, forKey: .age)
}
D
init(from decoder: Decoder) throws {
  let container = try decoder.container(keyedBy: CodingKeys.self)
  let infoContainer = try container.nestedContainer(keyedBy: InfoKeys.self, forKey: .info)
  name = try infoContainer.decode(String.self, forKey: .name)
  age = try infoContainer.decode(Int.self, forKey: .age)
}
Attempts:
2 left
💡 Hint
Remember to access the nested container using the correct key and key type.
❓ ui_behavior
intermediate
1:30remaining
Effect of missing key in custom decoder
What happens if a required key is missing when decoding with a custom decoder initializer in Swift?
iOS Swift
struct Product: Decodable {
  let id: Int
  let name: String

  enum CodingKeys: String, CodingKey {
    case id
    case name
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    id = try container.decode(Int.self, forKey: .id)
    name = try container.decode(String.self, forKey: .name)
  }
}

// JSON missing 'name' key
let jsonData = "{\"id\": 101}".data(using: .utf8)!
AThe decoding succeeds and 'name' is set to an empty string.
BThe decoding succeeds and 'name' is set to nil.
CThe decoding throws a DecodingError.keyNotFound error at runtime.
DThe decoding silently ignores the missing key and sets default values.
Attempts:
2 left
💡 Hint
Think about how Swift Decodable handles missing required keys by default.
❓ lifecycle
advanced
2:30remaining
Custom decoder with date decoding strategy
How can you configure a JSONDecoder to decode dates in a custom format when decoding a struct with a custom decoder initializer?
iOS Swift
struct Event: Decodable {
  let title: String
  let date: Date

  enum CodingKeys: String, CodingKey {
    case title
    case date
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    title = try container.decode(String.self, forKey: .title)
    date = try container.decode(Date.self, forKey: .date)
  }
}

let decoder = JSONDecoder()
// Configure decoder here for custom date format
A
decoder.dateDecodingStrategy = .custom { decoder in
  let container = try decoder.singleValueContainer()
  let dateString = try container.decode(String.self)
  let formatter = DateFormatter()
  formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
  guard let date = formatter.date(from: dateString) else {
    throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date format")
  }
  return date
}
Bdecoder.dateDecodingStrategy = .formatted(DateFormatter())
Cdecoder.dateDecodingStrategy = .secondsSince1970
Ddecoder.dateDecodingStrategy = .iso8601
Attempts:
2 left
💡 Hint
Use a custom closure to parse the date string with your own format.
❓ navigation
advanced
2:00remaining
Decoding nested JSON with optional nested container
Given a JSON where a nested object may be missing, how do you safely decode an optional nested container in a custom decoder initializer?
iOS Swift
struct Profile: Decodable {
  let username: String
  let address: Address?

  struct Address: Decodable {
    let city: String
    let zip: String
  }

  enum CodingKeys: String, CodingKey {
    case username
    case address
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    username = try container.decode(String.self, forKey: .username)
    if container.contains(.address) {
      let addressContainer = try container.nestedContainer(keyedBy: AddressCodingKeys.self, forKey: .address)
      let city = try addressContainer.decode(String.self, forKey: .city)
      let zip = try addressContainer.decode(String.self, forKey: .zip)
      address = Address(city: city, zip: zip)
    } else {
      address = nil
    }
  }

  enum AddressCodingKeys: String, CodingKey {
    case city
    case zip
  }
}
ADecode address as optional directly with decodeIfPresent(Address.self, forKey: .address).
BUse try? container.nestedContainer(keyedBy: AddressCodingKeys.self, forKey: .address) and unwrap optional.
CForce unwrap nested container with try container.nestedContainer(keyedBy: AddressCodingKeys.self, forKey: .address) without checking.
DUse container.contains(.address) to check before decoding nested container.
Attempts:
2 left
💡 Hint
Swift Decodable supports decoding optional nested objects directly.
🔧 Debug
expert
3:00remaining
Identify the cause of decoding failure in custom decoder
Why does the following custom decoder initializer fail to decode the JSON correctly?
iOS Swift
struct Item: Decodable {
  let id: Int
  let tags: [String]

  enum CodingKeys: String, CodingKey {
    case id
    case tags
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    id = try container.decode(Int.self, forKey: .id)
    let tagsContainer = try container.nestedUnkeyedContainer(forKey: .tags)
    tags = try tagsContainer.decode([String].self)
  }
}

// JSON example: {"id": 5, "tags": ["swift", "ios"]}
AnestedUnkeyedContainer returns an UnkeyedDecodingContainer which cannot decode an array directly.
Bdecode([String].self) is invalid inside a nestedUnkeyedContainer; should decode elements one by one.
CThe code should use decodeIfPresent instead of decode for tags.
DThe JSON format is invalid for decoding tags as an array.
Attempts:
2 left
💡 Hint
Unkeyed containers decode elements one at a time, not whole arrays.

Practice

(1/5)
1. What is the main purpose of using a custom decoder configuration in Swift's Decodable protocol?
easy
A. To control how data keys map to your code properties
B. To change the app's user interface colors
C. To speed up the app's launch time
D. To encrypt data before decoding

Solution

  1. Step 1: Understand the role of custom decoding

    Custom decoder configuration allows you to specify how JSON or other data keys match your Swift properties.
  2. Step 2: Identify the purpose in data mapping

    This helps fix mismatches when the data keys differ from your property names.
  3. Final Answer:

    To control how data keys map to your code properties -> Option A
  4. Quick Check:

    Custom decoding = data key mapping control [OK]
Hint: Custom decoder fixes key-property name mismatches [OK]
Common Mistakes:
  • Thinking it changes UI appearance
  • Assuming it improves app speed
  • Confusing decoding with encryption
2. Which of the following is the correct way to define a custom key mapping in a Swift Decodable struct?
easy
A. Declare properties as lazy var
B. Use an enum conforming to CodingKey with cases matching JSON keys
C. Override the init() method without parameters
D. Use @IBOutlet annotations on properties

Solution

  1. Step 1: Recall how to customize keys in Decodable

    Swift uses an enum conforming to CodingKey to map JSON keys to property names.
  2. Step 2: Identify the correct syntax

    The enum cases represent the JSON keys, allowing custom mapping.
  3. Final Answer:

    Use an enum conforming to CodingKey with cases matching JSON keys -> Option B
  4. Quick Check:

    Custom keys = enum CodingKey [OK]
Hint: Custom keys use enum CodingKey with cases [OK]
Common Mistakes:
  • Trying to override init() without parameters
  • Using lazy vars for decoding
  • Confusing UI annotations with decoding
3. Given this struct and JSON, what will be the value of userName after decoding?
struct User: Decodable {
  let userName: String
  enum CodingKeys: String, CodingKey {
    case userName = "user_name"
  }
}

let json = "{\"user_name\": \"Alice\"}".data(using: .utf8)!
medium
A. "userName"
B. Decoding error
C. nil
D. "Alice"

Solution

  1. Step 1: Understand the custom key mapping

    The JSON key "user_name" maps to the property userName via the CodingKeys enum.
  2. Step 2: Decode the JSON data

    The decoder reads "Alice" from "user_name" and assigns it to userName.
  3. Final Answer:

    "Alice" -> Option D
  4. Quick Check:

    Mapped key value = "Alice" [OK]
Hint: Check CodingKeys mapping to find decoded value [OK]
Common Mistakes:
  • Assuming property name must match JSON key exactly
  • Expecting nil if names differ
  • Thinking decoding fails without exact key match
4. What is wrong with this custom decoder implementation?
struct Product: Decodable {
  let id: Int
  let name: String
  enum CodingKeys: String, CodingKey {
    case id
    case productName
  }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.id = try container.decode(Int.self, forKey: .id)
    self.name = try container.decode(String.self, forKey: .productName)
  }
}
medium
A. Missing Decodable conformance
B. Properties are not declared as optional
C. CodingKeys enum does not map 'name' property correctly
D. Decoder container is not created properly

Solution

  1. Step 1: Check CodingKeys enum against properties

    The property name expects a key, but CodingKeys has productName which does not match the property name.
  2. Step 2: Identify the mapping issue

    Since productName is not linked to name, decoding will fail or mismatch.
  3. Final Answer:

    CodingKeys enum does not map 'name' property correctly -> Option C
  4. Quick Check:

    Property-key mismatch = error [OK]
Hint: Ensure CodingKeys cases match or map all properties [OK]
Common Mistakes:
  • Not mapping property names to keys
  • Forgetting Decodable conformance
  • Misusing decoder container creation
5. You receive JSON data with keys "first_name" and "last_name", but your Swift struct uses firstName and lastName. How do you configure your decoder to handle this mismatch efficiently?
hard
A. Create a CodingKeys enum mapping firstName = "first_name" and lastName = "last_name"
B. Rename your struct properties to match JSON keys exactly
C. Manually parse JSON strings without using Decodable
D. Use @objc annotations on properties

Solution

  1. Step 1: Identify the key-property name mismatch

    JSON keys use snake_case, but Swift properties use camelCase.
  2. Step 2: Use CodingKeys enum to map keys to properties

    Define enum with firstName = "first_name" and lastName = "last_name" to decode correctly.
  3. Step 3: Avoid renaming properties or manual parsing for cleaner code

    This approach keeps your code clean and flexible.
  4. Final Answer:

    Create a CodingKeys enum mapping firstName = "first_name" and lastName = "last_name" -> Option A
  5. Quick Check:

    Use CodingKeys for key mapping [OK]
Hint: Map JSON keys to properties with CodingKeys enum [OK]
Common Mistakes:
  • Renaming properties instead of mapping keys
  • Parsing JSON manually instead of using Decodable
  • Using irrelevant annotations like @objc
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard