@craft-native/ios 0.0.99 → 0.0.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -19,6 +19,8 @@ export interface CraftConfig {
19
19
  backgroundColor?: string;
20
20
  /** The launch and webview background while the phone is in Dark Mode. */
21
21
  backgroundColorDark?: string;
22
+ /** Edge-swipe back and forward through the page's history, pushState entries included. */
23
+ swipeNavigation?: boolean;
22
24
  enableSpeechRecognition?: boolean;
23
25
  enableHaptics?: boolean;
24
26
  enableShare?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craft-native/ios",
3
- "version": "0.0.99",
3
+ "version": "0.0.100",
4
4
  "homepage": "https://github.com/craft-native/craft/tree/main/packages/ios#readme",
5
5
  "repository": {
6
6
  "type": "git",
@@ -359,6 +359,8 @@ struct CraftConfig: Codable {
359
359
  var backgroundColor: String = "#1a1a2e"
360
360
  /// The background while the phone is in Dark Mode; the light one if unset.
361
361
  var backgroundColorDark: String? = nil
362
+ /// Edge-swipe back and forward through the page's history.
363
+ var swipeNavigation: Bool? = nil
362
364
  var enableSpeechRecognition: Bool = false
363
365
  var enableHaptics: Bool = false
364
366
  var enableShare: Bool = false
@@ -530,6 +532,13 @@ struct CraftWebView: UIViewRepresentable {
530
532
  let webView = WKWebView(frame: .zero, configuration: webConfig)
531
533
  webView.navigationDelegate = context.coordinator
532
534
  webView.isOpaque = false
535
+ // An edge swipe goes back (and forward) through the page's history,
536
+ // pushState entries included, the way every iOS app's stack does.
537
+ webView.allowsBackForwardNavigationGestures = config.swipeNavigation ?? false
538
+ #if DEBUG
539
+ // Safari's Develop menu can attach to a debug build; never a release.
540
+ if #available(iOS 16.4, *) { webView.isInspectable = true }
541
+ #endif
533
542
 
534
543
  // Before any message can be offered. Zig evaluates every reply against
535
544
  // this webview, and without it an action would run, succeed, and reach
@@ -1301,7 +1310,7 @@ struct CraftWebView: UIViewRepresentable {
1301
1310
  case "requestHealthAuthorization":
1302
1311
  if config.enableHealthKit {
1303
1312
  let types = body["types"] as? [String] ?? []
1304
- requestHealthAuthorization(types: types, callbackId: callbackId)
1313
+ requestHealthAuthorization(types: types, readOnly: body["readOnly"] as? Bool ?? false, callbackId: callbackId)
1305
1314
  } else {
1306
1315
  rejectCallback(callbackId, error: "HealthKit is disabled", code: "CAPABILITY_DISABLED")
1307
1316
  }
@@ -3239,19 +3248,28 @@ struct CraftWebView: UIViewRepresentable {
3239
3248
  var legacyNotifications = craft.notifications;
3240
3249
 
3241
3250
  craft.contractVersion = '1.0.0';
3251
+ // Actions answered by a person, through a system sheet they
3252
+ // may take a minute to read. Thirty seconds of reading the
3253
+ // HealthKit sheet used to fail the call while the sheet was
3254
+ // still open; these wait for the answer instead.
3255
+ var personFacing = {
3256
+ requestHealthAuthorization: true,
3257
+ requestPermission: true,
3258
+ signInWithApple: true
3259
+ };
3242
3260
  craft._invoke = function(action, payload) {
3243
3261
  var self = craft;
3244
3262
  var id = 'cb_' + (++self._callbackId);
3245
3263
  var message = Object.assign({}, payload || {}, {action: action, callbackId: id});
3246
3264
  window.webkit.messageHandlers.craft.postMessage(message);
3247
3265
  return new Promise(function(resolve, reject) {
3248
- var timeout = setTimeout(function() {
3266
+ var timeout = personFacing[action] ? null : setTimeout(function() {
3249
3267
  delete self._callbacks[id];
3250
3268
  reject(new Error('Craft bridge timed out: ' + action));
3251
3269
  }, 30000);
3252
3270
  self._callbacks[id] = {
3253
- resolve: function(value) { clearTimeout(timeout); resolve(value); },
3254
- reject: function(error) { clearTimeout(timeout); reject(error); }
3271
+ resolve: function(value) { if (timeout) clearTimeout(timeout); resolve(value); },
3272
+ reject: function(error) { if (timeout) clearTimeout(timeout); reject(error); }
3255
3273
  };
3256
3274
  });
3257
3275
  };
@@ -3387,7 +3405,9 @@ struct CraftWebView: UIViewRepresentable {
3387
3405
  readRecording: function() { return craft._invoke('readLocationRecording'); }
3388
3406
  };
3389
3407
  craft.health = {
3390
- requestAuthorization: function(types) { return craft._invoke('requestHealthAuthorization', {types: types || []}); },
3408
+ requestAuthorization: function(types, options) {
3409
+ return craft._invoke('requestHealthAuthorization', {types: types || [], readOnly: Boolean(options && options.write === false)});
3410
+ },
3391
3411
  getData: function(type, options) {
3392
3412
  options = options || {};
3393
3413
  return craft._invoke('getHealthData', {type: type, startDate: options.startDate, endDate: options.endDate});
@@ -5125,7 +5145,7 @@ struct CraftWebView: UIViewRepresentable {
5125
5145
  }
5126
5146
 
5127
5147
  // MARK: - Health
5128
- private func requestHealthAuthorization(types: [String], callbackId: String?) {
5148
+ private func requestHealthAuthorization(types: [String], readOnly: Bool = false, callbackId: String?) {
5129
5149
  guard let healthStore = healthStore else {
5130
5150
  rejectCallback(callbackId, error: "HealthKit not available")
5131
5151
  return
@@ -5188,6 +5208,9 @@ struct CraftWebView: UIViewRepresentable {
5188
5208
  }
5189
5209
  }
5190
5210
 
5211
+ // A page that only reads asks only to read: the sheet then says
5212
+ // "access", not "access and update".
5213
+ if readOnly { shareTypes.removeAll() }
5191
5214
  healthStore.requestAuthorization(toShare: shareTypes, read: readTypes) { [weak self] success, error in
5192
5215
  if success {
5193
5216
  self?.resolveCallback(callbackId, result: true)