Property Wrapper with Actor as storage

Hi everyone, this is slightly Apple Platform related, but I will try and keep it relatively generic as I think it could be useful on other platforms.

For a bit of context, I am trying to build a Property Wrapper that interacts with the Keychain with the standard CRU functionality, to ensure values are not overwritten in different contexts I have set up my helper object for interacting with the keychain set up as an Actor

I am using this helper object as the "storage" for my Property Wrapper, of course this leads to a problem with concurrent properties, I would like to have the wrappedValue property as a get, set property, but I need to access the helper object in an asynchronous context, because I want to have a setter I cannot have an async getter and I cannot seem to work out how I can access the actor in a synchronous way, I am probably missing something obvious, or I am trying to do something outside of the scope of Property Wrappers/Actors but my google-fu is failing me, so I thought I would ask around here.

I'm not sure it is much help, but this is how I left my code last night:

var wrappedValue: Value {
get { Task { await storage.value } }
set { Task { await storage.update(newValue) } }
}

Iā€™m not aware of any way to access actor in a blocking manner. Actors are intended to prevent writing blocking code. If you really need blocking behavior, implementing your storage as a plain class with a mutex inside would be better.

Alternatively, you can maintain a private copy of the data inside main actor (assuming your property wrapper is used in UI code). But make sure to make any writes to the master copy.

If you're willing to adopt actors, why not also adopt async properties? Technically, keychain accesses are blocking and should be wrapped asynchronously, so this is the perfect opportunity to adopt a best practice and the new concurrency features at the same time.

1 Like

I wanted to be able to write to the property as well, async properties does not support that.

But I think when I moved away to try and use async properties, Property Wrappers don't allow for async contexts in general at the moment, so it is a bit of a no go

1 Like