ReviewOS

also looking at this

craft-native/craft

fix(ios): resolve openSettings' selector before the lease, and say why two actions have no deadline

#251
Merged glennmichael123 wants to merge fix/ios-open-settings-lease into main
2 files +25 -2
packages/zig/src/bridge_mobile_permissions.zigmodified+16-2
Changes to packages/zig/src/bridge_mobile_permissions.zig
@@ -530,6 +530,13 @@ pub const PermissionsBridge = struct {
530530 const options = objc.msgSendId(NSDictionary, sel_dictionary) orelse
531531 return bridge_error.BridgeError.NativeCallFailed;
532532
533 // Resolved before the lease (#223). It was looked up after
534 // `publishSettingsCall`, so a failure here released the slot through
535 // the errdefer below but left the ticket parked in `settings_calls`
536 // for a call that had already been refused.
537 const sel_open = objc.sel_registerName("openURL:options:completionHandler:") orelse
538 return bridge_error.BridgeError.NativeCallFailed;
539
533540 const ticket = ios_async.acquire(A.open_settings) orelse {
534541 std.log.warn(
535542 "openSettings: no free reply slot; {d} native calls are already awaiting one",
@@ -540,8 +547,15 @@ pub const PermissionsBridge = struct {
540547 errdefer ios_async.abandon(ticket);
541548 publishSettingsCall(ticket);
542549
543 const sel_open = objc.sel_registerName("openURL:options:completionHandler:") orelse
544 return bridge_error.BridgeError.NativeCallFailed;
550 // No deadline, deliberately, and #223 lists this action for one. The
551 // app is suspended while Settings is open, and the uptime clock is
552 // not: a deadline shorter than the visit fires on resume and races the
553 // completion that was held back with it, answering TIMEOUT for an open
554 // that succeeded. People go to Settings to change something, so a
555 // visit longer than any sensible deadline is the ordinary case, not
556 // the edge. `openURL:options:completionHandler:` is called by UIKit on
557 // every open; the side table below is safe without a deadline because
558 // nothing frees this slot early.
545559 const OpenFn = *const fn (objc.id, objc.SEL, objc.id, objc.id, *anyopaque) callconv(.c) void;
546560 const openFn: OpenFn = @ptrCast(&objc.objc_msgSend);
547561 openFn(app, sel_open, url, options, @ptrCast(&settings_blocks[ticket.index]));