Skip to content

Commit dc49648

Browse files
feat: implement Voice Dictation feature for iOS keyboard extension
- Enabled local binaries for development in Package.swift. - Added VoiceDictationManagementView and ViewModel for managing dictation settings and history. - Introduced FlowSessionManager to handle audio recording and transcription flow. - Created shared constants and data bridge for inter-process communication between the main app and keyboard extension. - Updated Info.plist for keyboard extension with necessary permissions and configurations. - Integrated deep linking to start dictation sessions from the keyboard. This commit lays the groundwork for a fully functional voice dictation feature in the RunAnywhereAI iOS app.
1 parent c3f08d2 commit dc49648

16 files changed

Lines changed: 1857 additions & 2 deletions

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import Foundation
3737
// ./scripts/build-swift.sh --set-remote (sets useLocalBinaries = false)
3838
//
3939
// =============================================================================
40-
let useLocalBinaries = false // Toggle: true for local dev, false for release
40+
let useLocalBinaries = true // Toggle: true for local dev, false for release
4141

4242
// Version for remote XCFrameworks (used when testLocal = false)
4343
// Updated automatically by CI/CD during releases

examples/ios/RunAnywhereAI/RunAnywhereAI.xcodeproj/project.pbxproj

Lines changed: 198 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88

99
/* Begin PBXBuildFile section */
1010
541C59DA2E63772A00DD7839 /* RunAnywhere in Frameworks */ = {isa = PBXBuildFile; productRef = 541C59D92E63772A00DD7839 /* RunAnywhere */; };
11+
54398AC52F492D1D009D6B51 /* RunAnywhereKeyboard.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54398ABE2F492D1D009D6B51 /* RunAnywhereKeyboard.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1112
58ABEDD22ED16DA40058D033 /* RunAnywhereONNX in Frameworks */ = {isa = PBXBuildFile; productRef = 58ABEDD12ED16DA40058D033 /* RunAnywhereONNX */; };
1213
58LLAMACPP12ED16DA40058D0 /* RunAnywhereLlamaCPP in Frameworks */ = {isa = PBXBuildFile; productRef = 58LLAMACPP02ED16DA40058D0 /* RunAnywhereLlamaCPP */; };
14+
RACSHARED01RACSHARED01RACS /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = RACSHARED02RACSHARED02RACS /* SharedConstants.swift */; };
15+
RACSHARED03RACSHARED03RACS /* SharedDataBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = RACSHARED04RACSHARED04RACS /* SharedDataBridge.swift */; };
1316
/* End PBXBuildFile section */
1417

1518
/* Begin PBXContainerItemProxy section */
19+
54398AC32F492D1D009D6B51 /* PBXContainerItemProxy */ = {
20+
isa = PBXContainerItemProxy;
21+
containerPortal = 5480A1E82E2F250200337F2F /* Project object */;
22+
proxyType = 1;
23+
remoteGlobalIDString = 54398ABD2F492D1D009D6B51;
24+
remoteInfo = RunAnywhereKeyboard;
25+
};
1626
5480A1FF2E2F250400337F2F /* PBXContainerItemProxy */ = {
1727
isa = PBXContainerItemProxy;
1828
containerPortal = 5480A1E82E2F250200337F2F /* Project object */;
@@ -29,19 +39,64 @@
2939
};
3040
/* End PBXContainerItemProxy section */
3141

42+
/* Begin PBXCopyFilesBuildPhase section */
43+
54398AC62F492D1D009D6B51 /* Embed Foundation Extensions */ = {
44+
isa = PBXCopyFilesBuildPhase;
45+
buildActionMask = 2147483647;
46+
dstPath = "";
47+
dstSubfolderSpec = 13;
48+
files = (
49+
54398AC52F492D1D009D6B51 /* RunAnywhereKeyboard.appex in Embed Foundation Extensions */,
50+
);
51+
name = "Embed Foundation Extensions";
52+
runOnlyForDeploymentPostprocessing = 0;
53+
};
54+
/* End PBXCopyFilesBuildPhase section */
55+
3256
/* Begin PBXFileReference section */
3357
0C5E8414EC72B380DADD6717 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
3458
0D23254BCD6273187BD2441C /* libbz2.tbd */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
3559
502F1BAB2C2556A11E24EA6F /* libc++.tbd */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
60+
54398ABE2F492D1D009D6B51 /* RunAnywhereKeyboard.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RunAnywhereKeyboard.appex; sourceTree = BUILT_PRODUCTS_DIR; };
3661
5480A1F02E2F250200337F2F /* RunAnywhereAI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RunAnywhereAI.app; sourceTree = BUILT_PRODUCTS_DIR; };
3762
5480A1FE2E2F250400337F2F /* RunAnywhereAITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunAnywhereAITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3863
5480A2082E2F250400337F2F /* RunAnywhereAIUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunAnywhereAIUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3964
F8388285B0D64126DD4540F8 /* libarchive.tbd */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libarchive.tbd; path = usr/lib/libarchive.tbd; sourceTree = SDKROOT; };
65+
RACSHARED02RACSHARED02RACS /* SharedConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SharedConstants.swift; path = RunAnywhereAI/Shared/SharedConstants.swift; sourceTree = SOURCE_ROOT; };
66+
RACSHARED04RACSHARED04RACS /* SharedDataBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SharedDataBridge.swift; path = RunAnywhereAI/Shared/SharedDataBridge.swift; sourceTree = SOURCE_ROOT; };
4067
/* End PBXFileReference section */
4168

