Actors and Protocol requirements

Xcode 13 b5

I am trying to mock/stub an actor. However, I'm running into issues. Is it possible for an actor to conform to a protocol? For example, if we have the following Protocol and actor, the compiler complains that Actor-isolated instance method 'fetchProduct(id:)' cannot be used to satisfy a protocol requirement

protocol ProductFetcher: AnyObject {
    func fetchProduct(id: String) async -> Product
}

actor ProductStore: ProductFetcher {
    private var cache: [String: Product] = [:]

    func fetchProduct(id: String) -> Product {
        if let product = cache[id] {
            return product
        }
        let newProduct = Product(id: "1111", name: "New Product")
        cache[id] = newProduct
        return newProduct
    }
}

A few suggested fixes pop up
Add '@asyncHandler' to function 'fetchProduct(id:)' to create an implicit asynchronous context
Add 'nonisolated' to 'fetchProduct(id:)' to make this instance method not isolated to the actor
but I don't know to use the suggested fixes

Additionally, I tried passing in the function instead of a protocol. Like so

typealias ProductFetcher = (String) async -> Product

class MyViewModel {

    private let productFetcher: ProductFetcher

    init(productFetcher: @escaping ProductFetcher) {
        self.productFetcher = productFetcher
    }

    func load(id: String) async {
        let product = await productFetcher(id)
        print(product)
    }
}

let viewModel = MyViewModel(productFetcher: ProductStore.fetchProduct)

However, I get
Cannot convert value of type '(isolated ProductStore) -> (String) -> Product' to expected argument type 'ProductFetcher' (aka '(String) async -> Product')

So, how can I mock an actor?

1 Like

This sounds a bit off -- this works (I just confirmed, tho on a top of main compiler).

It is fine to conform to that async func with a func declared in an actor. This is documented here: swift-evolution/0306-actors.md at main ยท apple/swift-evolution ยท GitHub

Are you sure you are using the beta's toolchain and not something else?
The fact that messages mention @asyncHandler make me pretty suspicious you're using some very old toolchain, async handlers are gone since many months (they were only part of the initial proposals and have since been removed).

Thanks, @ktoso, I was using the swift version with the latest Xcode 13 beta 5. But I also tried the latest snapshot (dated August 8, is this the latest?), and although the Fix-It option with the @asyncHandler is gone. I still get the same compiler error
Actor-isolated instance method 'fetchProduct(id:)' cannot be used to satisfy a protocol requirement
and the Add 'nonisolated' to 'fetchProduct(id:)' to make this instance method not isolated to the actor

I ran into this issue yesterday and have at least a partial solution, conforming the protocol to Actor.