I need to make it a bit more deliberate use of the swizzle, but it solves my weird bug. If you present a SFSafariViewController it will remove everything behind it from the view heirarchy. In this case, the rootViewController.
However, the onChange() modifier isn’t called while offscreen… so programmatic dismissal driven by that modifier would fail to dismiss the browser. One simple Bool, but it’s overridden by subclassing and one cannot simply subclass a private type.
Selective method swizzling through an Objective-C category was the only real option I could think of. Despite avoiding swizzling for years, it’s a harmless modification so I’m kinda okay with it.
Fun to implement stuff I’ve only read about, really showed me some pitfalls. Particularly after digging through some of the details in header files [developer.limneos.net]
Well, swizzling kinda worked but would apply changes on a class level. What I ended up going with is called isa pointer swizzling [stackoverflow.com], and I think it might be how they manage class clusters like NSArray in Objective-C land.
In this one case, I have a dummy class that inherits from the same public base class and implements the needed property override. Using object_setClass seems to allow using my overridden method while others are forwarded to the original implementation.
Extracted everything into a separate submodule and documented the actual swizzling solution for future me. I'm really happy with the outcome, sits right along side the existing API but with a few more niceties and parameters.
For example, item identity is provided as a KeyPath parameter (like a ForEach) instead of a protocol requirement. Alerts have onDismiss callbacks, and you can present UIViewControllers in a ViewBuilder like fashion.