Post

Replies

Boosts

Views

Activity

iPhone Duo supports multiple windows but `requestSceneSessionDestruction` fails due to unsupported device idiom
Problem: iPhone Duo supports multiple windows using Split Views. However, we cannot programmatically close windows using requestSceneSessionDestruction because we get the following error: "This functionality is not supported for this device idiom." This seems like a miss in Apple's requestSceneSessionDestruction implementation. If the Duo is going to let users open multiple windows (where supportsMultipleScenes is true for the Duo), then developers should be able to close them via requestSceneSessionDestruction, too. 🤔 Is this a bug? I have filed a ticket here in case it is: FB25353479 Additional implementation details: Our app supports multiple windows on iPad devices. The Duo is the first phone to support multiple windows as well. For user convenience, our app has an option to combine information from all windows and then collapse everything down to one single window. We use requestSceneSessionDestruction to close the extraneous windows afterward. This works great on iPad, but we get the unsupported device idiom error on the Duo only. We have no way of closing windows programmatically as far as I can tell.
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
99
6d
Crashes because main actor isolated closures are called on a background thread with `DispatchGroup.notify`, but no compiler warnings
Hello! We are in the progress of migrating a large Swift 5.10 legacy code base over to use Swift 6.0 with Strict Concurrency checking. We have already stumbled across a few weird edge cases where the "guaranteed" @MainActor isolation is violated (such as with @objc #selector methods used with NotificationCenter). However, we recently found a new scenario where our app crashes accessing main actor isolated state on a background thread, and it was surprising that the compiler couldn't warn us. Minimal reproducible example: class ViewController: UIViewController { var isolatedStateString = "Some main actor isolated state" override func viewDidLoad() { exampleMethod() } /// Note: A `@MainActor` isolated method in a `@MainActor` isolated class. func exampleMethod() { testAsyncMethod() { [weak self] in // !!! Crash !!! MainActor.assertIsolated() // This callback inherits @MainActor from the class definition, but it is called on a background thread. // It is an error to mutate main actor isolated state off the main thread... self?.isolatedStateString = "Let me mutate my isolated state" } } func testAsyncMethod(completionHandler: (@escaping () -> Void)) { let group = DispatchGroup() let queue = DispatchQueue.global() // The compiler is totally fine with calling this on a background thread. group.notify(queue: queue) { completionHandler() } // The below code at least gives us a compiler warning to add `@Sendable` to our closure argument, which is helpful. // DispatchQueue.global().async { // completionHandler() // } } } The problem: In the above code, the completionHandler implementation inherits main actor isolation from the UIViewController class. However, when we call exampleMethod(), we crash because the completionHandler is called on a background thread via the DispatchGroup.notify(queue:). If were to instead use DispatchQueue.global().async (snippet at the bottom of the sample), the compiler helpfully warns us that completionHandler must be Sendable. Unfortunately, DispatchGroup's notify gives us no such compiler warnings. Thus, we crash at runtime. So my questions are: Why can't the compiler warn us about a potential problem with DispatchGroup().notify(queue:) like it can with DispatchQueue.global().async? How can we address this problem in a holistic way in our app, as it's a very simple mistake to make (with very bad consequences) while we migrate off GCD? I'm sure the broader answer here is "don't mix GCD and Concurrency", but unfortunately that's a little unavoidable as we migrate our large legacy code base! 🙂
3
3
1.4k
Nov ’25
iPhone Duo supports multiple windows but `requestSceneSessionDestruction` fails due to unsupported device idiom
Problem: iPhone Duo supports multiple windows using Split Views. However, we cannot programmatically close windows using requestSceneSessionDestruction because we get the following error: "This functionality is not supported for this device idiom." This seems like a miss in Apple's requestSceneSessionDestruction implementation. If the Duo is going to let users open multiple windows (where supportsMultipleScenes is true for the Duo), then developers should be able to close them via requestSceneSessionDestruction, too. 🤔 Is this a bug? I have filed a ticket here in case it is: FB25353479 Additional implementation details: Our app supports multiple windows on iPad devices. The Duo is the first phone to support multiple windows as well. For user convenience, our app has an option to combine information from all windows and then collapse everything down to one single window. We use requestSceneSessionDestruction to close the extraneous windows afterward. This works great on iPad, but we get the unsupported device idiom error on the Duo only. We have no way of closing windows programmatically as far as I can tell.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
99
Activity
6d
Crashes because main actor isolated closures are called on a background thread with `DispatchGroup.notify`, but no compiler warnings
Hello! We are in the progress of migrating a large Swift 5.10 legacy code base over to use Swift 6.0 with Strict Concurrency checking. We have already stumbled across a few weird edge cases where the "guaranteed" @MainActor isolation is violated (such as with @objc #selector methods used with NotificationCenter). However, we recently found a new scenario where our app crashes accessing main actor isolated state on a background thread, and it was surprising that the compiler couldn't warn us. Minimal reproducible example: class ViewController: UIViewController { var isolatedStateString = "Some main actor isolated state" override func viewDidLoad() { exampleMethod() } /// Note: A `@MainActor` isolated method in a `@MainActor` isolated class. func exampleMethod() { testAsyncMethod() { [weak self] in // !!! Crash !!! MainActor.assertIsolated() // This callback inherits @MainActor from the class definition, but it is called on a background thread. // It is an error to mutate main actor isolated state off the main thread... self?.isolatedStateString = "Let me mutate my isolated state" } } func testAsyncMethod(completionHandler: (@escaping () -> Void)) { let group = DispatchGroup() let queue = DispatchQueue.global() // The compiler is totally fine with calling this on a background thread. group.notify(queue: queue) { completionHandler() } // The below code at least gives us a compiler warning to add `@Sendable` to our closure argument, which is helpful. // DispatchQueue.global().async { // completionHandler() // } } } The problem: In the above code, the completionHandler implementation inherits main actor isolation from the UIViewController class. However, when we call exampleMethod(), we crash because the completionHandler is called on a background thread via the DispatchGroup.notify(queue:). If were to instead use DispatchQueue.global().async (snippet at the bottom of the sample), the compiler helpfully warns us that completionHandler must be Sendable. Unfortunately, DispatchGroup's notify gives us no such compiler warnings. Thus, we crash at runtime. So my questions are: Why can't the compiler warn us about a potential problem with DispatchGroup().notify(queue:) like it can with DispatchQueue.global().async? How can we address this problem in a holistic way in our app, as it's a very simple mistake to make (with very bad consequences) while we migrate off GCD? I'm sure the broader answer here is "don't mix GCD and Concurrency", but unfortunately that's a little unavoidable as we migrate our large legacy code base! 🙂
Replies
3
Boosts
3
Views
1.4k
Activity
Nov ’25