Post

Replies

Boosts

Views

Activity

Reply to UIAlertController sometimes does not call its UIAlertAction handler
Ed Ford, Apple DTS Engineer asked: Does your app tinker with the run loops as part of your alert presentation? No, a search in our code for the string “runloop” (case insensitive) finds matches only in two third-party components that are not involved in the alert presentation: https://github.com/jdg/MBProgressHUD/blob/master/MBProgressHUD.m https://github.com/MortimerGoro/MGSwipeTableCell/blob/master/MGSwipeTableCell/MGSwipeTableCell.m Here are a few more details about our alert presentation function in case they are relevant: The function and its callers are written in Objective-C. The function must be called on a secondary thread. It enforces this by verifying at the top of the function that NSThread.isMainThread is false. There is a local variable called “response”, of an enum type, to store which alert action the user chose. It is initialized to a value meaning “unknown”. The function calls dispatch_async(dispatch_get_main_queue(), ...) with a block that creates and presents the alert. The action handlers all contain code to set the “response” variable. The function then waits for a user response to the alert. Originally the wait code used a GCD semaphore (the alert action handlers called dispatch_semaphore_signal). When we noticed the uncalled handler problem, we tried switching to a POSIX semaphore. Then we tried avoiding semaphores altogether, instead using a polling loop that checks every 100ms (via usleep) to see if the “response” variable is set. The uncalled handler problem has persisted under all three methods of waiting for a user response. If and when an action handler is called and the “response” variable is set, the alert presentation function returns the value of the “response” variable.
Topic: UI Frameworks SubTopic: UIKit Tags:
Mar ’25
Reply to UIAlertController sometimes does not call its UIAlertAction handler
To be clear, even when the alert action handler doesn’t get called, we do see subsequent logging from other functions that run on the main thread, such as gesture handlers, applicationWillResignActive, etc. So we know that the main thread has not hung. Is this consistent with the other instances of this issue you’ve seen? I will certainly use a callback if I have to. The alert presentation function is used in about a dozen different places; we’ve seen the uncalled handler problem only for the most frequently shown action sheet, but if I understand you correctly the same problem could occur anywhere the function is used. The motivation for semaphores/polling was that, like the old NSAlert runModal function, it allows the caller to have straightforward linear code. (Using async/await was not an option because using Objective-C rather than Swift was a requirement of the project.) A possibly related WWDC video says, “A common anti-pattern is trying to make an asynchronous API act synchronous by waiting on a semaphore. This should always be avoided on the main thread.” https://developer.apple.com/videos/play/wwdc2021/10258?time=550 I thought this meant that the main thread should never wait on a semaphore. Should the main thread also never signal a semaphore, as in the alert case? What if both the waiting thread and the signaling thread are secondary threads? I’m asking because there are a few other places where our code uses a semaphore “to make an asynchronous API act synchronous,” always in an effort to allow linear code.
Topic: UI Frameworks SubTopic: UIKit Tags:
Mar ’25