69+
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
70+
54398AC92F492D1D009D6B51 /* Exceptions for "RunAnywhereKeyboard" folder in "RunAnywhereKeyboard" target */ = {
71+
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
72+
membershipExceptions = (
73+
Info.plist,
74+
);
75+
target = 54398ABD2F492D1D009D6B51 /* RunAnywhereKeyboard */;
76+
};
77+
54398ACD2F492DE7009D6B51 /* Exceptions for "RunAnywhereAI" folder in "RunAnywhereAI" target */ = {
78+
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
79+
membershipExceptions = (
80+
Info.plist,
81+
);
82+
target = 5480A1EF2E2F250200337F2F /* RunAnywhereAI */;
83+
};
84+
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
85+
4286
/* Begin PBXFileSystemSynchronizedRootGroup section */
87+
54398ABF2F492D1D009D6B51 /* RunAnywhereKeyboard */ = {
88+
isa = PBXFileSystemSynchronizedRootGroup;
89+
exceptions = (
90+
54398AC92F492D1D009D6B51 /* Exceptions for "RunAnywhereKeyboard" folder in "RunAnywhereKeyboard" target */,
91+
);
92+
path = RunAnywhereKeyboard;
93+
sourceTree = "<group>";
94+
};
4395
5480A1F22E2F250200337F2F /* RunAnywhereAI */ = {
4496
isa = PBXFileSystemSynchronizedRootGroup;
97+
exceptions = (
98+
54398ACD2F492DE7009D6B51 /* Exceptions for "RunAnywhereAI" folder in "RunAnywhereAI" target */,
99+
);
45100
path = RunAnywhereAI;
46101
sourceTree = "<group>";
47102
};
@@ -58,6 +113,13 @@
58113
/* End PBXFileSystemSynchronizedRootGroup section */
59114

60115
/* Begin PBXFrameworksBuildPhase section */
116+
54398ABB2F492D1D009D6B51 /* Frameworks */ = {
117+
isa = PBXFrameworksBuildPhase;
118+
buildActionMask = 2147483647;
119+
files = (
120+
);
121+
runOnlyForDeploymentPostprocessing = 0;
122+
};
61123
5480A1ED2E2F250200337F2F /* Frameworks */ = {
62124
isa = PBXFrameworksBuildPhase;
63125
buildActionMask = 2147483647;
@@ -85,6 +147,15 @@
85147
/* End PBXFrameworksBuildPhase section */
86148

87149
/* Begin PBXGroup section */
150+
54398C522F493174009D6B51 /* Recovered References */ = {
151+
isa = PBXGroup;
152+
children = (
153+
RACSHARED02RACSHARED02RACS /* SharedConstants.swift */,
154+
RACSHARED04RACSHARED04RACS /* SharedDataBridge.swift */,
155+
);
156+
name = "Recovered References";
157+
sourceTree = "<group>";
158+
};
88159
547A6C002E6374D1005EF0C7 /* Frameworks */ = {
89160
isa = PBXGroup;
90161
children = (
@@ -102,8 +173,10 @@
102173
5480A1F22E2F250200337F2F /* RunAnywhereAI */,
103174
5480A2012E2F250400337F2F /* RunAnywhereAITests */,
104175
5480A20B2E2F250400337F2F /* RunAnywhereAIUITests */,
176+
54398ABF2F492D1D009D6B51 /* RunAnywhereKeyboard */,
105177
547A6C002E6374D1005EF0C7 /* Frameworks */,
106178
5480A1F12E2F250200337F2F /* Products */,
179+
54398C522F493174009D6B51 /* Recovered References */,
107180
);
108181
sourceTree = "<group>";
109182
};
@@ -113,24 +186,49 @@
113186
5480A1F02E2F250200337F2F /* RunAnywhereAI.app */,
114187
5480A1FE2E2F250400337F2F /* RunAnywhereAITests.xctest */,
115188
5480A2082E2F250400337F2F /* RunAnywhereAIUITests.xctest */,
189+
54398ABE2F492D1D009D6B51 /* RunAnywhereKeyboard.appex */,
116190
);
117191
name = Products;
118192
sourceTree = "<group>";
119193
};
120194
/* End PBXGroup section */
121195

