I am trying to migrate a WatchConnectivity App to Swift6 and I found an Issue with my replyHandler
callback for sendMessageData.
I am wrapping sendMessageData
in withCheckedThrowingContinuation,
so that I can await the response of the reply. I then update a Main Actor ObservableObject
that keeps track of the count of connections that have not replied yet, before returning the data using continuation.resume.
...
@preconcurrency import WatchConnectivity
actor ConnectivityManager: NSObject, WCSessionDelegate {
private var session: WCSession = .default
private let connectivityMetaInfoManager: ConnectivityMetaInfoManager
...
private func sendMessageData(_ data: Data) async throws -> Data? {
Logger.shared.debug("called on Thread \(Thread.current)")
await connectivityMetaInfoManager.increaseOpenSendConnectionsCount()
return try await withCheckedThrowingContinuation({
continuation in
self.session.sendMessageData(
data,
replyHandler: { data in
Task {
await self.connectivityMetaInfoManager
.decreaseOpenSendConnectionsCount()
}
continuation.resume(returning: data)
},
errorHandler: { (error) in
Task {
await self.connectivityMetaInfoManager
.decreaseOpenSendConnectionsCount()
}
continuation.resume(throwing: error)
}
)
})
}
Calling sendMessageData
somehow causing the app to crash and display the debug message: Incorrect actor executor assumption
.
The code runs on swift 5 with SWIFT_STRICT_CONCURRENCY = complete. However when I switch to swift 6 the code crashes.
I rebuilt a simple version of the App. Adding bit by bit until I was able to cause the crash. See Broken App
Awaiting sendMessageData
and wrapping it in a task and adding the @Sendable
attribute to continuation,
solve the crash.
See Fixed App
But I do not understand why yet.
Is this intended behaviour?
Should the compiler warn you about this?
Is it a WatchConnectivity
issue?
I initially posted on forums.swift.org, but was told to repost here.