Skip to content

Commit c185828

Browse files
committed
embed metadata bundle into app and get path to it
1 parent 2ec60b8 commit c185828

File tree

10 files changed

+172
-5
lines changed

10 files changed

+172
-5
lines changed

packages/jsi/android/src/main/java/com/nativescriptjsi/NativescriptJsiModule.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ class NativescriptJsiModule(reactContext: ReactApplicationContext) :
99
return a * b
1010
}
1111

12+
override fun getArch() {
13+
// iOS-specific API. Let's just stub it on Android.
14+
return "unknown";
15+
}
16+
17+
override fun getMainBundleResourcePath() {
18+
// iOS-specific API. Let's just stub it on Android.
19+
return "";
20+
}
21+
1222
override fun nativescript_init(metadata_path: String?) {
1323
// NativeScript JSI is not currently supported on Android. For now, we just
1424
// no-op.

packages/jsi/apple/NativescriptJsi.mm

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,21 @@ - (NSNumber *)multiply:(double)a b:(double)b {
77
return result;
88
}
99

10+
- (NSString *)getMainBundleResourcePath {
11+
return [[NSBundle mainBundle] resourcePath];
12+
}
13+
14+
- (NSString *)getArch {
15+
#if defined(__arm64__)
16+
return @"arm64";
17+
#elif defined(__x86_64__)
18+
return @"x86_64";
19+
#endif
20+
return @"unknown";
21+
}
22+
1023
- (void)nativescript_init:(NSString *)metadata_path {
11-
// TODO
24+
NSLog(metadata_path);
1225
}
1326

1427
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:

packages/jsi/example/app.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424
"edgeToEdgeEnabled": true,
2525
"package": "org.nativescript.jsi.example"
2626
},
27+
"plugins": [
28+
[
29+
"@bacons/link-assets",
30+
[
31+
"../../../metadata-generator/metadata/metadata.ios-sim.arm64.h",
32+
"../../../metadata-generator/metadata/metadata.ios-sim.arm64.nsmd",
33+
"../../../metadata-generator/metadata/metadata.ios-sim.x86_64.h",
34+
"../../../metadata-generator/metadata/metadata.ios-sim.x86_64.nsmd",
35+
"../../../metadata-generator/metadata/metadata.ios.arm64.h",
36+
"../../../metadata-generator/metadata/metadata.ios.arm64.nsmd"
37+
]
38+
]
39+
],
2740
"web": {
2841
"favicon": "./assets/favicon.png"
2942
}

packages/jsi/example/macos/NativescriptJsi.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
514201552437B4B40078DB4F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 514201532437B4B40078DB4F /* Main.storyboard */; };
1515
514201582437B4B40078DB4F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 514201572437B4B40078DB4F /* main.m */; };
1616
7B824CDAE58CB024149952F9 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EFC31A54416DA5A3BCE77EAF /* PrivacyInfo.xcprivacy */; };
17+
7D910A3E2F49565700407C28 /* metadata.macos.arm64.h in Resources */ = {isa = PBXBuildFile; fileRef = 7D910A3A2F49565700407C28 /* metadata.macos.arm64.h */; };
18+
7D910A3F2F49565700407C28 /* metadata.macos.x86_64.h in Resources */ = {isa = PBXBuildFile; fileRef = 7D910A3B2F49565700407C28 /* metadata.macos.x86_64.h */; };
19+
7D910A402F49565700407C28 /* metadata.macos.x86_64.nsmd in Resources */ = {isa = PBXBuildFile; fileRef = 7D910A3C2F49565700407C28 /* metadata.macos.x86_64.nsmd */; };
20+
7D910A412F49565700407C28 /* metadata.macos.arm64.nsmd in Resources */ = {isa = PBXBuildFile; fileRef = 7D910A3D2F49565700407C28 /* metadata.macos.arm64.nsmd */; };
1721
EF62F1C38E47F6BB34DD982C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EFC31A54416DA5A3BCE77EAF /* PrivacyInfo.xcprivacy */; };
1822
/* End PBXBuildFile section */
1923