122196
/* Begin PBXNativeTarget section */
197+
54398ABD2F492D1D009D6B51 /* RunAnywhereKeyboard */ = {
198+
isa = PBXNativeTarget;
199+
buildConfigurationList = 54398ACA2F492D1D009D6B51 /* Build configuration list for PBXNativeTarget "RunAnywhereKeyboard" */;
200+
buildPhases = (
201+
54398ABA2F492D1D009D6B51 /* Sources */,
202+
54398ABB2F492D1D009D6B51 /* Frameworks */,
203+
54398ABC2F492D1D009D6B51 /* Resources */,
204+
);
205+
buildRules = (
206+
);
207+
dependencies = (
208+
);
209+
fileSystemSynchronizedGroups = (
210+
54398ABF2F492D1D009D6B51 /* RunAnywhereKeyboard */,
211+
);
212+
name = RunAnywhereKeyboard;
213+
packageProductDependencies = (
214+
);
215+
productName = RunAnywhereKeyboard;
216+
productReference = 54398ABE2F492D1D009D6B51 /* RunAnywhereKeyboard.appex */;
217+
productType = "com.apple.product-type.app-extension";
218+
};
123219
5480A1EF2E2F250200337F2F /* RunAnywhereAI */ = {
124220
isa = PBXNativeTarget;
125221
buildConfigurationList = 5480A2122E2F250400337F2F /* Build configuration list for PBXNativeTarget "RunAnywhereAI" */;
126222
buildPhases = (
127223
5480A1EC2E2F250200337F2F /* Sources */,
128224
5480A1ED2E2F250200337F2F /* Frameworks */,
129225
5480A1EE2E2F250200337F2F /* Resources */,
226+
54398AC62F492D1D009D6B51 /* Embed Foundation Extensions */,
130227
);
131228
buildRules = (
132229
);
133230
dependencies = (
231+
54398AC42F492D1D009D6B51 /* PBXTargetDependency */,
134232
);
135233
fileSystemSynchronizedGroups = (
136234
5480A1F22E2F250200337F2F /* RunAnywhereAI */,
@@ -196,9 +294,12 @@
196294
isa = PBXProject;
197295
attributes = {
198296
BuildIndependentTargetsInParallel = 1;
199-
LastSwiftUpdateCheck = 1640;
297+
LastSwiftUpdateCheck = 2620;
200298
LastUpgradeCheck = 1640;
201299
TargetAttributes = {
300+
54398ABD2F492D1D009D6B51 = {
301+
CreatedOnToolsVersion = 26.2;
302+
};
202303
5480A1EF2E2F250200337F2F = {
203304
CreatedOnToolsVersion = 16.4;
204305
};
@@ -232,11 +333,19 @@
232333
5480A1EF2E2F250200337F2F /* RunAnywhereAI */,
233334
5480A1FD2E2F250400337F2F /* RunAnywhereAITests */,
234335
5480A2072E2F250400337F2F /* RunAnywhereAIUITests */,
336+
54398ABD2F492D1D009D6B51 /* RunAnywhereKeyboard */,
235337
);
236338
};
237339
/* End PBXProject section */
238340

239341
/* Begin PBXResourcesBuildPhase section */
342+
54398ABC2F492D1D009D6B51 /* Resources */ = {
343+
isa = PBXResourcesBuildPhase;
344+
buildActionMask = 2147483647;
345+
files = (
346+
);
347+
runOnlyForDeploymentPostprocessing = 0;
348+
};
240349
5480A1EE2E2F250200337F2F /* Resources */ = {
241350
isa = PBXResourcesBuildPhase;
242351
buildActionMask = 2147483647;
@@ -308,6 +417,15 @@
308417
/* End PBXShellScriptBuildPhase section */
309418

310419
/* Begin PBXSourcesBuildPhase section */
420+
54398ABA2F492D1D009D6B51 /* Sources */ = {
421+
isa = PBXSourcesBuildPhase;
422+
buildActionMask = 2147483647;
423+
files = (
424+
RACSHARED01RACSHARED01RACS /* SharedConstants.swift in Sources */,
425+
RACSHARED03RACSHARED03RACS /* SharedDataBridge.swift in Sources */,
426+
);
427+
runOnlyForDeploymentPostprocessing = 0;
428+
};
311429
5480A1EC2E2F250200337F2F /* Sources */ = {
312430
isa = PBXSourcesBuildPhase;
313431
buildActionMask = 2147483647;
@@ -332,6 +450,11 @@
332450
/* End PBXSourcesBuildPhase section */
333451

334452
/* Begin PBXTargetDependency section */
453+
54398AC42F492D1D009D6B51 /* PBXTargetDependency */ = {
454+
isa = PBXTargetDependency;
455+
target = 54398ABD2F492D1D009D6B51 /* RunAnywhereKeyboard */;
456+
targetProxy = 54398AC32F492D1D009D6B51 /* PBXContainerItemProxy */;
457+
};
335458
5480A2002E2F250400337F2F /* PBXTargetDependency */ = {
336459
isa = PBXTargetDependency;
337460
target = 5480A1EF2E2F250200337F2F /* RunAnywhereAI */;
@@ -345,6 +468,69 @@
345468
/* End PBXTargetDependency section */
346469

347470
/* Begin XCBuildConfiguration section */
471+
54398AC72F492D1D009D6B51 /* Debug */ = {
472+
isa = XCBuildConfiguration;
473+
buildSettings = {
474+
CODE_SIGN_ENTITLEMENTS = RunAnywhereKeyboard/RunAnywhereKeyboard.entitlements;
475+
CODE_SIGN_STYLE = Automatic;
476+
CURRENT_PROJECT_VERSION = 1;
477+
DEVELOPMENT_TEAM = L86FH3K93L;
478+
GENERATE_INFOPLIST_FILE = YES;
479+
INFOPLIST_FILE = RunAnywhereKeyboard/Info.plist;
480+
INFOPLIST_KEY_CFBundleDisplayName = RunAnywhereKeyboard;
481+
INFOPLIST_KEY_NSHumanReadableCopyright = "";
482+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
483+
LD_RUNPATH_SEARCH_PATHS = (
484+
"$(inherited)",
485+
"@executable_path/Frameworks",
486+
"@executable_path/../../Frameworks",
487+
);
488+
MARKETING_VERSION = 1.0;
489+
PRODUCT_BUNDLE_IDENTIFIER = com.runanywhere.RunAnywhere.RunAnywhereKeyboard;
490+
PRODUCT_NAME = "$(TARGET_NAME)";
491+
SDKROOT = iphoneos;
492+
SKIP_INSTALL = YES;
493+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
494+
SWIFT_APPROACHABLE_CONCURRENCY = YES;
495+
SWIFT_EMIT_LOC_STRINGS = YES;
496+
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
497+
SWIFT_VERSION = 5.0;
498+
TARGETED_DEVICE_FAMILY = "1,2";
499+
};
500+
name = Debug;
501+
};
502+
54398AC82F492D1D009D6B51 /* Release */ = {
503+
isa = XCBuildConfiguration;
504+
buildSettings = {
505+
CODE_SIGN_ENTITLEMENTS = RunAnywhereKeyboard/RunAnywhereKeyboard.entitlements;
506+
CODE_SIGN_STYLE = Automatic;
507+
CURRENT_PROJECT_VERSION = 1;
508+
DEVELOPMENT_TEAM = L86FH3K93L;
509+
GENERATE_INFOPLIST_FILE = YES;
510+
INFOPLIST_FILE = RunAnywhereKeyboard/Info.plist;
511+
INFOPLIST_KEY_CFBundleDisplayName = RunAnywhereKeyboard;
512+
INFOPLIST_KEY_NSHumanReadableCopyright = "";
513+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
514+
LD_RUNPATH_SEARCH_PATHS = (
515+
"$(inherited)",
516+
"@executable_path/Frameworks",
517+
"@executable_path/../../Frameworks",
518+
);
519+
MARKETING_VERSION = 1.0;
520+
PRODUCT_BUNDLE_IDENTIFIER = com.runanywhere.RunAnywhere.RunAnywhereKeyboard;
521+
PRODUCT_NAME = "$(TARGET_NAME)";
522+
SDKROOT = iphoneos;
523+
SKIP_INSTALL = YES;
524+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
525+
SWIFT_APPROACHABLE_CONCURRENCY = YES;
526+
SWIFT_EMIT_LOC_STRINGS = YES;
527+
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
528+
SWIFT_VERSION = 5.0;
529+
TARGETED_DEVICE_FAMILY = "1,2";
530+
VALIDATE_PRODUCT = YES;
531+
};
532+
name = Release;
533+
};
348534
5480A2102E2F250400337F2F /* Debug */ = {
349535
isa = XCBuildConfiguration;
350536
buildSettings = {
@@ -474,6 +660,7 @@
474660
DEVELOPMENT_TEAM = L86FH3K93L;
475661
ENABLE_PREVIEWS = YES;
476662
GENERATE_INFOPLIST_FILE = YES;
663+
INFOPLIST_FILE = RunAnywhereAI/Info.plist;
477664
INFOPLIST_KEY_CFBundleDisplayName = RunAnywhere;
478665
INFOPLIST_KEY_NSCameraUsageDescription = "RunAnywhere AI needs access to your camera for vision language model features to analyze images.";
479666
INFOPLIST_KEY_NSMicrophoneUsageDescription = "RunAnywhere AI needs access to your microphone to transcribe your voice input and provide voice-based interactions.";
@@ -517,6 +704,7 @@
517704
DEVELOPMENT_TEAM = L86FH3K93L;
518705
ENABLE_PREVIEWS = YES;
519706
GENERATE_INFOPLIST_FILE = YES;
707+
INFOPLIST_FILE = RunAnywhereAI/Info.plist;
520708
INFOPLIST_KEY_CFBundleDisplayName = RunAnywhere;
521709
INFOPLIST_KEY_NSCameraUsageDescription = "RunAnywhere AI needs access to your camera for vision language model features to analyze images.";
522710
INFOPLIST_KEY_NSMicrophoneUsageDescription = "RunAnywhere AI needs access to your microphone to transcribe your voice input and provide voice-based interactions.";
@@ -639,6 +827,15 @@
639827
/* End XCBuildConfiguration section */
640828

641829
/* Begin XCConfigurationList section */
830+
54398ACA2F492D1D009D6B51 /* Build configuration list for PBXNativeTarget "RunAnywhereKeyboard" */ = {
831+
isa = XCConfigurationList;
832+
buildConfigurations = (
833+
54398AC72F492D1D009D6B51 /* Debug */,
834+
54398AC82F492D1D009D6B51 /* Release */,
835+
);
836+
defaultConfigurationIsVisible = 0;
837+
defaultConfigurationName = Release;
838+
};
642839
5480A1EB2E2F250200337F2F /* Build configuration list for PBXProject "RunAnywhereAI" */ = {
643840
isa = XCConfigurationList;
644841
buildConfigurations = (

examples/ios/RunAnywhereAI/RunAnywhereAI/App/ContentView.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ struct MoreHubView: View {
151151
subtitle: "Manage models and files"
152152
)
153153
}
154+
155+
#if os(iOS)
156+
NavigationLink {
157+
VoiceDictationManagementView()
158+
} label: {
159+
FeatureRow(
160+
icon: "keyboard",
161+
iconColor: .indigo,
162+
title: "Voice Keyboard",
163+
subtitle: "Dictate text in any app on-device"
164+
)
165+
}
166+
#endif
154167
} header: {
155168
Text("Utilities")
156169
} footer: {

examples/ios/RunAnywhereAI/RunAnywhereAI/App/RunAnywhereAIApp.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import AppKit
2121
struct RunAnywhereAIApp: App {
2222
private let logger = Logger(subsystem: "com.runanywhere.RunAnywhereAI", category: "RunAnywhereAIApp")
2323
@StateObject private var modelManager = ModelManager.shared
24+
#if os(iOS)
25+
@StateObject private var flowSession = FlowSessionManager.shared
26+
#endif
2427
@State private var isSDKInitialized = false
2528
@State private var initializationError: Error?
2629

@@ -30,6 +33,15 @@ struct RunAnywhereAIApp: App {
3033
if isSDKInitialized {
3134
ContentView()
3235
.environmentObject(modelManager)
36+
#if os(iOS)
37+
.environmentObject(flowSession)
38+
.onOpenURL { url in
39+
guard url.scheme == SharedConstants.urlScheme,
40+
url.host == "startFlow" else { return }
41+
logger.info("📲 Received startFlow deep link")
42+
flowSession.handleStartFlow()
43+
}
44+
#endif
3345
.onAppear {
3446
logger.info("🎉 App is ready to use!")
3547
}

0 commit comments

Comments
 (0)