Conforming @MainActor class to Codable

How does one add Codable conformance to a class that needs to be isolated to the MainActor?

For example, the following code gives compiler errors:

@MainActor final class MyClass: Codable {
	var value: Int
	
	enum CodingKeys: String, CodingKey {
		case value
	}
	
	init(from decoder: Decoder) throws { // <-- Compiler error: Initializer 'init(from:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Decodable'
		let data = try decoder.container(keyedBy: CodingKeys.self)
		self.value = try data.decode(Int.self, forKey: .value)
	}
	
	func encode(to encoder: Encoder) throws { // <-- Compiler error: Instance method 'encode(to:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Encodable'
		var container = encoder.container(keyedBy: CodingKeys.self)
		try container.encode(value, forKey: .value)
	}
}

I'm definitely struggling to get my head around actors and @MainActor at the moment!

Post not yet marked as solved Up vote post of peggers123 Down vote post of peggers123
2.6k views

Replies

I've worked out that I need to change init and encode to async functions:

@MainActor final class MyClass: Codable {
	var value: Int
	
	enum CodingKeys: String, CodingKey {
		case value
	}
	
	init(from decoder: Decoder) async throws {
		let data = try decoder.container(keyedBy: CodingKeys.self)
		self.value = try data.decode(Int.self, forKey: .value)
	}
	
	func encode(to encoder: Encoder) async throws {
		var container = encoder.container(keyedBy: CodingKeys.self)
		try container.encode(value, forKey: .value)
	}
}
  • That doesn't work for me. Adding async to those does make the errors on those functions go away, but the compiler still complains

    Type 'User' does not conform to protocol 'Decodable' Type 'User' does not conform to protocol 'Encodable'

    with no further information.

Add a Comment