From 008f67663cd0222af5fcadb39939e5fbf22dc0d9 Mon Sep 17 00:00:00 2001
From: "Evan W. Patton" <ewpatton@mit.edu>
Date: Mon, 13 Jan 2025 16:08:16 -0500
Subject: [PATCH] Implement ReceivingState block for iOS

Change-Id: I199628efabea227df8555f72c9891cdd21617541
---
 .../AIComponentKit.xcodeproj/project.pbxproj  |  4 +++
 .../components-ios/src/ReceivingState.swift   | 30 +++++++++++++++++++
 appinventor/components-ios/src/Texting.swift  |  7 +++--
 appinventor/components-ios/src/runtime.scm    |  2 ++
 4 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 appinventor/components-ios/src/ReceivingState.swift

diff --git a/appinventor/AIComponentKit.xcodeproj/project.pbxproj b/appinventor/AIComponentKit.xcodeproj/project.pbxproj
index bd5471c0d2a..329da0fbb02 100644
--- a/appinventor/AIComponentKit.xcodeproj/project.pbxproj
+++ b/appinventor/AIComponentKit.xcodeproj/project.pbxproj
@@ -26,6 +26,7 @@
 		0609147D1DE61B530049B7AB /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0609147B1DE61B530049B7AB /* SQLite.framework */; };
 		0609147E1DE61B530049B7AB /* Toast_Swift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0609147C1DE61B530049B7AB /* Toast_Swift.framework */; };
 		060A83D51E004E1E00C6B7D9 /* JsonUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060A83D41E004E1E00C6B7D9 /* JsonUtil.swift */; };
+		060F4AEE2D35B597005D01BA /* ReceivingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060F4AED2D35B583005D01BA /* ReceivingState.swift */; };
 		06159D8C1DEFE20A00593D30 /* TextBoxBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06159D8B1DEFE20A00593D30 /* TextBoxBase.swift */; };
 		06159D8E1DEFF0C600593D30 /* PasswordTextBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06159D8D1DEFF0C600593D30 /* PasswordTextBox.swift */; };
 		0618A28D1D8CF4EE0013A191 /* AIComponentKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0618A2841D8CF4EE0013A191 /* AIComponentKit.framework */; };
@@ -410,6 +411,7 @@
 		0609147B1DE61B530049B7AB /* SQLite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SQLite.framework; path = "build/Debug-iphoneos/SQLite.swift/SQLite.framework"; sourceTree = "<group>"; };
 		0609147C1DE61B530049B7AB /* Toast_Swift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Toast_Swift.framework; path = "build/Debug-iphoneos/Toast-Swift/Toast_Swift.framework"; sourceTree = "<group>"; };
 		060A83D41E004E1E00C6B7D9 /* JsonUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JsonUtil.swift; sourceTree = "<group>"; };
+		060F4AED2D35B583005D01BA /* ReceivingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceivingState.swift; sourceTree = "<group>"; };
 		06159D8B1DEFE20A00593D30 /* TextBoxBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextBoxBase.swift; sourceTree = "<group>"; };
 		06159D8D1DEFF0C600593D30 /* PasswordTextBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordTextBox.swift; sourceTree = "<group>"; };
 		0618A26D1D8CE3750013A191 /* AIComponentKit-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AIComponentKit-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -1450,6 +1452,7 @@
 				681D59042A84138A007B5DB5 /* FileScope.swift */,
 				06E91E112D2B236800377845 /* LOBFValues.swift */,
 				681D59062A84139E007B5DB5 /* OptionList.swift */,
+				060F4AED2D35B583005D01BA /* ReceivingState.swift */,
 				06208B512BD9D7380097EF43 /* ScreenOrientation.swift */,
 			);
 			name = common;
@@ -1991,6 +1994,7 @@
 				043ACD8B20104F52002C74DD /* DatePicker.swift in Sources */,
 				0644F6C21F37D20700642E4D /* LifecycleDelegate.swift in Sources */,
 				06D151E81DC4FE2A00FC981E /* ElementsUtil.swift in Sources */,
+				060F4AEE2D35B597005D01BA /* ReceivingState.swift in Sources */,
 				080C7FE321077707007C94A8 /* Ev3ResponseManager.swift in Sources */,
 				064884D621E682EA0086411C /* iOS9Util.swift in Sources */,
 				B48808CC2ACFB3780046DF4F /* PointChartView.swift in Sources */,
diff --git a/appinventor/components-ios/src/ReceivingState.swift b/appinventor/components-ios/src/ReceivingState.swift
new file mode 100644
index 00000000000..afbf9730c34
--- /dev/null
+++ b/appinventor/components-ios/src/ReceivingState.swift
@@ -0,0 +1,30 @@
+// -*- mode: swift; swift-mode:basic-offset: 2; -*-
+// Copyright 2025 MIT, All rights reserved
+// Released under the Apache License, Version 2.0
+// http://www.apache.org/licenses/LICENSE-2.0
+
+import Foundation
+
+@objc public class ReceivingState: NSObject, OptionList {
+  @objc public static let Off = ReceivingState(1)
+  @objc public static let Foreground = ReceivingState(2)
+  @objc public static let Always = ReceivingState(3)
+
+  private static let LOOKUP: [Int32:ReceivingState] = generateOptionsLookup(
+    Off, Foreground, Always
+  )
+
+  let value: Int32
+
+  @objc private init(_ value: Int32) {
+    self.value = value
+  }
+
+  @objc class func fromUnderlyingValue(_ value: Int32) -> ReceivingState? {
+    return LOOKUP[value]
+  }
+
+  @objc public func toUnderlyingValue() -> AnyObject {
+    return value as AnyObject
+  }
+}
diff --git a/appinventor/components-ios/src/Texting.swift b/appinventor/components-ios/src/Texting.swift
index 6bf22ea1d99..caf59d927a8 100644
--- a/appinventor/components-ios/src/Texting.swift
+++ b/appinventor/components-ios/src/Texting.swift
@@ -46,11 +46,14 @@ open class Texting: NonvisibleComponent, MFMessageComposeViewControllerDelegate
     }
   }
 
-  @objc open var ReceivingEnabled: Bool {
+  @objc open var ReceivingEnabled: Int32 {
     get {
-      return false  // Receiving messages not supported on iOS
+      return ReceivingState.Off.value  // Receiving messages not supported on iOS
     }
     set(enabled) {
+      if enabled == ReceivingState.Off.value {
+        return  // No state change since Off is the only valid value on iOS.
+      }
       if _form?.isRepl ?? false {
         // Receiving messages not supported on iOS
         _form?.dispatchErrorOccurredEvent(self, "ReceivingEnabled",
diff --git a/appinventor/components-ios/src/runtime.scm b/appinventor/components-ios/src/runtime.scm
index 284eb4da99b..443d7b3e2e0 100644
--- a/appinventor/components-ios/src/runtime.scm
+++ b/appinventor/components-ios/src/runtime.scm
@@ -377,6 +377,8 @@
    ((number? arg) arg)
    ((string? arg)
     (or (padded-string->number arg) *non-coercible-value*))
+   ((yail:isa arg AIComponentKit.OptionList)
+    (coerce-to-number (yail:invoke arg 'toUnderlyingValue)))
    (else *non-coercible-value*)))
 
 (define (coerce-to-key arg)