expo-modules-jsi 58.0.7 → 58.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/apple/Benchmarks/RuntimeCacheBenchmarks.swift +71 -0
- package/apple/Benchmarks/UnownedDecodeBenchmarks.swift +121 -0
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptCodable+Containers.swift +52 -10
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptCodable+Data.swift +5 -0
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptCodable+Date.swift +27 -5
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptCodable+Primitives.swift +75 -0
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptDecodable.swift +34 -5
- package/apple/Sources/ExpoModulesJSI/Coding/JavaScriptValueKinds.swift +73 -0
- package/apple/Sources/ExpoModulesJSI/Protocols/JSIRepresentable.swift +4 -2
- package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift +18 -13
- package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntimeCache.swift +74 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptArray.swift +26 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptObject.swift +22 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptPromise.swift +14 -14
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptUnownedValue.swift +17 -0
- package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptValue.swift +54 -1
- package/apple/Sources/ExpoModulesJSI/Utilities/String+JSI.swift +4 -3
- package/apple/Sources/ExpoModulesJSI-Cxx/include/JSIUtils.h +27 -0
- package/apple/Tests/JavaScriptDecodableKindsTests.swift +132 -0
- package/apple/Tests/JavaScriptRuntimeCacheTests.swift +117 -0
- package/apple/Tests/JavaScriptRuntimeTests.swift +59 -0
- package/apple/Tests/JavaScriptUnownedDecodeTests.swift +99 -0
- package/apple/Tests/JavaScriptUnownedElementsTests.swift +76 -0
- package/apple/scripts/build-xcframework.sh +15 -0
- package/package.json +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import ExpoModulesJSI
|
|
2
|
+
import Testing
|
|
3
|
+
|
|
4
|
+
private final class CachedBox {
|
|
5
|
+
let value: Int
|
|
6
|
+
|
|
7
|
+
init(_ value: Int) {
|
|
8
|
+
self.value = value
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@Suite
|
|
13
|
+
@JavaScriptActor
|
|
14
|
+
struct JavaScriptRuntimeCacheTests {
|
|
15
|
+
let runtime = JavaScriptRuntime()
|
|
16
|
+
|
|
17
|
+
@Test
|
|
18
|
+
func `creates the value on first use and reuses it afterwards`() {
|
|
19
|
+
let key = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
20
|
+
var makeCount = 0
|
|
21
|
+
|
|
22
|
+
let first = runtime.cached(key) {
|
|
23
|
+
makeCount += 1
|
|
24
|
+
return CachedBox(1)
|
|
25
|
+
}
|
|
26
|
+
let second = runtime.cached(key) {
|
|
27
|
+
makeCount += 1
|
|
28
|
+
return CachedBox(2)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#expect(makeCount == 1)
|
|
32
|
+
#expect(first === second)
|
|
33
|
+
#expect(second.value == 1)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Test
|
|
37
|
+
func `keys are independent`() {
|
|
38
|
+
let firstKey = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
39
|
+
let secondKey = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
40
|
+
|
|
41
|
+
#expect(runtime.cached(firstKey) { CachedBox(1) }.value == 1)
|
|
42
|
+
#expect(runtime.cached(secondKey) { CachedBox(2) }.value == 2)
|
|
43
|
+
#expect(runtime.cached(firstKey) { CachedBox(3) }.value == 1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Test
|
|
47
|
+
func `keys can be used in any order`() {
|
|
48
|
+
let keys = (0..<16).map { _ in JavaScriptRuntime.Cache.Key<CachedBox>() }
|
|
49
|
+
|
|
50
|
+
// Using the last key first grows the storage past all the others, which must then stay empty.
|
|
51
|
+
#expect(runtime.cached(keys[15]) { CachedBox(15) }.value == 15)
|
|
52
|
+
#expect(runtime.cached(keys[3]) { CachedBox(3) }.value == 3)
|
|
53
|
+
#expect(runtime.cached(keys[15]) { CachedBox(-1) }.value == 15)
|
|
54
|
+
#expect(runtime.cached(keys[0]) { CachedBox(0) }.value == 0)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
func `each runtime has its own entries`() {
|
|
59
|
+
let key = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
60
|
+
let otherRuntime = JavaScriptRuntime()
|
|
61
|
+
|
|
62
|
+
#expect(runtime.cached(key) { CachedBox(1) }.value == 1)
|
|
63
|
+
#expect(otherRuntime.cached(key) { CachedBox(2) }.value == 2)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Test
|
|
67
|
+
func `a value can be created from other cached values`() {
|
|
68
|
+
let baseKey = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
69
|
+
let derivedKey = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
70
|
+
|
|
71
|
+
// The nested lookup runs while the outer one is still creating its value.
|
|
72
|
+
let derived = runtime.cached(derivedKey) {
|
|
73
|
+
let base = runtime.cached(baseKey) { CachedBox(20) }
|
|
74
|
+
return CachedBox(base.value + 1)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#expect(derived.value == 21)
|
|
78
|
+
#expect(runtime.cached(baseKey) { CachedBox(0) }.value == 20)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Test
|
|
82
|
+
func `a throwing make caches nothing`() throws {
|
|
83
|
+
struct MakeError: Error {}
|
|
84
|
+
let key = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
85
|
+
|
|
86
|
+
#expect(throws: MakeError.self) {
|
|
87
|
+
try runtime.cached(key) { throw MakeError() }
|
|
88
|
+
}
|
|
89
|
+
#expect(runtime.cached(key) { CachedBox(1) }.value == 1)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Test
|
|
93
|
+
func `caches JavaScript values`() throws {
|
|
94
|
+
let key = JavaScriptRuntime.Cache.Key<JavaScriptValue>()
|
|
95
|
+
|
|
96
|
+
let first = try runtime.cached(key) { try runtime.eval("({ answer: 42 })") }
|
|
97
|
+
let second = try runtime.cached(key) { try runtime.eval("({ answer: 0 })") }
|
|
98
|
+
|
|
99
|
+
#expect(first === second)
|
|
100
|
+
#expect(second.getObject().getProperty("answer").getInt() == 42)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Test
|
|
104
|
+
func `cached values are released with the runtime`() {
|
|
105
|
+
let key = JavaScriptRuntime.Cache.Key<CachedBox>()
|
|
106
|
+
weak var cachedValue: CachedBox?
|
|
107
|
+
|
|
108
|
+
do {
|
|
109
|
+
let runtime = JavaScriptRuntime()
|
|
110
|
+
cachedValue = runtime.cached(key) { CachedBox(1) }
|
|
111
|
+
#expect(cachedValue != nil)
|
|
112
|
+
withExtendedLifetime(runtime) {}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#expect(cachedValue == nil)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -34,6 +34,40 @@ struct JavaScriptRuntimeTests {
|
|
|
34
34
|
#expect(fn.asValue().isFunction() == true)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
@Test
|
|
38
|
+
func `host function returns a fresh string`() throws {
|
|
39
|
+
let fn = runtime.createFunction("greet") { [runtime] _, _ in
|
|
40
|
+
return JavaScriptValue(runtime, "hello")
|
|
41
|
+
}
|
|
42
|
+
runtime.global().setProperty("greet", value: fn)
|
|
43
|
+
#expect(try runtime.eval("greet() + ' ' + greet()").getString() == "hello hello")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Test
|
|
47
|
+
func `host function returns a shared value repeatedly`() throws {
|
|
48
|
+
// The same instance is returned on every call, so the host call must copy the engine handle
|
|
49
|
+
// instead of moving it out: the captured value has to stay valid for the next call.
|
|
50
|
+
let shared = JavaScriptValue(runtime, "shared")
|
|
51
|
+
let fn = runtime.createFunction("shared") { _, _ in
|
|
52
|
+
return shared
|
|
53
|
+
}
|
|
54
|
+
runtime.global().setProperty("shared", value: fn)
|
|
55
|
+
#expect(try runtime.eval("shared() + ' ' + shared()").getString() == "shared shared")
|
|
56
|
+
#expect(shared.getString() == "shared")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@Test
|
|
60
|
+
func `host function returns an object it keeps`() throws {
|
|
61
|
+
let kept = runtime.createObject()
|
|
62
|
+
kept.setProperty("answer", value: 42)
|
|
63
|
+
let fn = runtime.createFunction("kept") { _, _ in
|
|
64
|
+
return kept.asValue()
|
|
65
|
+
}
|
|
66
|
+
runtime.global().setProperty("kept", value: fn)
|
|
67
|
+
#expect(try runtime.eval("kept().answer + kept().answer").getInt() == 84)
|
|
68
|
+
#expect(kept.getProperty("answer").getInt() == 42)
|
|
69
|
+
}
|
|
70
|
+
|
|
37
71
|
@Test
|
|
38
72
|
func `evaluate script`() throws {
|
|
39
73
|
#expect(try runtime.eval("'hello' + ' ' + 'world'").getString() == "hello world")
|
|
@@ -217,6 +251,31 @@ struct JavaScriptRuntimeTests {
|
|
|
217
251
|
#expect(hostObject.getProperty("unknown").isUndefined())
|
|
218
252
|
}
|
|
219
253
|
|
|
254
|
+
@Test
|
|
255
|
+
func `host object getter returns strings`() throws {
|
|
256
|
+
// `fresh` is created per access and gets moved into the result; `shared` is the same instance on
|
|
257
|
+
// every access and has to be copied so it stays valid.
|
|
258
|
+
let shared = JavaScriptValue(runtime, "shared")
|
|
259
|
+
let hostObject = runtime.createHostObject(
|
|
260
|
+
get: { [runtime] name in
|
|
261
|
+
switch name {
|
|
262
|
+
case "fresh":
|
|
263
|
+
return JavaScriptValue(runtime, "fresh")
|
|
264
|
+
case "shared":
|
|
265
|
+
return shared
|
|
266
|
+
default:
|
|
267
|
+
return .undefined
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
getPropertyNames: { ["fresh", "shared"] }
|
|
271
|
+
)
|
|
272
|
+
runtime.global().setProperty("host", value: hostObject)
|
|
273
|
+
|
|
274
|
+
#expect(try runtime.eval("host.fresh + host.fresh").getString() == "freshfresh")
|
|
275
|
+
#expect(try runtime.eval("host.shared + host.shared").getString() == "sharedshared")
|
|
276
|
+
#expect(shared.getString() == "shared")
|
|
277
|
+
}
|
|
278
|
+
|
|
220
279
|
@Test
|
|
221
280
|
func `host object set property`() {
|
|
222
281
|
var storedValue: Int?
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Copyright 2026-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesJSI
|
|
4
|
+
import Foundation
|
|
5
|
+
import Testing
|
|
6
|
+
|
|
7
|
+
/// Decodes through the `JavaScriptUnownedValue` overloads, and through `withUnownedValue(in:_:)` from an
|
|
8
|
+
/// owning value.
|
|
9
|
+
@Suite("JavaScriptDecodable unowned decode")
|
|
10
|
+
@JavaScriptActor
|
|
11
|
+
struct JavaScriptUnownedDecodeTests {
|
|
12
|
+
let runtime = JavaScriptRuntime()
|
|
13
|
+
|
|
14
|
+
private func unowned<T: JavaScriptDecodable>(_ type: T.Type, from source: String) throws -> T {
|
|
15
|
+
let value = try runtime.eval(source)
|
|
16
|
+
let buffer = JavaScriptValuesBuffer.allocate(in: runtime, with: value)
|
|
17
|
+
return try T.decode(buffer.unownedValue(at: 0), in: runtime)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// MARK: - withUnownedValue
|
|
21
|
+
|
|
22
|
+
@Test
|
|
23
|
+
func `withUnownedValue borrows the value it is called on`() throws {
|
|
24
|
+
let number = try runtime.eval("42")
|
|
25
|
+
#expect(number.withUnownedValue(in: runtime) { $0.getDouble() } == 42)
|
|
26
|
+
|
|
27
|
+
let string = try runtime.eval("'text'")
|
|
28
|
+
#expect(string.withUnownedValue(in: runtime) { $0.getString() } == "text")
|
|
29
|
+
|
|
30
|
+
let object = try runtime.eval("({ answer: 42 })")
|
|
31
|
+
let answer = try object.withUnownedValue(in: runtime) { try $0.asObject(in: runtime).getProperty("answer").asInt() }
|
|
32
|
+
#expect(answer == 42)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
func `withUnownedValue works for a value without a runtime`() {
|
|
37
|
+
let value = JavaScriptValue.number(1.5)
|
|
38
|
+
#expect(value.withUnownedValue(in: runtime) { $0.getDouble() } == 1.5)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// MARK: - Default owning decode
|
|
42
|
+
|
|
43
|
+
@Test
|
|
44
|
+
func `a type that only decodes unowned values also decodes owning ones`() throws {
|
|
45
|
+
let value = try runtime.eval("7")
|
|
46
|
+
#expect(try UnownedOnly.decode(value, in: runtime) == UnownedOnly(number: 7))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// MARK: - Containers
|
|
50
|
+
|
|
51
|
+
@Test
|
|
52
|
+
func `Array decodes an array and arrayizes a scalar`() throws {
|
|
53
|
+
#expect(try unowned([Int].self, from: "[1, 2, 3]") == [1, 2, 3])
|
|
54
|
+
#expect(try unowned([Int].self, from: "4") == [4])
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
func `Dictionary decodes an object and skips undefined properties`() throws {
|
|
59
|
+
#expect(try unowned([String: Int].self, from: "({ a: 1, b: undefined })") == ["a": 1])
|
|
60
|
+
#expect(throws: (any Error).self) {
|
|
61
|
+
_ = try unowned([String: Int].self, from: "42")
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@Test
|
|
66
|
+
func `Date decodes a number, a string and a Date`() throws {
|
|
67
|
+
#expect(try unowned(Date.self, from: "1000") == Date(timeIntervalSince1970: 1))
|
|
68
|
+
#expect(try unowned(Date.self, from: "'1970-01-01T00:00:02Z'") == Date(timeIntervalSince1970: 2))
|
|
69
|
+
#expect(try unowned(Date.self, from: "new Date(3000)") == Date(timeIntervalSince1970: 3))
|
|
70
|
+
#expect(throws: (any Error).self) {
|
|
71
|
+
_ = try unowned(Date.self, from: "true")
|
|
72
|
+
}
|
|
73
|
+
#expect(throws: (any Error).self) {
|
|
74
|
+
_ = try unowned(Date.self, from: "({ getTime() { return 0 } })")
|
|
75
|
+
}
|
|
76
|
+
#expect(throws: (any Error).self) {
|
|
77
|
+
_ = try unowned(Date.self, from: "'not a date'")
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Test
|
|
82
|
+
func `Date decodes the same from an owning value`() throws {
|
|
83
|
+
#expect(try Date.decode(runtime.eval("1000"), in: runtime) == Date(timeIntervalSince1970: 1))
|
|
84
|
+
#expect(try Date.decode(runtime.eval("'1970-01-01T00:00:02Z'"), in: runtime) == Date(timeIntervalSince1970: 2))
|
|
85
|
+
#expect(try Date.decode(runtime.eval("new Date(3000)"), in: runtime) == Date(timeIntervalSince1970: 3))
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Implements only the unowned decode, so its owning decode is the protocol default.
|
|
90
|
+
private struct UnownedOnly: JavaScriptDecodable, Equatable {
|
|
91
|
+
let number: Double
|
|
92
|
+
|
|
93
|
+
@JavaScriptActor
|
|
94
|
+
static func decode(_ value: borrowing JavaScriptUnownedValue, in runtime: borrowing JavaScriptRuntime) throws
|
|
95
|
+
-> UnownedOnly
|
|
96
|
+
{
|
|
97
|
+
return UnownedOnly(number: try value.asDouble())
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright 2026-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesJSI
|
|
4
|
+
import Testing
|
|
5
|
+
|
|
6
|
+
/// Lending array elements and object properties out as `JavaScriptUnownedValue`s.
|
|
7
|
+
@Suite("Unowned elements and properties")
|
|
8
|
+
@JavaScriptActor
|
|
9
|
+
struct JavaScriptUnownedElementsTests {
|
|
10
|
+
let runtime = JavaScriptRuntime()
|
|
11
|
+
|
|
12
|
+
@Test
|
|
13
|
+
func `mapUnowned transforms every element in order`() throws {
|
|
14
|
+
let array = try runtime.eval("[1, 'two', null, { four: 4 }]").getArray()
|
|
15
|
+
let kinds = array.mapUnowned { element -> String in
|
|
16
|
+
if element.isNumber() {
|
|
17
|
+
return "number \(element.getDouble())"
|
|
18
|
+
}
|
|
19
|
+
if element.isString() {
|
|
20
|
+
return "string \(element.getString())"
|
|
21
|
+
}
|
|
22
|
+
if element.isNull() {
|
|
23
|
+
return "null"
|
|
24
|
+
}
|
|
25
|
+
return "object"
|
|
26
|
+
}
|
|
27
|
+
#expect(kinds == ["number 1.0", "string two", "null", "object"])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Test
|
|
31
|
+
func `mapUnowned of an empty array is empty`() throws {
|
|
32
|
+
let array = try runtime.eval("[]").getArray()
|
|
33
|
+
#expect(array.mapUnowned { $0.isNumber() }.isEmpty)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Test
|
|
37
|
+
func `mapUnowned rethrows the transform's error`() throws {
|
|
38
|
+
let array = try runtime.eval("[1, 'two']").getArray()
|
|
39
|
+
#expect(throws: (any Error).self) {
|
|
40
|
+
_ = try array.mapUnowned { try $0.asDouble() }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Test
|
|
45
|
+
func `withUnownedProperty lends the property and undefined for a missing one`() throws {
|
|
46
|
+
let object = try runtime.eval("({ answer: 42, name: 'expo' })").getObject()
|
|
47
|
+
#expect(object.withUnownedProperty("answer") { $0.getDouble() } == 42)
|
|
48
|
+
#expect(object.withUnownedProperty("name") { $0.getString() } == "expo")
|
|
49
|
+
#expect(object.withUnownedProperty("missing") { $0.isUndefined() })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Test
|
|
53
|
+
func `containers decode nested values through the unowned path`() throws {
|
|
54
|
+
let value = try runtime.eval("[[1, 2], [3]]")
|
|
55
|
+
#expect(try [[Int]].decode(value, in: runtime) == [[1, 2], [3]])
|
|
56
|
+
let dictionary = try runtime.eval("({ a: [1], b: undefined, c: [2, 3] })")
|
|
57
|
+
#expect(try [String: [Int]].decode(dictionary, in: runtime) == ["a": [1], "c": [2, 3]])
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Test
|
|
61
|
+
func `an unowned value tells arrays apart and reads them`() throws {
|
|
62
|
+
let buffer = JavaScriptValuesBuffer.allocate(
|
|
63
|
+
in: runtime,
|
|
64
|
+
with: try runtime.eval("[1, 2, 3]"),
|
|
65
|
+
try runtime.eval("({ length: 3 })"),
|
|
66
|
+
try runtime.eval("new Uint8Array(3)"),
|
|
67
|
+
try runtime.eval("3")
|
|
68
|
+
)
|
|
69
|
+
// `#expect` can't capture the `~Copyable` value, so compare the results instead.
|
|
70
|
+
let isArray = (0..<4).map { buffer.unownedValue(at: $0).isArray() }
|
|
71
|
+
#expect(isArray == [true, false, false, false])
|
|
72
|
+
let array = buffer.unownedValue(at: 0).getArray(in: runtime)
|
|
73
|
+
#expect(array.length == 3)
|
|
74
|
+
#expect(array.mapUnowned { $0.getDouble() } == [1, 2, 3])
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -208,6 +208,18 @@ build_slice() {
|
|
|
208
208
|
# `___profc_*` symbols and `__llvm_prf_*` sections) plus ~40% extra binary size. Setting
|
|
209
209
|
# CLANG_COVERAGE_MAPPING=NO is what removes the flags; CLANG_ENABLE_CODE_COVERAGE=NO alone
|
|
210
210
|
# does not, and `-enableCodeCoverage NO` is rejected outside of `test`.
|
|
211
|
+
#
|
|
212
|
+
# With a dSYM, Xcode's default STRIP_SWIFT_SYMBOLS=YES runs `strip -T`, which removes or renames to
|
|
213
|
+
# `<redacted>` every Swift symbol that isn't exported. Crash reports symbolicated on the device then
|
|
214
|
+
# show no function name for any frame in this framework. Keeping the symbols adds about 250 KB of
|
|
215
|
+
# symbol table to the device slice; the code itself doesn't change.
|
|
216
|
+
#
|
|
217
|
+
# The binary .swiftmodule must not embed this checkout's absolute paths: consumers key
|
|
218
|
+
# the Xcode compilation cache on its content, so any PACKAGE_DIR or PODS_ROOT path inside
|
|
219
|
+
# it makes every module that imports ExpoModulesJSI a cache miss in another checkout or
|
|
220
|
+
# worktree. SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO drops the serialized search paths and
|
|
221
|
+
# SWIFT_ENABLE_EXPLICIT_MODULES=NO the explicit-module cache directories under
|
|
222
|
+
# .DerivedData. The .swiftinterface and the dSYM are unaffected.
|
|
211
223
|
(cd "$PACKAGE_DIR" && env -i PATH="$PATH" HOME="$HOME" PODS_ROOT="$PODS_ROOT" RN_ROOT="$RN_ROOT" \
|
|
212
224
|
xcodebuild \
|
|
213
225
|
build \
|
|
@@ -226,10 +238,13 @@ build_slice() {
|
|
|
226
238
|
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
|
|
227
239
|
SKIP_INSTALL=NO \
|
|
228
240
|
DEBUG_INFORMATION_FORMAT=dwarf-with-dsym \
|
|
241
|
+
STRIP_SWIFT_SYMBOLS=NO \
|
|
229
242
|
COMPILER_INDEX_STORE_ENABLE=NO \
|
|
230
243
|
SWIFT_COMPILATION_MODE=wholemodule \
|
|
231
244
|
CLANG_ENABLE_CODE_COVERAGE=NO \
|
|
232
245
|
CLANG_COVERAGE_MAPPING=NO \
|
|
246
|
+
SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO \
|
|
247
|
+
SWIFT_ENABLE_EXPLICIT_MODULES=NO \
|
|
233
248
|
)
|
|
234
249
|
|
|
235
250
|
local product_path="${BUILD_PRODUCTS_PATH}/${build_dir_name}"
|