ReviewOS

also looking at this

craft-native/craft

fix(ios): answer a malformed argument instead of leaving the page waiting

#246
Merged glennmichael123 wants to merge fix/ios-invalid-argument into main
2 files +136 -0
packages/ios/templates/CraftApp.swiftmodified+26-0
Changes to packages/ios/templates/CraftApp.swift
@@ -863,6 +863,8 @@ struct CraftWebView: UIViewRepresentable {
863863 case "setBadge":
864864 if let count = body["count"] as? Int {
865865 setBadgeCount(count, callbackId: callbackId)
866 } else {
867 rejectCallback(callbackId, error: "setBadge needs a whole number of badges", code: "INVALID_ARGUMENT")
866868 }
867869 case "clearBadge":
868870 setBadgeCount(0, callbackId: callbackId)
@@ -877,6 +879,8 @@ struct CraftWebView: UIViewRepresentable {
877879 case "setFlashlight":
878880 if let enabled = body["enabled"] as? Bool {
879881 setFlashlight(enabled: enabled, callbackId: callbackId)
882 } else {
883 rejectCallback(callbackId, error: "setFlashlight needs true or false", code: "INVALID_ARGUMENT")
880884 }
881885 // Vibrate pattern
882886 case "vibrate":
@@ -891,6 +895,8 @@ struct CraftWebView: UIViewRepresentable {
891895 if let urlString = body["url"] as? String, let url = URL(string: urlString) {
892896 UIApplication.shared.open(url)
893897 resolveCallback(callbackId, result: true)
898 } else {
899 rejectCallback(callbackId, error: "openURL needs a URL it can parse", code: "INVALID_ARGUMENT")
894900 }
895901 // App state
896902 case "getAppState":
@@ -1298,6 +1304,8 @@ struct CraftWebView: UIViewRepresentable {
12981304 case "setShortcuts":
12991305 if let shortcuts = body["shortcuts"] as? [[String: Any]] {
13001306 setAppShortcuts(shortcuts: shortcuts, callbackId: callbackId)
1307 } else {
1308 rejectCallback(callbackId, error: "setShortcuts needs a list of shortcuts", code: "INVALID_ARGUMENT")
13011309 }
13021310 case "clearShortcuts":
13031311 clearAppShortcuts(callbackId: callbackId)
@@ -1308,16 +1316,22 @@ struct CraftWebView: UIViewRepresentable {
13081316 let value = body["value"] as? String {
13091317 let group = body["group"] as? String
13101318 setSharedKeychainItem(key: key, value: value, group: group, callbackId: callbackId)
1319 } else {
1320 rejectCallback(callbackId, error: "setSharedItem needs both a key and a value", code: "INVALID_ARGUMENT")
13111321 }
13121322 case "getSharedItem":
13131323 if let key = body["key"] as? String {
13141324 let group = body["group"] as? String
13151325 getSharedKeychainItem(key: key, group: group, callbackId: callbackId)
1326 } else {
1327 rejectCallback(callbackId, error: "getSharedItem needs a key", code: "INVALID_ARGUMENT")
13161328 }
13171329 case "removeSharedItem":
13181330 if let key = body["key"] as? String {
13191331 let group = body["group"] as? String
13201332 removeSharedKeychainItem(key: key, group: group, callbackId: callbackId)
1333 } else {
1334 rejectCallback(callbackId, error: "removeSharedItem needs a key", code: "INVALID_ARGUMENT")
13211335 }
13221336
13231337 // MARK: - Local Auth Persistence
@@ -1325,6 +1339,8 @@ struct CraftWebView: UIViewRepresentable {
13251339 if let enabled = body["enabled"] as? Bool {
13261340 let duration = body["duration"] as? Double ?? 300 // 5 min default
13271341 setBiometricPersistence(enabled: enabled, duration: duration, callbackId: callbackId)
1342 } else {
1343 rejectCallback(callbackId, error: "setBiometricPersistence needs true or false", code: "INVALID_ARGUMENT")
13281344 }
13291345 case "checkBiometricPersistence":
13301346 checkBiometricPersistence(callbackId: callbackId)
@@ -1408,6 +1424,8 @@ struct CraftWebView: UIViewRepresentable {
14081424 case "updateWidget":
14091425 if let data = body["data"] as? [String: Any] {
14101426 updateWidget(data: data, callbackId: callbackId)
1427 } else {
1428 rejectCallback(callbackId, error: "updateWidget needs a data object", code: "INVALID_ARGUMENT")
14111429 }
14121430 case "reloadWidgets":
14131431 reloadAllWidgets(callbackId: callbackId)
@@ -1417,20 +1435,28 @@ struct CraftWebView: UIViewRepresentable {
14171435 if let phrase = body["phrase"] as? String,
14181436 let action = body["shortcutAction"] as? String {
14191437 registerSiriShortcut(phrase: phrase, action: action, callbackId: callbackId)
1438 } else {
1439 rejectCallback(callbackId, error: "registerSiriShortcut needs both a phrase and a shortcutAction", code: "INVALID_ARGUMENT")
14201440 }
14211441 case "removeSiriShortcut":
14221442 if let action = body["shortcutAction"] as? String {
14231443 removeSiriShortcut(action: action, callbackId: callbackId)
1444 } else {
1445 rejectCallback(callbackId, error: "removeSiriShortcut needs a shortcutAction", code: "INVALID_ARGUMENT")
14241446 }
14251447
14261448 // MARK: - Watch Connectivity
14271449 case "sendToWatch":
14281450 if let message = body["message"] as? [String: Any] {
14291451 sendMessageToWatch(message: message, callbackId: callbackId)
1452 } else {
1453 rejectCallback(callbackId, error: "sendToWatch needs a message object", code: "INVALID_ARGUMENT")
14301454 }
14311455 case "updateWatchContext":
14321456 if let context = body["context"] as? [String: Any] {
14331457 updateWatchContext(context: context, callbackId: callbackId)
1458 } else {
1459 rejectCallback(callbackId, error: "updateWatchContext needs a context object", code: "INVALID_ARGUMENT")
14341460 }
14351461 case "isWatchReachable":
14361462 isWatchReachable(callbackId: callbackId)