expo-modules-core 3.0.21 → 3.0.22
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
CHANGED
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 3.0.22 — 2025-10-20
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- [iOS] Introduce ExpoAppDelegateSubscriberManager class ([#40008](https://github.com/expo/expo/pull/40008) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
18
|
+
|
|
13
19
|
## 3.0.21 — 2025-10-09
|
|
14
20
|
|
|
15
21
|
### 💡 Others
|
package/android/build.gradle
CHANGED
|
@@ -29,7 +29,7 @@ if (shouldIncludeCompose) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
group = 'host.exp.exponent'
|
|
32
|
-
version = '3.0.
|
|
32
|
+
version = '3.0.22'
|
|
33
33
|
|
|
34
34
|
def isExpoModulesCoreTests = {
|
|
35
35
|
Gradle gradle = getGradle()
|
|
@@ -79,7 +79,7 @@ android {
|
|
|
79
79
|
defaultConfig {
|
|
80
80
|
consumerProguardFiles 'proguard-rules.pro'
|
|
81
81
|
versionCode 1
|
|
82
|
-
versionName "3.0.
|
|
82
|
+
versionName "3.0.22"
|
|
83
83
|
buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
|
|
84
84
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
|
|
85
85
|
|
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
import Dispatch
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
public class ExpoAppDelegateSubscriberManager: NSObject {
|
|
5
|
+
#if os(iOS) || os(tvOS)
|
|
6
|
+
|
|
7
|
+
@objc
|
|
8
|
+
public static func application(
|
|
9
|
+
_ application: UIApplication,
|
|
10
|
+
willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
|
11
|
+
) -> Bool {
|
|
12
|
+
let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
|
|
13
|
+
$0.responds(to: #selector(application(_:willFinishLaunchingWithOptions:)))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// If we can't find a subscriber that implements `willFinishLaunchingWithOptions`, we will delegate the decision if we can handel the passed URL to
|
|
17
|
+
// the `didFinishLaunchingWithOptions` method by returning `true` here.
|
|
18
|
+
// You can read more about how iOS handles deep links here: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application#discussion
|
|
19
|
+
if parsedSubscribers.isEmpty {
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return parsedSubscribers.reduce(false) { result, subscriber in
|
|
24
|
+
return subscriber.application?(application, willFinishLaunchingWithOptions: launchOptions) ?? false || result
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@objc
|
|
29
|
+
public static func application(
|
|
30
|
+
_ application: UIApplication,
|
|
31
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
|
32
|
+
) -> Bool {
|
|
33
|
+
ExpoAppDelegateSubscriberRepository.subscribers.forEach { subscriber in
|
|
34
|
+
// Subscriber result is ignored as it doesn't matter if any subscriber handled the incoming URL – we always return `true` anyway.
|
|
35
|
+
_ = subscriber.application?(application, didFinishLaunchingWithOptions: launchOptions)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return true
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#elseif os(macOS)
|
|
42
|
+
@objc
|
|
43
|
+
public static func applicationWillFinishLaunching(_ notification: Notification) {
|
|
44
|
+
let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
|
|
45
|
+
$0.responds(to: #selector(applicationWillFinishLaunching(_:)))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
parsedSubscribers.forEach { subscriber in
|
|
49
|
+
subscriber.applicationWillFinishLaunching?(notification)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@objc
|
|
54
|
+
public static func applicationDidFinishLaunching(_ notification: Notification) {
|
|
55
|
+
ExpoAppDelegateSubscriberRepository
|
|
56
|
+
.subscribers
|
|
57
|
+
.forEach { subscriber in
|
|
58
|
+
// Subscriber result is ignored as it doesn't matter if any subscriber handled the incoming URL – we always return `true` anyway.
|
|
59
|
+
_ = subscriber.applicationDidFinishLaunching?(notification)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// TODO: - Configuring and Discarding Scenes
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
// MARK: - Responding to App Life-Cycle Events
|
|
67
|
+
|
|
68
|
+
#if os(iOS) || os(tvOS)
|
|
69
|
+
|
|
70
|
+
@objc
|
|
71
|
+
public static func applicationDidBecomeActive(_ application: UIApplication) {
|
|
72
|
+
ExpoAppDelegateSubscriberRepository
|
|
73
|
+
.subscribers
|
|
74
|
+
.forEach { $0.applicationDidBecomeActive?(application) }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@objc
|
|
78
|
+
public static func applicationWillResignActive(_ application: UIApplication) {
|
|
79
|
+
ExpoAppDelegateSubscriberRepository
|
|
80
|
+
.subscribers
|
|
81
|
+
.forEach { $0.applicationWillResignActive?(application) }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@objc
|
|
85
|
+
public static func applicationDidEnterBackground(_ application: UIApplication) {
|
|
86
|
+
ExpoAppDelegateSubscriberRepository
|
|
87
|
+
.subscribers
|
|
88
|
+
.forEach { $0.applicationDidEnterBackground?(application) }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@objc
|
|
92
|
+
public static func applicationWillEnterForeground(_ application: UIApplication) {
|
|
93
|
+
ExpoAppDelegateSubscriberRepository
|
|
94
|
+
.subscribers
|
|
95
|
+
.forEach { $0.applicationWillEnterForeground?(application) }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@objc
|
|
99
|
+
public static func applicationWillTerminate(_ application: UIApplication) {
|
|
100
|
+
ExpoAppDelegateSubscriberRepository
|
|
101
|
+
.subscribers
|
|
102
|
+
.forEach { $0.applicationWillTerminate?(application) }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#elseif os(macOS)
|
|
106
|
+
@objc
|
|
107
|
+
public static func applicationDidBecomeActive(_ notification: Notification) {
|
|
108
|
+
ExpoAppDelegateSubscriberRepository
|
|
109
|
+
.subscribers
|
|
110
|
+
.forEach { $0.applicationDidBecomeActive?(notification) }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@objc
|
|
114
|
+
public static func applicationWillResignActive(_ notification: Notification) {
|
|
115
|
+
ExpoAppDelegateSubscriberRepository
|
|
116
|
+
.subscribers
|
|
117
|
+
.forEach { $0.applicationWillResignActive?(notification) }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@objc
|
|
121
|
+
public static func applicationDidHide(_ notification: Notification) {
|
|
122
|
+
ExpoAppDelegateSubscriberRepository
|
|
123
|
+
.subscribers
|
|
124
|
+
.forEach { $0.applicationDidHide?(notification) }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@objc
|
|
128
|
+
public static func applicationWillUnhide(_ notification: Notification) {
|
|
129
|
+
ExpoAppDelegateSubscriberRepository
|
|
130
|
+
.subscribers
|
|
131
|
+
.forEach { $0.applicationWillUnhide?(notification) }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@objc
|
|
135
|
+
public static func applicationWillTerminate(_ notification: Notification) {
|
|
136
|
+
ExpoAppDelegateSubscriberRepository
|
|
137
|
+
.subscribers
|
|
138
|
+
.forEach { $0.applicationWillTerminate?(notification) }
|
|
139
|
+
}
|
|
140
|
+
#endif
|
|
141
|
+
|
|
142
|
+
// TODO: - Responding to Environment Changes
|
|
143
|
+
|
|
144
|
+
// TODO: - Managing App State Restoration
|
|
145
|
+
|
|
146
|
+
// MARK: - Downloading Data in the Background
|
|
147
|
+
|
|
148
|
+
#if os(iOS) || os(tvOS)
|
|
149
|
+
@objc
|
|
150
|
+
public static func application(
|
|
151
|
+
_ application: UIApplication,
|
|
152
|
+
handleEventsForBackgroundURLSession identifier: String,
|
|
153
|
+
completionHandler: @escaping () -> Void
|
|
154
|
+
) {
|
|
155
|
+
let selector = #selector(application(_:handleEventsForBackgroundURLSession:completionHandler:))
|
|
156
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
157
|
+
var subscribersLeft = subs.count
|
|
158
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.handleBackgroundEvents")
|
|
159
|
+
|
|
160
|
+
let handler = {
|
|
161
|
+
dispatchQueue.sync {
|
|
162
|
+
subscribersLeft -= 1
|
|
163
|
+
|
|
164
|
+
if subscribersLeft == 0 {
|
|
165
|
+
completionHandler()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if subs.isEmpty {
|
|
171
|
+
completionHandler()
|
|
172
|
+
} else {
|
|
173
|
+
subs.forEach {
|
|
174
|
+
$0.application?(application, handleEventsForBackgroundURLSession: identifier, completionHandler: handler)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
#endif
|
|
180
|
+
|
|
181
|
+
// MARK: - Handling Remote Notification Registration
|
|
182
|
+
|
|
183
|
+
@objc
|
|
184
|
+
public static func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
185
|
+
ExpoAppDelegateSubscriberRepository
|
|
186
|
+
.subscribers
|
|
187
|
+
.forEach { $0.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@objc
|
|
191
|
+
public static func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
|
192
|
+
ExpoAppDelegateSubscriberRepository
|
|
193
|
+
.subscribers
|
|
194
|
+
.forEach { $0.application?(application, didFailToRegisterForRemoteNotificationsWithError: error) }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#if os(iOS) || os(tvOS)
|
|
198
|
+
@objc
|
|
199
|
+
public static func application(
|
|
200
|
+
_ application: UIApplication,
|
|
201
|
+
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
|
|
202
|
+
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
|
|
203
|
+
) {
|
|
204
|
+
let selector = #selector(application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
|
|
205
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
206
|
+
var subscribersLeft = subs.count
|
|
207
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.remoteNotification", qos: .userInteractive)
|
|
208
|
+
var failedCount = 0
|
|
209
|
+
var newDataCount = 0
|
|
210
|
+
|
|
211
|
+
let handler = { (result: UIBackgroundFetchResult) in
|
|
212
|
+
dispatchQueue.sync {
|
|
213
|
+
if result == .failed {
|
|
214
|
+
failedCount += 1
|
|
215
|
+
} else if result == .newData {
|
|
216
|
+
newDataCount += 1
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
subscribersLeft -= 1
|
|
220
|
+
|
|
221
|
+
if subscribersLeft == 0 {
|
|
222
|
+
if newDataCount > 0 {
|
|
223
|
+
completionHandler(.newData)
|
|
224
|
+
} else if failedCount > 0 {
|
|
225
|
+
completionHandler(.failed)
|
|
226
|
+
} else {
|
|
227
|
+
completionHandler(.noData)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if subs.isEmpty {
|
|
234
|
+
completionHandler(.noData)
|
|
235
|
+
} else {
|
|
236
|
+
subs.forEach { subscriber in
|
|
237
|
+
subscriber.application?(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: handler)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#elseif os(macOS)
|
|
243
|
+
@objc
|
|
244
|
+
public static func application(
|
|
245
|
+
_ application: NSApplication,
|
|
246
|
+
didReceiveRemoteNotification userInfo: [String: Any]
|
|
247
|
+
) {
|
|
248
|
+
let selector = #selector(application(_:didReceiveRemoteNotification:))
|
|
249
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
250
|
+
|
|
251
|
+
subs.forEach { subscriber in
|
|
252
|
+
subscriber.application?(application, didReceiveRemoteNotification: userInfo)
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
#endif
|
|
256
|
+
|
|
257
|
+
// MARK: - Continuing User Activity and Handling Quick Actions
|
|
258
|
+
|
|
259
|
+
@objc
|
|
260
|
+
public static func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
|
|
261
|
+
return ExpoAppDelegateSubscriberRepository
|
|
262
|
+
.subscribers
|
|
263
|
+
.reduce(false) { result, subscriber in
|
|
264
|
+
return subscriber.application?(application, willContinueUserActivityWithType: userActivityType) ?? false || result
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#if os(iOS) || os(tvOS)
|
|
269
|
+
@objc
|
|
270
|
+
public static func application(
|
|
271
|
+
_ application: UIApplication,
|
|
272
|
+
continue userActivity: NSUserActivity,
|
|
273
|
+
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
|
|
274
|
+
) -> Bool {
|
|
275
|
+
let selector = #selector(application(_:continue:restorationHandler:))
|
|
276
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
277
|
+
var subscribersLeft = subs.count
|
|
278
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.continueUserActivity", qos: .userInteractive)
|
|
279
|
+
var allRestorableObjects = [UIUserActivityRestoring]()
|
|
280
|
+
|
|
281
|
+
let handler = { (restorableObjects: [UIUserActivityRestoring]?) in
|
|
282
|
+
dispatchQueue.sync {
|
|
283
|
+
if let restorableObjects = restorableObjects {
|
|
284
|
+
allRestorableObjects.append(contentsOf: restorableObjects)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
subscribersLeft -= 1
|
|
288
|
+
|
|
289
|
+
if subscribersLeft == 0 {
|
|
290
|
+
restorationHandler(allRestorableObjects)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return subs.reduce(false) { result, subscriber in
|
|
296
|
+
return subscriber.application?(application, continue: userActivity, restorationHandler: handler) ?? false || result
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
#elseif os(macOS)
|
|
300
|
+
@objc
|
|
301
|
+
public static func application(
|
|
302
|
+
_ application: NSApplication,
|
|
303
|
+
continue userActivity: NSUserActivity,
|
|
304
|
+
restorationHandler: @escaping ([any NSUserActivityRestoring]) -> Void
|
|
305
|
+
) -> Bool {
|
|
306
|
+
let selector = #selector(application(_:continue:restorationHandler:))
|
|
307
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
308
|
+
var subscribersLeft = subs.count
|
|
309
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.continueUserActivity", qos: .userInteractive)
|
|
310
|
+
var allRestorableObjects = [NSUserActivityRestoring]()
|
|
311
|
+
|
|
312
|
+
let handler = { (restorableObjects: [NSUserActivityRestoring]?) in
|
|
313
|
+
dispatchQueue.sync {
|
|
314
|
+
if let restorableObjects = restorableObjects {
|
|
315
|
+
allRestorableObjects.append(contentsOf: restorableObjects)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
subscribersLeft -= 1
|
|
319
|
+
|
|
320
|
+
if subscribersLeft == 0 {
|
|
321
|
+
restorationHandler(allRestorableObjects)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return subs.reduce(false) { result, subscriber in
|
|
327
|
+
return subscriber.application?(application, continue: userActivity, restorationHandler: handler) ?? false || result
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
#endif
|
|
331
|
+
|
|
332
|
+
@objc
|
|
333
|
+
public static func application(_ application: UIApplication, didUpdate userActivity: NSUserActivity) {
|
|
334
|
+
return ExpoAppDelegateSubscriberRepository
|
|
335
|
+
.subscribers
|
|
336
|
+
.forEach { $0.application?(application, didUpdate: userActivity) }
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
@objc
|
|
340
|
+
public static func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) {
|
|
341
|
+
return ExpoAppDelegateSubscriberRepository
|
|
342
|
+
.subscribers
|
|
343
|
+
.forEach {
|
|
344
|
+
$0.application?(application, didFailToContinueUserActivityWithType: userActivityType, error: error)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
#if os(iOS)
|
|
349
|
+
@objc
|
|
350
|
+
public static func application(
|
|
351
|
+
_ application: UIApplication,
|
|
352
|
+
performActionFor shortcutItem: UIApplicationShortcutItem,
|
|
353
|
+
completionHandler: @escaping (Bool) -> Void
|
|
354
|
+
) {
|
|
355
|
+
let selector = #selector(application(_:performActionFor:completionHandler:))
|
|
356
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
357
|
+
var subscribersLeft = subs.count
|
|
358
|
+
var result: Bool = false
|
|
359
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.performAction", qos: .userInteractive)
|
|
360
|
+
|
|
361
|
+
let handler = { (succeeded: Bool) in
|
|
362
|
+
dispatchQueue.sync {
|
|
363
|
+
result = result || succeeded
|
|
364
|
+
subscribersLeft -= 1
|
|
365
|
+
|
|
366
|
+
if subscribersLeft == 0 {
|
|
367
|
+
completionHandler(result)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if subs.isEmpty {
|
|
373
|
+
completionHandler(result)
|
|
374
|
+
} else {
|
|
375
|
+
subs.forEach { subscriber in
|
|
376
|
+
subscriber.application?(application, performActionFor: shortcutItem, completionHandler: handler)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
#endif
|
|
381
|
+
|
|
382
|
+
// MARK: - Background Fetch
|
|
383
|
+
|
|
384
|
+
#if os(iOS) || os(tvOS)
|
|
385
|
+
@objc
|
|
386
|
+
public static func application(
|
|
387
|
+
_ application: UIApplication,
|
|
388
|
+
performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
|
|
389
|
+
) {
|
|
390
|
+
let selector = #selector(application(_:performFetchWithCompletionHandler:))
|
|
391
|
+
let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
|
|
392
|
+
var subscribersLeft = subs.count
|
|
393
|
+
let dispatchQueue = DispatchQueue(label: "expo.application.performFetch", qos: .userInteractive)
|
|
394
|
+
var failedCount = 0
|
|
395
|
+
var newDataCount = 0
|
|
396
|
+
|
|
397
|
+
let handler = { (result: UIBackgroundFetchResult) in
|
|
398
|
+
dispatchQueue.sync {
|
|
399
|
+
if result == .failed {
|
|
400
|
+
failedCount += 1
|
|
401
|
+
} else if result == .newData {
|
|
402
|
+
newDataCount += 1
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
subscribersLeft -= 1
|
|
406
|
+
|
|
407
|
+
if subscribersLeft == 0 {
|
|
408
|
+
if newDataCount > 0 {
|
|
409
|
+
completionHandler(.newData)
|
|
410
|
+
} else if failedCount > 0 {
|
|
411
|
+
completionHandler(.failed)
|
|
412
|
+
} else {
|
|
413
|
+
completionHandler(.noData)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if subs.isEmpty {
|
|
420
|
+
completionHandler(.noData)
|
|
421
|
+
} else {
|
|
422
|
+
subs.forEach { subscriber in
|
|
423
|
+
subscriber.application?(application, performFetchWithCompletionHandler: handler)
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
#endif
|
|
429
|
+
|
|
430
|
+
// MARK: - Opening a URL-Specified Resource
|
|
431
|
+
#if os(iOS) || os(tvOS)
|
|
432
|
+
|
|
433
|
+
@objc
|
|
434
|
+
public static func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
|
435
|
+
return ExpoAppDelegateSubscriberRepository.subscribers.reduce(false) { result, subscriber in
|
|
436
|
+
return subscriber.application?(app, open: url, options: options) ?? false || result
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
#elseif os(macOS)
|
|
440
|
+
@objc
|
|
441
|
+
public static func application(_ app: NSApplication, open urls: [URL]) {
|
|
442
|
+
ExpoAppDelegateSubscriberRepository.subscribers.forEach { subscriber in
|
|
443
|
+
subscriber.application?(app, open: urls)
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
#endif
|
|
447
|
+
|
|
448
|
+
#if os(iOS)
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Sets allowed orientations for the application. It will use the values from `Info.plist`as the orientation mask unless a subscriber requested
|
|
452
|
+
* a different orientation.
|
|
453
|
+
*/
|
|
454
|
+
@objc
|
|
455
|
+
public static func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
|
456
|
+
let deviceOrientationMask = allowedOrientations(for: UIDevice.current.userInterfaceIdiom)
|
|
457
|
+
let universalOrientationMask = allowedOrientations(for: .unspecified)
|
|
458
|
+
let infoPlistOrientations = deviceOrientationMask.isEmpty ? universalOrientationMask : deviceOrientationMask
|
|
459
|
+
|
|
460
|
+
let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
|
|
461
|
+
$0.responds(to: #selector(application(_:supportedInterfaceOrientationsFor:)))
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// We want to create an intersection of all orientations set by subscribers.
|
|
465
|
+
let subscribersMask: UIInterfaceOrientationMask = parsedSubscribers.reduce(.all) { result, subscriber in
|
|
466
|
+
guard let requestedOrientation = subscriber.application?(application, supportedInterfaceOrientationsFor: window) else {
|
|
467
|
+
return result
|
|
468
|
+
}
|
|
469
|
+
return requestedOrientation.intersection(result)
|
|
470
|
+
}
|
|
471
|
+
return parsedSubscribers.isEmpty ? infoPlistOrientations : subscribersMask
|
|
472
|
+
}
|
|
473
|
+
#endif
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
#if os(iOS)
|
|
477
|
+
private func allowedOrientations(for userInterfaceIdiom: UIUserInterfaceIdiom) -> UIInterfaceOrientationMask {
|
|
478
|
+
// For now only iPad-specific orientations are supported
|
|
479
|
+
let deviceString = userInterfaceIdiom == .pad ? "~pad" : ""
|
|
480
|
+
var mask: UIInterfaceOrientationMask = []
|
|
481
|
+
guard let orientations = Bundle.main.infoDictionary?["UISupportedInterfaceOrientations\(deviceString)"] as? [String] else {
|
|
482
|
+
return mask
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
for orientation in orientations {
|
|
486
|
+
switch orientation {
|
|
487
|
+
case "UIInterfaceOrientationPortrait":
|
|
488
|
+
mask.insert(.portrait)
|
|
489
|
+
case "UIInterfaceOrientationLandscapeLeft":
|
|
490
|
+
mask.insert(.landscapeLeft)
|
|
491
|
+
case "UIInterfaceOrientationLandscapeRight":
|
|
492
|
+
mask.insert(.landscapeRight)
|
|
493
|
+
case "UIInterfaceOrientationPortraitUpsideDown":
|
|
494
|
+
mask.insert(.portraitUpsideDown)
|
|
495
|
+
default:
|
|
496
|
+
break
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return mask
|
|
500
|
+
}
|
|
501
|
+
#endif // os(iOS)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.22",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"@testing-library/react-native": "^13.2.0",
|
|
66
66
|
"expo-module-scripts": "^5.0.7"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "ea56136a4420322f46d00e4b1549595d8f85150e"
|
|
69
69
|
}
|