[Swift] SwiftUI AppStorage array, optional

SwiftUI의 AppStorage를 사용할 때 기본 값을 optional로 줄 수 없는 경우 아래와 같은 에러 메세지가 나타난다.

No exact matches in call to initializer

그럴 경우 아래의 코드를 추가한다.

extension Optional: RawRepresentable where Wrapped: Codable {
    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self) else {
            return "{}"
        }
        return String(decoding: data, as: UTF8.self)
    }

    public init?(rawValue: String) {
        guard let value = try? JSONDecoder().decode(Self.self, from: Data(rawValue.utf8)) else {
            return nil
        }
        self = value
    }
}

대다수의 기본 타입들은 Codable을 채택하고 있기때문에 사용 가능

그리고 Array의 경우에도 위의 오류와 동일하게 발생할텐데 아래의 코드를 추가한다.

extension Array: RawRepresentable where Element: Codable {
    public init?(rawValue: String) {
        guard
            let data = rawValue.data(using: .utf8),
            let result = try? JSONDecoder().decode([Element].self, from: data)
        else {
            return nil
        }
        self = result
    }

    public var rawValue: String {
        guard
            let data = try? JSONEncoder().encode(self),
            let result = String(data: data, encoding: .utf8)
        else {
            return "[]"
        }
        return result
    }
}