class MyModel: ObservableObject {
@Published var selection = FamilyActivitySelection()
init() {
$selection.sink {
newSelection in
print(newSelection)
}
}
}
class MyView: View {
@StateObject var model = MyModel()
// some body
// ....
// my method
func removeToken(token: ApplicationToken) {
model.selection.applicationTokens.remove(token)
}
}
I am using the above code. When I call removeToken, the callback from the sink (which is registered in init() of MyModel) is called without any changes. newSelection still contains the token that I removed.
Currently, I am using the additional code below to work around the problem.
.onChange(of: model.selection.applicationTokens) {
newSet in
model.selection.applicationTokens = newSet
}
Should I use the workaround solution, or am I missing something?
Post not yet marked as solved
I am maintaining a macOS app, a GUI on top of a command line tool. A Process() object is used to kick off the command line tool with arguments. And completion handlers are triggered for post actions when command line tool is completed. My question is: I want to refactor the process to use async and await, and not use completion handlers.
func execute(command: String, arguments:[String]) -> async {
let task = Process()
task.launchPath = command
task.arguments = arguments
...
do {
try task.run()
} catch let e {
let error = e
propogateerror(error: error)
}
...
}
...
and like this in calling the process
await execute(..)
Combine is used to monitor the ProcessTermination:
NotificationCenter.default.publisher(
for: Process.didTerminateNotification)
.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
.sink { _ in
.....
// Release Combine subscribers
self.subscriptons.removeAll()
}.store(in: &subscriptons)
Using Combine works fine by using completion handlers, but not by refactor to async. What is the best way to refactor the function? I know there is a task.waitUntilExit(), but is this 100% bulletproof? Will it always wait until external task is completed?
Post not yet marked as solved
I'm just putting this here for visibility, I already submitted FB13688825.
If you say this:
Task {
for await tracks in avPlayerItem.publisher(for: \.tracks, options: [.initial]).values {
print("*** fired with: \(tracks.description)")
}
}
...it fires once with: "*** fired with: []"
If you say this:
avPlayerItem.publisher(for: \.tracks).sink { [weak self] tracks in
print("*** fired with: \(tracks.description)")
}.store(in: &subscriptions)
...you get, as expected, multiple fires, most with data in them such as: *** fired with: [<AVPlayerItemTrack: 0x10a9869a0, assetTrack = <AVAssetTrack: 0x10a9869f0...
I think it's a bug but I'm just going to go back to the "old way" for now. No emergency.
Post not yet marked as solved
Hi,
Is there any way to return cached URLSession response and then reload and return?
I want show cached response while load last version of API call, and if reload works fine, show the latest version of response and in case os failure, show cached response (if exists)
Thanks!