Having trouble with RawRespresentable "Expected to decode String but found a dictionary instead."

I want to use AppStorage for a custom struct I am using

struct Activities {
    var name: String
    var age: Int
}
struct ContentView: View {
    @AppStorage("key") private var activities: Activities = .init(name: "Albert", age: 42)

    var body: some View {
        VStack {
            TextField("Activity Name", text: $activities.name)
        }
    }
}

The above code generates a compiler warning, recommending I add RawRepresentable conformance. So I've added it like this:

extension Activities: RawRepresentable {
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8) else {
            return nil
        }
        do {
            let result = try JSONDecoder().decode(Activities.self, from: data)
            self = result
        }
        catch {
            print(error)
            return nil
        }
    }
    var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
              let result = String(data: data, encoding: .utf8) else {
            return "{}"
        }
        return result
    }
}

This leads to a stack overflow because calling encode from rawValue calls rawValue. :-( I overcame this by declaring Codable conformance and overriding the default Encodable implementation:

extension Activities: Codable {
    enum CodingKeys: String, CodingKey {
        case name
        case age
    }
    func encode(to encoder: any Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(age, forKey: .age)
    }
}

This solves the stack overflow, but now init?(rawValue: String) is failing and I'm not sure why. When I set a breakpoint in my catch block I see the following:

(lldb) po error
▿ DecodingError
  ▿ typeMismatch : 2 elements
    - .0 : Swift.String
    ▿ .1 : Context
      - codingPath : 0 elements
      - debugDescription : "Expected to decode String but found a dictionary instead."
      - underlyingError : nil

(lldb) po rawValue
{"name":"Albert2","age":42}
(lldb) po data
▿ 27 bytes
  - count : 27
  ▿ bytes : 27 elements
    - 0 : 123
    - 1 : 34
    - 2 : 110
    - 3 : 97
    - 4 : 109
    - 5 : 101
    - 6 : 34
    - 7 : 58
    - 8 : 34
(truncated to save space for posting :-)
Having trouble with RawRespresentable "Expected to decode String but found a dictionary instead."
 
 
Q