also looking at this
feat(ios): signInWithApple, and scanQRCode's real reason — ratchet 25 → 23
#122
6 files
+591
-5
| @@ -58,6 +58,7 @@ const zig_sources = [_][]const u8{ | ||
| 58 | 58 | @embedFile("src/bridge_mobile_health.zig"), |
| 59 | 59 | @embedFile("src/bridge_mobile_speech.zig"), |
| 60 | 60 | @embedFile("src/bridge_mobile_nfc.zig"), |
| 61 | @embedFile("src/bridge_mobile_auth_apple.zig"), | |
| 61 | 62 | }; |
| 62 | 63 | |
| 63 | 64 | /// The action list lives in the `switch action` block, and nowhere else. |
| @@ -106,9 +107,13 @@ const dispatch_end = "func webView("; | ||
| 106 | 107 | /// audio tap, which is the first callback in this migration that runs on a |
| 107 | 108 | /// thread where a lock is a bug rather than a slowdown. |
| 108 | 109 | /// 24 with scanNFC, which had no recorded reason at all — not a deferral that |
| 109 | /// expired, just an action nobody had reached. One framework, one guard, one | |
| 110 | /// small delegate; the four remaining like it are registerPush, scanQRCode and | |
| 111 | /// signInWithApple. | |
| 110 | /// expired, just an action nobody had reached. | |
| 111 | /// 23 with signInWithApple, which needed the first object-returning delegate | |
| 112 | /// method in the migration (`presentationAnchorForAuthorizationController:`). | |
| 113 | /// Of the four that had no recorded reason, scanQRCode turned out to have a | |
| 114 | /// real one and is in the table below; `registerPush` is the last, and its | |
| 115 | /// device token arrives through a notification the Swift app delegate posts, | |
| 116 | /// which is a coupling to weigh rather than a wall. | |
| 112 | 117 | /// 25 with scheduleNotification. Its deferral was the first to expire on its |
| 113 | 118 | /// own: the blocker recorded in `bridge_mobile_notifications.zig` was that |
| 114 | 119 | /// `ios_async` could only resolve, so an action whose two failure paths are |
| @@ -116,7 +121,7 @@ const dispatch_end = "func webView("; | ||
| 116 | 121 | /// and `deliverErrorCode` landed the day after that was written. Worth |
| 117 | 122 | /// re-reading the other deferrals for the same reason before assuming they |
| 118 | 123 | /// still hold. |
| 119 | const max_not_yet_migrated: usize = 24; | |
| 124 | const max_not_yet_migrated: usize = 23; | |
| 120 | 125 | |
| 121 | 126 | fn dispatcherRegion() []const u8 { |
| 122 | 127 | const begin = std.mem.indexOf(u8, swift_spec, dispatch_begin) orelse return ""; |
| @@ -298,6 +303,14 @@ const deliberate_deferrals = [_]Deferral{ | ||
| 298 | 303 | .{ .action = "resumeLocationRecording", .reason = "Coordinator.init re-adopts recordings at launch; Zig cannot stop what Swift restored" }, |
| 299 | 304 | .{ .action = "getLocationRecordingState", .reason = "Coordinator.init re-adopts recordings at launch; Zig cannot stop what Swift restored" }, |
| 300 | 305 | |
| 306 | // VisionKit's `DataScannerViewController` is Swift-only: the framework's | |
| 307 | // Objective-C headers carry DocumentCamera and nothing else, and the | |
| 308 | // delegate callback takes a `RecognizedItem`, a Swift enum with associated | |
| 309 | // values that `objc_msgSend` cannot destructure. Same class of wall as | |
| 310 | // ActivityKit, and checked against the iphonesimulator SDK rather than | |
| 311 | // assumed. | |
| 312 | .{ .action = "scanQRCode", .reason = "VisionKit's DataScanner is Swift-only; the delegate takes a Swift enum with associated values" }, | |
| 313 | ||
| 301 | 314 | // Not a capability gap: the spec's own success path has never executed, so |
| 302 | 315 | // there is no working contract to port. See the tracking issue. |
| 303 | 316 | .{ .action = "startVideoRecording", .reason = "the spec reads info[.originalImage] for a movie pick, so its success path never runs" }, |
| @@ -332,7 +345,7 @@ test "every recorded deferral is real, and still a deferral" { | ||
| 332 | 345 | } |
| 333 | 346 | |
| 334 | 347 | // Non-vacuity: the loop above is satisfied by an empty table. |
| 335 | try testing.expect(deliberate_deferrals.len >= 20); | |
| 348 | try testing.expect(deliberate_deferrals.len >= 22); | |
| 336 | 349 | |
| 337 | 350 | // And the table cannot claim more than remain unmigrated. |
| 338 | 351 | try testing.expect(deliberate_deferrals.len <= max_not_yet_migrated); |