Replies: 1 comment 2 replies
-
@mhayes853 Thanks for the discussion and thoughtfulness. We definitely think there are improvements we can make to the loading infrastructure of Sharing, and better interplay between the load and subscribe endpoints. I think the main thing you bring up would be solvable with a new API on func subscribe(
context: LoadContext<Value>,
subscriber: SharedSubscriber<Value>
) -> SharedSubscription {
nonisolated(unsafe) let observer = NotificationCenter.default.addObserver(
forName: .CKAccountChanged,
object: nil,
queue: nil
) { _ in
+ subscriber.yieldLoading()
Task {
subscriber.yield(with: await Result { try await CKContainer.default().accountStatus() })
}
}
return SharedSubscription { NotificationCenter.default.removeObserver(observer) }
} Would you be up for attempting a PR for such functionality? As for allowing One thought I have is that if func load(
context: LoadContext<Value>,
continuation: LoadContinuation<Value>,
+ subscriber: SharedSubscriber<Value>
) {
Task {
let cachedData = try await cache.loadData()
resume(with: cachedData)
+ subscriber.yieldLoading()
+ subscriber.yield(with: await Result { try await apiClient.loadData() }
}
} Again, could be worth exploring if you have the inclination! |
Beta Was this translation helpful? Give feedback.
-
The value of
isLoading
on@Shared
properties seems to only be true when someLoadContinuation
has been passed to the underlying shared key either through loading the initial value, or whenload
is called explicitly on the Shared property.However, let's take a simplified version of a
SharedReaderKey
that checks the currentCKAccountStatus
from CloudKit as an example.Ignoring potential race conditions from contention between
load
andsubscribe
making separate calls toaccountStatus
, there seems to be no way to indicate a new loading state to the@SharedReader
property from within thisSharedReaderKey
.For instance, when the key receives a new
CKAccountChanged
notification, it must load the new account status asynchronously in the background. However, the fact that there is background loading going on is not reflected in the@SharedReader
property as there is no way to indicate that loading has started up again insidesubscribe
. Despite there possibly being a loadedCKAccountStatus
available in the@SharedReader
property, we may still want to display a loading indicator alongside the available status whilst this background loading is occurring.We could work around this a bit by creating a custom type that holds this loading state, that gets emitted from the key. Eg.
Then we could update
CKAccountStatusKey
in a similar manner:While this certainly allows for more control over the loading state, the consumer of this key using
@SharedReader
now must be aware that they shouldn't be using theisLoading
property on theSharedReader
, but rather theisLoading
property inCKAccountStatusState
.If we wanted to rely on the
isLoading
property on@SharedReader
, we could omit the subscription logic from theCKAccountStatusKey
, and opt instead to observe theCKAccountChanged
notification outside of the key say at the root of the application instead. When we observe the notification, we can then invokeload
directly on the@SharedReader
like so:This allows us to use
$accountStatus.isLoading
as the main source of truth for the loading state, but I think it would be ideal for maintainability to keep this subscription logic withinCKAccountStatusKey
as then it would be the sole component that deals with the account status (and also we can take advantage of the fact that we can automatically unsubscribe fromNotificationCenter
when no consumers ofCKAccountStatusKey
are active).For some more advanced use cases of this kind of control of the loading state, I'm currently working on some tooling that makes common asynchronous data fetching like network calls more friendly with
@SharedReader
. In particular, some of this tooling includes automatically refetching the data when the network comes back online. The work of observing the current internet connectivity status, and refetching the data would occur somewhere in thesubscribe
method of someSharedReaderKey
. Naturally, I would like to indicate to the consumer of the@SharedReader
that the data is being refetched throughisLoading
such that a loading indicator can be displayed in the UI.Additionally, I may want to send back multiple payloads of data over time (say in a case where we first want to load some cached data on disk, and then fetch the latest data via the network), but still indicate that the data is in a collective "loading" state. It would be ideal to have precise control of the loading state here, but currently it seems that
isLoading
will automatically be set to false when sending back any payload throughLoadContinuation
. To illustrate this a bit more clearly, I think it would be cool if something like this could be done:I have a couple of final questions to ask. As of right now, what would be the recommended way for handling these kinds of complex loading states? Secondly, is it possible that the library could address these use cases in the future?
Anyways, thanks for taking the time to read through this.
Beta Was this translation helpful? Give feedback.
All reactions