Skip to content

Commit 5ea8293

Browse files
fixing rn for rag +some permissions for vlm + npm dependencies + archive logic improved
1 parent 3ac04c8 commit 5ea8293

21 files changed

Lines changed: 1747 additions & 4141 deletions

File tree

examples/react-native/RunAnywhereAI/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ const App: React.FC = () => {
206206
// ONNX module with STT and TTS models
207207
// Using tar.gz format hosted on RunanywhereAI/sherpa-onnx for fast native extraction
208208
// Using explicit IDs ensures models are recognized after download across app restarts
209-
ONNX.register();
209+
await ONNX.register();
210210
// Register ONNX models in parallel
211211
const onnxPromises = [
212212
ONNX.addModel({

examples/react-native/RunAnywhereAI/ios/RunAnywhereAI.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
1717
AABB001122334455 /* NativeAudioModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABB001122334456 /* NativeAudioModule.swift */; };
1818
AABB001122334457 /* NativeAudioModule.m in Sources */ = {isa = PBXBuildFile; fileRef = AABB001122334458 /* NativeAudioModule.m */; };
19+
CCDD001122334455 /* DocumentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCDD001122334456 /* DocumentService.swift */; };
20+
CCDD001122334457 /* DocumentService.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDD001122334458 /* DocumentService.m */; };
1921
/* End PBXBuildFile section */
2022

2123
/* Begin PBXContainerItemProxy section */
@@ -46,6 +48,8 @@
4648
9E75FBBD9CE4CFEFC37E3C16 /* libPods-RunAnywhereAI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunAnywhereAI.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4749
AABB001122334456 /* NativeAudioModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NativeAudioModule.swift; path = RunAnywhereAI/NativeAudioModule.swift; sourceTree = "<group>"; };
4850
AABB001122334458 /* NativeAudioModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NativeAudioModule.m; path = RunAnywhereAI/NativeAudioModule.m; sourceTree = "<group>"; };
51+
CCDD001122334456 /* DocumentService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DocumentService.swift; path = RunAnywhereAI/DocumentService.swift; sourceTree = "<group>"; };
52+
CCDD001122334458 /* DocumentService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DocumentService.m; path = RunAnywhereAI/DocumentService.m; sourceTree = "<group>"; };
4953
AABB001122334459 /* RunAnywhereAI-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RunAnywhereAI-Bridging-Header.h"; path = "RunAnywhereAI/RunAnywhereAI-Bridging-Header.h"; sourceTree = "<group>"; };
5054
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
5155
FF375136ECCEFB06442E8E31 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = RunAnywhereAI/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
@@ -94,6 +98,8 @@
9498
13B07FB01A68108700A75B9A /* AppDelegate.swift */,
9599
AABB001122334456 /* NativeAudioModule.swift */,
96100
AABB001122334458 /* NativeAudioModule.m */,
101+
CCDD001122334456 /* DocumentService.swift */,
102+
CCDD001122334458 /* DocumentService.m */,
97103
AABB001122334459 /* RunAnywhereAI-Bridging-Header.h */,
98104
13B07FB51A68108700A75B9A /* Images.xcassets */,
99105
13B07FB61A68108700A75B9A /* Info.plist */,
@@ -404,6 +410,8 @@
404410
13B07FBC1A68108700A75B9A /* AppDelegate.swift in Sources */,
405411
AABB001122334455 /* NativeAudioModule.swift in Sources */,
406412
AABB001122334457 /* NativeAudioModule.m in Sources */,
413+
CCDD001122334455 /* DocumentService.swift in Sources */,
414+
CCDD001122334457 /* DocumentService.m in Sources */,
407415
);
408416
runOnlyForDeploymentPostprocessing = 0;
409417
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#import <React/RCTBridgeModule.h>
2+
3+
@interface RCT_EXTERN_MODULE(DocumentService, NSObject)
4+
5+
RCT_EXTERN_METHOD(extractText:(NSString *)filePath
6+
withResolver:(RCTPromiseResolveBlock)resolve
7+
withRejecter:(RCTPromiseRejectBlock)reject)
8+
9+
@end
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import Foundation
2+
import PDFKit
3+
import React
4+
5+
/// Native document text extraction using PDFKit.
6+
/// Mirrors the iOS example app's DocumentService.swift for RAG document ingestion.
7+
@objc(DocumentService)
8+
class DocumentService: NSObject {
9+
10+
@objc static func requiresMainQueueSetup() -> Bool {
11+
return false
12+
}
13+
14+
/// Extract plain text from a file at the given path.
15+
/// Supports PDF (via PDFKit) and JSON / plain text (via String).
16+
@objc func extractText(
17+
_ filePath: String,
18+
withResolver resolve: @escaping RCTPromiseResolveBlock,
19+
withRejecter reject: @escaping RCTPromiseRejectBlock
20+
) {
21+
DispatchQueue.global(qos: .userInitiated).async {
22+
do {
23+
// Document picker may return a file:// URI or a bare path
24+
let url: URL
25+
if filePath.hasPrefix("file://") {
26+
url = URL(string: filePath) ?? URL(fileURLWithPath: filePath)
27+
} else {
28+
url = URL(fileURLWithPath: filePath)
29+
}
30+
let hasAccess = url.startAccessingSecurityScopedResource()
31+
defer {
32+
if hasAccess { url.stopAccessingSecurityScopedResource() }
33+
}
34+
35+
let ext = url.pathExtension.lowercased()
36+
let text: String
37+
38+
switch ext {
39+
case "pdf":
40+
text = try Self.extractPDFText(from: url)
41+
case "json":
42+
text = try Self.extractJSONText(from: url)
43+
default:
44+
text = try String(contentsOf: url, encoding: .utf8)
45+
}
46+
47+
resolve(text)
48+
} catch {
49+
reject("EXTRACT_ERROR", error.localizedDescription, error)
50+
}
51+
}
52+
}
53+
54+
// MARK: - PDF extraction (PDFKit)
55+
56+
private static func extractPDFText(from url: URL) throws -> String {
57+
guard let document = PDFDocument(url: url) else {
58+
throw NSError(domain: "DocumentService", code: 1,
59+
userInfo: [NSLocalizedDescriptionKey: "Failed to open PDF. File may be corrupted or image-only."])
60+
}
61+
guard document.pageCount > 0 else {
62+
throw NSError(domain: "DocumentService", code: 2,
63+
userInfo: [NSLocalizedDescriptionKey: "PDF has no pages."])
64+
}
65+
66+
var pages: [String] = []
67+
for i in 0..<document.pageCount {
68+
if let page = document.page(at: i), let text = page.string, !text.isEmpty {
69+
pages.append(text)
70+
}
71+
}
72+
73+
let result = pages.joined(separator: "\n")
74+
guard !result.isEmpty else {
75+
throw NSError(domain: "DocumentService", code: 3,
76+
userInfo: [NSLocalizedDescriptionKey: "PDF contains no extractable text (may be image-only)."])
77+
}
78+
return result
79+
}
80+
81+
// MARK: - JSON extraction (recursive string values)
82+
83+
private static func extractJSONText(from url: URL) throws -> String {
84+
let data = try Data(contentsOf: url)
85+
let parsed = try JSONSerialization.jsonObject(with: data)
86+
var strings: [String] = []
87+
extractStrings(from: parsed, into: &strings)
88+
return strings.joined(separator: "\n")
89+
}
90+
91+
private static func extractStrings(from value: Any, into result: inout [String]) {
92+
if let string = value as? String {
93+
result.append(string)
94+
} else if let dict = value as? [String: Any] {
95+
for (_, v) in dict {
96+
extractStrings(from: v, into: &result)
97+
}
98+
} else if let array = value as? [Any] {
99+
for element in array {
100+
extractStrings(from: element, into: &result)
101+
}
102+
}
103+
}
104+
}

