diff --git a/DemoApp/Demo/TypeSwift/TypeSwift.swift b/DemoApp/Demo/TypeSwift/TypeSwift.swift index 8c34e14..fd65ede 100644 --- a/DemoApp/Demo/TypeSwift/TypeSwift.swift +++ b/DemoApp/Demo/TypeSwift/TypeSwift.swift @@ -11,6 +11,13 @@ /// An enumeration of TypeScript identifiers generated to be used in Swift code. enum TypeSwift { + // State Variables + case total(_ value: Double) + case textFieldValue(_ value: String) + case switchValue(_ value: Bool) + case selectedDevice(_ device: Device) + case selectedOS(_ os: OperatingSystems) + // Functions case updateTotal(_ value: Double) case updateDeviceDropdown(_ device: Device) @@ -20,6 +27,13 @@ enum TypeSwift { var jsString: String { switch self { + case .total(let value): return "total.value = \(value)" + case .textFieldValue(let value): return "textFieldValue.value = `\(value)`" + case .switchValue(let value): return "switchValue.value = \(value)" + case .selectedDevice(let device): return "selectedDevice.value = Device.\(device)" + case .selectedOS(let os): return "selectedOS.value = OperatingSystems.\(os)" + + // Functions case .updateTotal(let value): return "updateTotal(\(value))" case .updateDeviceDropdown(let device): return "updateDeviceDropdown(Device.\(device))" case .updateOSDropdown(let os): return "updateOSDropdown(OperatingSystems.\(os))" @@ -43,6 +57,13 @@ import WebKit extension TypeSwift { enum MessageHandlers { + case total((Double) -> Void) + case textFieldValue((String) -> Void) + case switchValue((Bool) -> Void) + case selectedDevice((Device) -> Void) + case selectedOS((OperatingSystems) -> Void) + + // Static Functions case updateTotal((Double) -> Void) case updateTextField((String) -> Void) case updateDeviceDropdown((Device) -> Void) @@ -51,6 +72,13 @@ extension TypeSwift { var name: String { switch self { + case .total: return "total" + case .textFieldValue: return "textFieldValue" + case .switchValue: return "switchValue" + case .selectedDevice: return "selectedDevice" + case .selectedOS: return "selectedOS" + + // Static Functions case .updateTotal: return "updateTotal" case .updateTextField: return "updateTextField" case .updateDeviceDropdown: return "updateDeviceDropdown" @@ -61,18 +89,41 @@ extension TypeSwift { func handle(message: WKScriptMessage) { switch self { + case .total(let callback): + if let value = message.body as? Double { + callback(value) + } + case .textFieldValue(let callback): + if let value = message.body as? String { + callback(value) + } + case .selectedDevice(let callback): + if let deviceData = message.body as? String, + let device = Device(rawValue: deviceData) { + callback(device) + } + case .selectedOS(let callback): + if let osData = message.body as? String, + let os = OperatingSystems(rawValue: osData) { + callback(os) + } + case .switchValue(let callback): + if let value = message.body as? Bool { + callback(value) + } + + // Static Functions case .updateTotal(let callback): if let value = message.body as? Double { callback(value) } case .updateTextField(let callback): - if let text = message.body as? String { - callback(text) + if let value = message.body as? String { + callback(value) } case .updateDeviceDropdown(let callback): if let deviceData = message.body as? String, - let data = deviceData.data(using: .utf8), - let device = try? JSONDecoder().decode(Device.self, from: data) { + let device = Device(rawValue: deviceData) { callback(device) } case .updateOSDropdown(let callback): @@ -81,8 +132,8 @@ extension TypeSwift { callback(os) } case .updateSwitch(let callback): - if let switchValue = message.body as? Bool { - callback(switchValue) + if let value = message.body as? Bool { + callback(value) } } } diff --git a/DemoApp/Demo/Views/Pages/ComponentsView/ComponentsView.swift b/DemoApp/Demo/Views/Pages/ComponentsView/ComponentsView.swift index 941e586..18bf2ea 100644 --- a/DemoApp/Demo/Views/Pages/ComponentsView/ComponentsView.swift +++ b/DemoApp/Demo/Views/Pages/ComponentsView/ComponentsView.swift @@ -10,8 +10,8 @@ import SwiftUI struct ComponentsView: View { let manager: ObservableWebViewManager - @State private var textFieldValue: String = "" @State private var total: Double = 0 + @State private var textFieldValue: String = "" @State private var selectedDevice: TypeSwift.Device = .Phone @State private var selectedOS: TypeSwift.OperatingSystems = .iOS @State private var switchValue: Bool = true @@ -21,19 +21,19 @@ struct ComponentsView: View { HStack(spacing: 0) { ObservableWebView(manager: manager) .frame(width: geometry.size.width / 2) - .tsMessageHandler(.updateTotal { newValue in + .tsMessageHandler(.total { newValue in total = newValue }, manager: manager) - .tsMessageHandler(.updateTextField { newValue in + .tsMessageHandler(.textFieldValue { newValue in textFieldValue = newValue }, manager: manager) - .tsMessageHandler(.updateDeviceDropdown { newValue in + .tsMessageHandler(.selectedDevice { newValue in selectedDevice = newValue }, manager: manager) - .tsMessageHandler(.updateOSDropdown { newValue in + .tsMessageHandler(.selectedOS { newValue in selectedOS = newValue }, manager: manager) - .tsMessageHandler(.updateSwitch { newValue in + .tsMessageHandler(.switchValue { newValue in switchValue = newValue }, manager: manager) @@ -44,10 +44,10 @@ struct ComponentsView: View { ComponentSection(header: "Buttons") { HStack { PrimaryButton("+1", foreground: .white, background: .blue) { - manager.ts(.updateTotal(total + 1)) + manager.ts(.total(total + 1)) } PrimaryButton("-1", foreground: .white, background: .red) { - manager.ts(.updateTotal(total - 1)) + manager.ts(.total(total - 1)) } Text("\(total, specifier: "%.0f")") .font(.system(size: 14, weight: .medium)) @@ -57,7 +57,7 @@ struct ComponentsView: View { ComponentSection(header: "TextField") { PrimaryTextField(text: $textFieldValue) .onChange(of: textFieldValue) { - manager.ts(.updateTextField(textFieldValue)) + manager.ts(.textFieldValue(textFieldValue)) } } @@ -66,12 +66,12 @@ struct ComponentsView: View { MonoSubheader("enum") EnumDropdownMenu(selection: $selectedDevice) .onChange(of: selectedDevice) { - manager.ts(.updateDeviceDropdown(selectedDevice)) + manager.ts(.selectedDevice(selectedDevice)) } MonoSubheader("const") EnumDropdownMenu(selection: $selectedOS) .onChange(of: selectedOS) { - manager.ts(.updateOSDropdown(selectedOS)) + manager.ts(.selectedOS(selectedOS)) } } } @@ -79,7 +79,7 @@ struct ComponentsView: View { ComponentSection(header: "Switch") { LargeSwitch(state: $switchValue) .onChange(of: switchValue) { - manager.ts(.updateSwitch(switchValue)) + manager.ts(.switchValue(switchValue)) } } } diff --git a/ReactDemo/src/app/swift-components/layout.tsx b/ReactDemo/src/app/swift-components/layout.tsx index d4d2e7a..83c54d0 100644 --- a/ReactDemo/src/app/swift-components/layout.tsx +++ b/ReactDemo/src/app/swift-components/layout.tsx @@ -2,8 +2,12 @@ import { FC, ReactNode } from 'react'; const SwiftComponentsLayout: FC<{ children: ReactNode }> = ({ children }) => { return ( -
This is a React web app
+This is a React web app
-