ReviewOS

craft-native/craft

fix(ios): five page calls drop the answer the native side sends them

#207
Closed glennmichael123 opened this 10 days ago ·
10 days ago

The iOS page script posts five actions with no callbackId, and the Swift dispatcher answers all five anyway. resolveCallback and rejectCallback both open with guard let id = callbackId else { return }, so every one of those answers is thrown away. This is the same shape as #203 (share), which is being fixed separately.

page callpostswhat the native side says that the page never hears
craft.haptic(style){action: 'haptic', style}CAPABILITY_DISABLED when enableHaptics is off
craft.startListening(){action: 'startListening'}CAPABILITY_DISABLED when enableSpeechRecognition is off
craft.geolocation.watchPosition(cb){action: 'watchPosition'}CAPABILITY_DISABLED when enableGeolocation is off; the callback simply never fires
craft.geolocation.clearWatch() and craft.location.clearWatch(id){action: 'clearWatch'}true
craft.vibrate(pattern){action: 'vibrate', pattern}true

The first three are the ones that hurt. A page that calls them with the capability disabled gets no error and no event, which reads the same as "still waiting". The contract wrappers make it worse: craft.haptics.impact() returns Promise.resolve() after calling craft.haptic, so it reports success for a call that was refused.

The last two only lose a true. They are listed because they have the same shape, and a page cannot tell a lost true from a lost rejection.

What guards it now

ios_conformance_test.zig scans every postMessage in the page script. It fails when a post carries no callbackId for an action whose Swift case answers through one, unless the action is on a recorded list. These five are that list. The second half of the test fails when a listed action gets fixed without being removed, so the list can only shrink.

Fixing one

Give the page method a callbackId and return the promise, the way openCamera does. Then take the action off unanswered_posts. For haptic and vibrate, also check the craft.haptics wrappers, which currently return Promise.resolve() whatever native says.

Found while fixing #203.

Sign in to comment on this issue.