Protect mutable state with Swift actors

RSS for tag

Discuss the WWDC21 session Protect mutable state with Swift actors.

Posts under wwdc21-10133 tag

11 Posts

Post

Replies

Boosts

Views

Activity

problems with consecutive if statements
I made a function that checks over several conditions tu return a string. the function is called when a navigation link is pressed the issue I'm having is that it breaks after the third if statement and only keeps checking after pressing the navigation link for the second time. func diag() {       viewModel.npH = Double(Float(viewModel.pH) ?? 0)       viewModel.npCO2 = Double(Float(viewModel.pCO2) ?? 0)       viewModel.nHCO3 = Double(Float(viewModel.HCO3) ?? 0)       if viewModel.npH > 7.45 {         diagnos.resultado1 = "alcalemia"         print ("1")         }       if viewModel.npCO2 < 40 {         diagnos.resultado2 = "alcalosis respiratoria"         print ("2")         }       if viewModel.nHCO3 > 24 {         diagnos.resultado3 = "alcalosis metabólica"         print ("3")       }               if viewModel.npH < 7.35 {         diagnos.resultado1 = "acidemia"         print ("4")       }       if viewModel.npCO2 > 40 {         diagnos.resultado2 = "acidosis respiratoria"         print ("5")       }       if viewModel.nHCO3 < 24 {         diagnos.resultado3 = "acidosis metabólica"         print ("6")       }       if diagnos.resultado1 == "acidemia" && diagnos.resultado3 == "acidosis metabólica" && (viewModel.expectPCO2aci - 2)...(viewModel.expectPCO2aci + 2) ~= viewModel.npCO2 {         diagnos.resultado4 = "acidosis metabólica compensada"         diagnos.resultado2 = ""         print ("7")         }       if diagnos.resultado1 == "alcalemia" && diagnos.resultado3 == "alcalosis metabólica" && (viewModel.expectALCPCO2 - 0.5)...(viewModel.expectALCPCO2 + 0.5) ~= viewModel.npCO2 {         diagnos.resultado4 = "alcalosis metabólica compensada"         diagnos.resultado3 = ""         print ("8")       }       if diagnos.resultado1 == "alcalemia" && diagnos.resultado2 == "alcalosis respiratoria"         && viewModel.agucro == 1         && (viewModel.expectHCO3alkA - 0.5)...(viewModel.expectHCO3alkA + 0.5) ~= viewModel.nHCO3 {         diagnos.resultado4 = "alcalosis respiratoria compensada"         diagnos.resultado3 = ""         print ("9")       }             }    }
4
0
854
May ’22
Async/await and maxConcurrentOperationCount
I'm writing an app that performs actions in a web browser automatically on user's behalf. Currently my app uses OperationQueue to perform asynchronous work. I'm trying to rewrite the app to use async/await instead. Note, that it is necessary for my app to limit the number of concurrently executing work items. Otherwise the app may run into server throttling issues. However, I can't find an equivalent to OperationQueue's maxConcurrentOperationCount parameter in the new concurrency model. Is there a way to limit the number of concurrently running "lanes" of execution without resorting to using OperationQueue / DispatchQueue / NSLock ?
1
0
1.5k
Mar ’22
Using actors in a SwiftUI .task
Hi, having the concurrency checks (-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks) enabled I always get this warning, when trying to access/use an actor in a SwiftUI .task: "Cannot use parameter 'self' with a non-sendable type 'ContentView' from concurrently-executed code". What would be a correct implementation? Here's a minimal code-sample which produces this warning: import SwiftUI struct ContentView: View { @State var someVar = 5 var a1 = A1() var body: some View { Text("Hello, world!") .padding() .task { await a1.doSomething() } } } public actor A1 { func doSomething() { print("Hello") } }
1
0
2.4k
Feb ’22
Will TSAN or the Swift compiler identify possible Swift async-await race conditions?
I haven't followed the swift forums very closely, so perhaps there is news buried deep somewhere mentioning this. Will the swift compiler and/or TSAN at runtime in the future be able to identify possible race conditions associated with Swift async-await (excluding data races that are "erased" by async-await)? I suppose this could equate to proving a function is reentrant in some scenarios (from a compiler's perspective, though I'm not knowledgeable about compilers)? Consider, e.g. the scenario described in "Protect Mutable State with Swift Actors" around 9:15, where Dario talks about actor reentrancy, with the cache for the image URL
0
0
752
Jan ’22
TaskGroup in and Actor
I've had an issue in my project where I trigger a task from a SwiftUI View with the modifier .task. From there it calls and async function into an actor that has a TaskGroup that makes concurrent network calls that has a type of Void.self. I've noticed that sometimes the TaskGroup is either never called and will no longer be called. I'm wondering if perhaps a TaskGroup inside of an Actor that has a parent Task created outside the Actor is a problem? But it does seem to work if I change the Actor to a Class. Could someone help explain to me why this is?
0
0
685
Aug ’21
actors, SwiftUI and @Published
Hi, is there a way that an actor can have a @MainActor @Published annotated property which is then consumed by a SwiftUI View "as usual"? Currently this: @Published @MainActor public private(set) var state: State = .initial gives me the following error when trying to access it from with a SwiftUI View: "Actor-isolated property '$state' can only be referenced from inside the actor" I guess I understand where the error is coming from, but I wonder if there's a way to publish properties from actors and be able to make sure they are updated on the main thread by annotating them with @MainActor.
1
0
4k
Aug ’21
Entering the actor through two async let calls hangs the app at suspension point.
I have been trying to work with the image downloader code provided in the session to see if I could download two images at once and cache them in the actor. For some reason, when I enter the download method on the actor with two consecutive async let calls, the app hangs at the deepest suspension point. I am providing a very minimum code you can copy and paste into a new iOS Storyboard-based project, replacing the code in ViewController.swift: enum ImageDownloadError: Error {     case badImage } actor ImageDownloader {     private var cache: [URL: UIImage] = [:]     func image(from url: URL) async throws -> UIImage {         if let image = cache[url] {             return image         }         print("Downloading image")         let image = try await downloadImage(url: url)         print("Downloaded image")         cache[url] = image         return image     }     private func downloadImage(url: URL) async throws -> UIImage {         let imageRequest = URLRequest(url: url)         let (data, imageResponse) = try await URLSession.shared.data(for: imageRequest)         guard let image = UIImage(data: data), (imageResponse as? HTTPURLResponse)?.statusCode == 200 else {             throw ImageDownloadError.badImage         }         return image     } } class ViewController: UIViewController {     override func viewDidLoad() {         super.viewDidLoad()         async {             await downloadImages()         }     }     func downloadImages() async {         let downloader = ImageDownloader()         let imageURL = URL(string:  "https://www.andyibanez.com/fairesepages.github.io/tutorials/async-await/part3/3.png")!         async let downloadedImage = downloader.image(from: imageURL)         //async let sameDownloadedImage = downloader.image(from: imageURL) // Uncomment to see the bug         var images = [UIImage?]()         images += [try? await downloadedImage]         //images += [try? await sameDownloadedImage]         print("Finished everything")     } } If you uncomment the code marked as Uncomment to see the bug, you will see that the code will go through many different await calls, but it will hang on the ine in the URLSession.shared.data(for: imageRequest) call. The app just hangs there and doesn't continue executing. Commenting the same line will let it work fine. Are there any known workarounds for this? I would love to get this to work. I have opened a feedback on this, linking it just in case FB9213145
0
0
772
Jul ’21
How to set TableColumn in Table using ForEach
Table(tableData) {           ForEach(tableColumns) { item in             TableColumn(item.name) { data in Text(data.value)             }           } }
Replies
6
Boosts
0
Views
2.6k
Activity
Oct ’23
problems with consecutive if statements
I made a function that checks over several conditions tu return a string. the function is called when a navigation link is pressed the issue I'm having is that it breaks after the third if statement and only keeps checking after pressing the navigation link for the second time. func diag() {       viewModel.npH = Double(Float(viewModel.pH) ?? 0)       viewModel.npCO2 = Double(Float(viewModel.pCO2) ?? 0)       viewModel.nHCO3 = Double(Float(viewModel.HCO3) ?? 0)       if viewModel.npH > 7.45 {         diagnos.resultado1 = "alcalemia"         print ("1")         }       if viewModel.npCO2 < 40 {         diagnos.resultado2 = "alcalosis respiratoria"         print ("2")         }       if viewModel.nHCO3 > 24 {         diagnos.resultado3 = "alcalosis metabólica"         print ("3")       }               if viewModel.npH < 7.35 {         diagnos.resultado1 = "acidemia"         print ("4")       }       if viewModel.npCO2 > 40 {         diagnos.resultado2 = "acidosis respiratoria"         print ("5")       }       if viewModel.nHCO3 < 24 {         diagnos.resultado3 = "acidosis metabólica"         print ("6")       }       if diagnos.resultado1 == "acidemia" && diagnos.resultado3 == "acidosis metabólica" && (viewModel.expectPCO2aci - 2)...(viewModel.expectPCO2aci + 2) ~= viewModel.npCO2 {         diagnos.resultado4 = "acidosis metabólica compensada"         diagnos.resultado2 = ""         print ("7")         }       if diagnos.resultado1 == "alcalemia" && diagnos.resultado3 == "alcalosis metabólica" && (viewModel.expectALCPCO2 - 0.5)...(viewModel.expectALCPCO2 + 0.5) ~= viewModel.npCO2 {         diagnos.resultado4 = "alcalosis metabólica compensada"         diagnos.resultado3 = ""         print ("8")       }       if diagnos.resultado1 == "alcalemia" && diagnos.resultado2 == "alcalosis respiratoria"         && viewModel.agucro == 1         && (viewModel.expectHCO3alkA - 0.5)...(viewModel.expectHCO3alkA + 0.5) ~= viewModel.nHCO3 {         diagnos.resultado4 = "alcalosis respiratoria compensada"         diagnos.resultado3 = ""         print ("9")       }             }    }
Replies
4
Boosts
0
Views
854
Activity
May ’22
Async/await and maxConcurrentOperationCount
I'm writing an app that performs actions in a web browser automatically on user's behalf. Currently my app uses OperationQueue to perform asynchronous work. I'm trying to rewrite the app to use async/await instead. Note, that it is necessary for my app to limit the number of concurrently executing work items. Otherwise the app may run into server throttling issues. However, I can't find an equivalent to OperationQueue's maxConcurrentOperationCount parameter in the new concurrency model. Is there a way to limit the number of concurrently running "lanes" of execution without resorting to using OperationQueue / DispatchQueue / NSLock ?
Replies
1
Boosts
0
Views
1.5k
Activity
Mar ’22
Using actors in a SwiftUI .task
Hi, having the concurrency checks (-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks) enabled I always get this warning, when trying to access/use an actor in a SwiftUI .task: "Cannot use parameter 'self' with a non-sendable type 'ContentView' from concurrently-executed code". What would be a correct implementation? Here's a minimal code-sample which produces this warning: import SwiftUI struct ContentView: View { @State var someVar = 5 var a1 = A1() var body: some View { Text("Hello, world!") .padding() .task { await a1.doSomething() } } } public actor A1 { func doSomething() { print("Hello") } }
Replies
1
Boosts
0
Views
2.4k
Activity
Feb ’22
Sample code for wwdc21 Actors talk?
In this talk , at 12:00, the speaker refers to code associated with this talk. But I can't find it anywhere. Is it available?
Replies
1
Boosts
0
Views
905
Activity
Jan ’22
Associated Code?
When showing an ImageDownloader actor, the presenter said a solution on avoiding duplicate downloads is shown with the code associated with this video. When will this code be available? I don't see it on the video page.
Replies
6
Boosts
0
Views
2.9k
Activity
Jan ’22
Will TSAN or the Swift compiler identify possible Swift async-await race conditions?
I haven't followed the swift forums very closely, so perhaps there is news buried deep somewhere mentioning this. Will the swift compiler and/or TSAN at runtime in the future be able to identify possible race conditions associated with Swift async-await (excluding data races that are "erased" by async-await)? I suppose this could equate to proving a function is reentrant in some scenarios (from a compiler's perspective, though I'm not knowledgeable about compilers)? Consider, e.g. the scenario described in "Protect Mutable State with Swift Actors" around 9:15, where Dario talks about actor reentrancy, with the cache for the image URL
Replies
0
Boosts
0
Views
752
Activity
Jan ’22
TaskGroup in and Actor
I've had an issue in my project where I trigger a task from a SwiftUI View with the modifier .task. From there it calls and async function into an actor that has a TaskGroup that makes concurrent network calls that has a type of Void.self. I've noticed that sometimes the TaskGroup is either never called and will no longer be called. I'm wondering if perhaps a TaskGroup inside of an Actor that has a parent Task created outside the Actor is a problem? But it does seem to work if I change the Actor to a Class. Could someone help explain to me why this is?
Replies
0
Boosts
0
Views
685
Activity
Aug ’21
actors, SwiftUI and @Published
Hi, is there a way that an actor can have a @MainActor @Published annotated property which is then consumed by a SwiftUI View "as usual"? Currently this: @Published @MainActor public private(set) var state: State = .initial gives me the following error when trying to access it from with a SwiftUI View: "Actor-isolated property '$state' can only be referenced from inside the actor" I guess I understand where the error is coming from, but I wonder if there's a way to publish properties from actors and be able to make sure they are updated on the main thread by annotating them with @MainActor.
Replies
1
Boosts
0
Views
4k
Activity
Aug ’21
Actors and async/await testing before macOS 12?
Is there any way to test async/await and actors on macOS 11? Some sort of runtime toolchain I can install on my dev machine? I've ported some code and would love to test it without upgrading my only dev machine to macOS 12 yet. Thanks! 🙏
Replies
3
Boosts
0
Views
936
Activity
Jul ’21
Entering the actor through two async let calls hangs the app at suspension point.
I have been trying to work with the image downloader code provided in the session to see if I could download two images at once and cache them in the actor. For some reason, when I enter the download method on the actor with two consecutive async let calls, the app hangs at the deepest suspension point. I am providing a very minimum code you can copy and paste into a new iOS Storyboard-based project, replacing the code in ViewController.swift: enum ImageDownloadError: Error {     case badImage } actor ImageDownloader {     private var cache: [URL: UIImage] = [:]     func image(from url: URL) async throws -> UIImage {         if let image = cache[url] {             return image         }         print("Downloading image")         let image = try await downloadImage(url: url)         print("Downloaded image")         cache[url] = image         return image     }     private func downloadImage(url: URL) async throws -> UIImage {         let imageRequest = URLRequest(url: url)         let (data, imageResponse) = try await URLSession.shared.data(for: imageRequest)         guard let image = UIImage(data: data), (imageResponse as? HTTPURLResponse)?.statusCode == 200 else {             throw ImageDownloadError.badImage         }         return image     } } class ViewController: UIViewController {     override func viewDidLoad() {         super.viewDidLoad()         async {             await downloadImages()         }     }     func downloadImages() async {         let downloader = ImageDownloader()         let imageURL = URL(string:  "https://www.andyibanez.com/fairesepages.github.io/tutorials/async-await/part3/3.png")!         async let downloadedImage = downloader.image(from: imageURL)         //async let sameDownloadedImage = downloader.image(from: imageURL) // Uncomment to see the bug         var images = [UIImage?]()         images += [try? await downloadedImage]         //images += [try? await sameDownloadedImage]         print("Finished everything")     } } If you uncomment the code marked as Uncomment to see the bug, you will see that the code will go through many different await calls, but it will hang on the ine in the URLSession.shared.data(for: imageRequest) call. The app just hangs there and doesn't continue executing. Commenting the same line will let it work fine. Are there any known workarounds for this? I would love to get this to work. I have opened a feedback on this, linking it just in case FB9213145
Replies
0
Boosts
0
Views
772
Activity
Jul ’21