@@ -30,6 +34,10 @@
3034
514201592437B4B40078DB4F /* NativescriptJsi.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NativescriptJsi.entitlements; sourceTree = "<group>"; };
3135
56ACB951E4DBD7FF2C4E44BD /* libPods-NativescriptJsi-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NativescriptJsi-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3236
73F6ED21BE44D52AFD144A8A /* Pods-NativescriptJsi-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NativescriptJsi-macOS.debug.xcconfig"; path = "Target Support Files/Pods-NativescriptJsi-macOS/Pods-NativescriptJsi-macOS.debug.xcconfig"; sourceTree = "<group>"; };
37+
7D910A3A2F49565700407C28 /* metadata.macos.arm64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = metadata.macos.arm64.h; path = "../../../../metadata-generator/metadata/metadata.macos.arm64.h"; sourceTree = "<group>"; };
38+
7D910A3B2F49565700407C28 /* metadata.macos.x86_64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = metadata.macos.x86_64.h; path = "../../../../metadata-generator/metadata/metadata.macos.x86_64.h"; sourceTree = "<group>"; };
39+
7D910A3C2F49565700407C28 /* metadata.macos.x86_64.nsmd */ = {isa = PBXFileReference; lastKnownFileType = file; name = metadata.macos.x86_64.nsmd; path = "../../../../metadata-generator/metadata/metadata.macos.x86_64.nsmd"; sourceTree = "<group>"; };
40+
7D910A3D2F49565700407C28 /* metadata.macos.arm64.nsmd */ = {isa = PBXFileReference; lastKnownFileType = file; name = metadata.macos.arm64.nsmd; path = "../../../../metadata-generator/metadata/metadata.macos.arm64.nsmd"; sourceTree = "<group>"; };
3341
C5F477BB472D20434A8B470D /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-NativescriptJsi-macOS/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
3442
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
3543
EFC31A54416DA5A3BCE77EAF /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
@@ -104,6 +112,10 @@
104112
83CBB9F61A601CBA00E9B192 = {
105113
isa = PBXGroup;
106114
children = (
115+
7D910A3A2F49565700407C28 /* metadata.macos.arm64.h */,
116+
7D910A3D2F49565700407C28 /* metadata.macos.arm64.nsmd */,
117+
7D910A3B2F49565700407C28 /* metadata.macos.x86_64.h */,
118+
7D910A3C2F49565700407C28 /* metadata.macos.x86_64.nsmd */,
107119
5142014A2437B4B30078DB4F /* NativescriptJsi-macOS */,
108120
832341AE1AAA6A7D00B99B32 /* Libraries */,
109121
83CBBA001A601CBA00E9B192 /* Products */,
@@ -226,6 +238,10 @@
226238
isa = PBXResourcesBuildPhase;
227239
buildActionMask = 2147483647;
228240
files = (
241+
7D910A3E2F49565700407C28 /* metadata.macos.arm64.h in Resources */,
242+
7D910A3F2F49565700407C28 /* metadata.macos.x86_64.h in Resources */,
243+
7D910A402F49565700407C28 /* metadata.macos.x86_64.nsmd in Resources */,
244+
7D910A412F49565700407C28 /* metadata.macos.arm64.nsmd in Resources */,
229245
514201522437B4B40078DB4F /* Assets.xcassets in Resources */,
230246
514201552437B4B40078DB4F /* Main.storyboard in Resources */,
231247
EF62F1C38E47F6BB34DD982C /* PrivacyInfo.xcprivacy in Resources */,

packages/jsi/example/macos/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,6 @@ SPEC CHECKSUMS:
26972697
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
26982698
Yoga: 927965149d92a77941dba4f446f50786a95f8ecc
26992699

2700-
PODFILE CHECKSUM: d0f6855baa2675db5351c183e82a4d2c16c2342a
2700+
PODFILE CHECKSUM: af4c3bdedf4df2375937d89b0393bbe11ed04e95
27012701

27022702
COCOAPODS: 1.16.2

packages/jsi/example/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
"macos": "react-native run-macos"
1010
},
1111
"dependencies": {
12+
"@bacons/link-assets": "1.1.0",
1213
"expo": "~54.0.33",
14+
"expo-device": "~8.0.10",
1315
"expo-status-bar": "~3.0.9",
1416
"react": "19.1.4",
1517
"react-native": "0.81.6",

packages/jsi/example/src/App.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import { Text, View, StyleSheet, Button } from 'react-native';
2-
import { multiply, nativescript_init } from 'nativescript-jsi';
1+
import { Text, View, StyleSheet, Button, Platform } from 'react-native';
2+
import {
3+
getArch,
4+
getMainBundleResourcePath,
5+
multiply,
6+
nativescript_init,
7+
} from 'nativescript-jsi';
38

49
const result = multiply(3, 7);
510

@@ -11,7 +16,10 @@ export default function App() {
1116
title="Init NativeScript"
1217
onPress={() => {
1318
try {
14-
nativescript_init('abc');
19+
console.log('metadataFileName', getMetadataFileName());
20+
nativescript_init(
21+
`${getMainBundleResourcePath()}/${getMetadataFileName()}`
22+
);
1523
} catch (error) {
1624
console.log('Error initialising NativeScript:', error);
1725
}
@@ -21,6 +29,23 @@ export default function App() {
2129
);
2230
}
2331

32+
function getMetadataFileName() {
33+
if (Platform.OS === 'ios') {
34+
const { isDevice, supportedCpuArchitectures } = require('expo-device');
35+
36+
const arch = supportedCpuArchitectures.some((arch: string) =>
37+
arch.toLowerCase().includes('arm64') ? 'arm64' : 'x84_64'
38+
);
39+
return `metadata.ios${isDevice ? '' : '-sim'}.${arch}.nsmd`;
40+
}
41+
42+
if (Platform.OS === 'macos') {
43+
return `metadata.macos.${getArch()}.nsmd`;
44+
}
45+
46+
throw new Error('This example only supports iOS and macOS.');
47+
}
48+
2449
const styles = StyleSheet.create({
2550
container: {
2651
flex: 1,

packages/jsi/src/NativeNativescriptJsi.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { TurboModuleRegistry, type TurboModule } from 'react-native';
22

33
export interface Spec extends TurboModule {
44
multiply(a: number, b: number): number;
5+
getArch(): string;
6+
getMainBundleResourcePath(): string;
57
nativescript_init(metadata_path: string | null): void;
68
}
79

packages/jsi/src/index.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@ export function multiply(a: number, b: number): number {
44
return NativescriptJsi.multiply(a, b);
55
}
66

7+
/**
8+
* @deprecated This is a convenience API for use by this library's example app
9+
* to help get the path to the bundled metadata. Normally this API would be
10+
* provided via expo-device or something.
11+
*
12+
* @platform iOS and macOS. Returns "unknown" on Android.
13+
*/
14+
export function getArch(): string {
15+
return NativescriptJsi.getArch();
16+
}
17+
18+
/**
19+
* @deprecated This is a convenience API for use by this library's example app
20+
* to help get the path to the bundled metadata. Normally this API would be
21+
* provided via expo-file-system or something.
22+
*
23+
* @platform iOS and macOS. Returns empty string on Android.
24+
*/
25+
export function getMainBundleResourcePath(): string {
26+
return NativescriptJsi.getMainBundleResourcePath();
27+
}
28+
729
/**
830
* Initialise NativeScript JSI. This installs its bindings to the Objective-C
931
* runtime. It will bind to whatever APIs are referenced in in the metadata
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
diff --git a/node_modules/@bacons/link-assets/build/groupFiles.js b/node_modules/@bacons/link-assets/build/groupFiles.js
2+
index 91c7f85..c2470ae 100644
3+
--- a/node_modules/@bacons/link-assets/build/groupFiles.js
4+
+++ b/node_modules/@bacons/link-assets/build/groupFiles.js
5+
@@ -5,6 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6+
Object.defineProperty(exports, "__esModule", { value: true });
7+
exports.groupFilesByType = void 0;
8+
const mime_1 = __importDefault(require("mime"));
9+
+function getCustomType(type){
10+
+ if(type.endsWith(".h")){
11+
+ return "text/x-chdr";
12+
+ }
13+
+ if(type.endsWith(".nsmd")){
14+
+ return "application/x-nsmd";
15+
+ }
16+
+
17+
+ return '';
18+
+}
19+
/**
20+
* Given an array of files, it groups it by it's type.
21+
* Type of the file is inferred from it's mimetype based on the extension
22+
@@ -17,7 +27,7 @@ const mime_1 = __importDefault(require("mime"));
23+
* the returned object will be: {font: ['fonts/a.ttf'], image: ['images/b.jpg']}
24+
*/
25+
function groupFilesByType(assets) {
26+
- return groupBy(assets, (type) => (mime_1.default.getType(type) || "").split("/")[0]);
27+
+ return groupBy(assets, (type) => (mime_1.default.getType(type) || getCustomType(type) || "").split("/")[0]);
28+
}
29+
exports.groupFilesByType = groupFilesByType;
30+
function groupBy(arr, block) {
31+
diff --git a/node_modules/@bacons/link-assets/build/index.js b/node_modules/@bacons/link-assets/build/index.js
32+
index d65e664..b9121c0 100644
33+
--- a/node_modules/@bacons/link-assets/build/index.js
34+
+++ b/node_modules/@bacons/link-assets/build/index.js
35+
@@ -62,6 +62,7 @@ const withIosLinkedAsset = (config, { font, image }) => {
36+
}
37+
addResourceFile(font);
38+
addResourceFile(image);
39+
+ addResourceFile(application);
40+
return config;
41+
});
42+
config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
43+
@@ -71,13 +72,17 @@ const withIosLinkedAsset = (config, { font, image }) => {
44+
const existingFonts = config.modResults.UIAppFonts || [];
45+
const fontList = (_a = font === null || font === void 0 ? void 0 : font.map((font) => path_1.default.basename(font))) !== null && _a !== void 0 ? _a : [];
46+
debug("Native iOS Fonts:", fontList);
47+
- const allFonts = [
48+
+ const allFonts = Array.from(new Set([
49+
// @ts-expect-error
50+
...existingFonts,
51+
...fontList,
52+
- ];
53+
- // @ts-ignore Type mismatch with the lib
54+
- config.modResults.UIAppFonts = Array.from(new Set(allFonts));
55+
+ ]));
56+
+ // FIXME: if allFonts was previously populated, but is now empty, remove
57+
+ // the key somehow.
58+
+ if(allFonts.length){
59+
+ // @ts-ignore Type mismatch with the lib
60+
+ config.modResults.UIAppFonts = allFonts;
61+
+ }
62+
return config;
63+
});
64+
return config;

0 commit comments

Comments
 (0)