examples/react-native/RunAnywhereAI/ios/RunAnywhereAI/PrivacyInfo.xcprivacy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<key>NSPrivacyAccessedAPITypeReasons</key>
1111
<array>
1212
<string>C617.1</string>
13+
<string>3B52.1</string>
1314
</array>
1415
</dict>
1516
<dict>

examples/react-native/RunAnywhereAI/package-lock.json

Lines changed: 85 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/react-native/RunAnywhereAI/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,25 @@
1919
},
2020
"dependencies": {
2121
"@react-native-async-storage/async-storage": "^2.2.0",
22+
"@react-native-clipboard/clipboard": "^1.16.3",
2223
"@react-navigation/bottom-tabs": "^7.12.0",
2324
"@react-navigation/native": "^7.1.28",
2425
"@react-navigation/native-stack": "^7.12.0",
2526
"@runanywhere/core": "file:../../../sdk/runanywhere-react-native/packages/core",
2627
"@runanywhere/llamacpp": "file:../../../sdk/runanywhere-react-native/packages/llamacpp",
2728
"@runanywhere/onnx": "file:../../../sdk/runanywhere-react-native/packages/onnx",
28-
"@runanywhere/rag": "file:../../../sdk/runanywhere-react-native/packages/rag",
2929
"react": "19.2.0",
3030
"react-native": "0.83.1",
31+
"react-native-document-picker": "^9.3.1",
3132
"react-native-fs": "^2.20.0",
33+
"react-native-image-picker": "^8.2.1",
3234
"react-native-live-audio-stream": "^1.1.1",
3335
"react-native-nitro-modules": "^0.33.7",
3436
"react-native-permissions": "^5.4.4",
3537
"react-native-safe-area-context": "^5.6.2",
3638
"react-native-screens": "^4.23.0",
3739
"react-native-vector-icons": "^10.3.0",
40+
"react-native-vision-camera": "^4.7.3",
3841
"rn-fetch-blob": "^0.12.0",
3942
"zustand": "^5.0.0"
4043
},

0 commit comments

Comments
 (0)