@nativescript/core 9.0.0-preview.3 → 9.0.1
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/application/application-common.d.ts +40 -14
- package/application/application-common.js +109 -5
- package/application/application-common.js.map +1 -1
- package/application/application-interfaces.d.ts +31 -0
- package/application/application-shims.d.ts +27 -0
- package/application/application-shims.js +27 -0
- package/application/application-shims.js.map +1 -1
- package/application/application.android.d.ts +12 -2
- package/application/application.android.js +380 -343
- package/application/application.android.js.map +1 -1
- package/application/application.d.ts +74 -1
- package/application/application.ios.d.ts +68 -1
- package/application/application.ios.js +642 -16
- package/application/application.ios.js.map +1 -1
- package/application/helpers.android.d.ts +0 -9
- package/application/helpers.android.js +0 -54
- package/application/helpers.android.js.map +1 -1
- package/application/helpers.d.ts +0 -10
- package/application/helpers.ios.d.ts +0 -19
- package/application/helpers.ios.js +0 -38
- package/application/helpers.ios.js.map +1 -1
- package/cli-hooks/{before-checkForChanges.js → before-checkForChanges.mjs} +7 -7
- package/cli-hooks/postinstall.mjs +7 -0
- package/cli-hooks/preuninstall.mjs +7 -0
- package/config/config.interface.d.ts +21 -0
- package/connectivity/index.android.js +25 -25
- package/connectivity/index.android.js.map +1 -1
- package/core-types/index.d.ts +78 -63
- package/core-types/index.js +11 -1
- package/core-types/index.js.map +1 -1
- package/core-types/validators.js +14 -5
- package/core-types/validators.js.map +1 -1
- package/data/observable/index.d.ts +2 -1
- package/data/observable/index.js +31 -19
- package/data/observable/index.js.map +1 -1
- package/fps-meter/fps-native.ios.js +1 -1
- package/fps-meter/fps-native.ios.js.map +1 -1
- package/globals/index.js +1 -2
- package/globals/index.js.map +1 -1
- package/http/http-request/index.ios.js +1 -1
- package/http/http-request/index.ios.js.map +1 -1
- package/image-asset/image-asset-common.js +31 -3
- package/image-asset/image-asset-common.js.map +1 -1
- package/image-source/index.android.js +4 -3
- package/image-source/index.android.js.map +1 -1
- package/image-source/index.d.ts +2 -2
- package/index.d.ts +1 -0
- package/index.js +0 -1
- package/index.js.map +1 -1
- package/inspector_modules.d.ts +0 -5
- package/inspector_modules.js +223 -103
- package/inspector_modules.js.map +1 -1
- package/package.json +15 -13
- package/platform/screen/index.d.ts +5 -0
- package/platforms/android/widgets-release.aar +0 -0
- package/references.d.ts +1 -1
- package/timer/index.android.js +15 -7
- package/timer/index.android.js.map +1 -1
- package/timer/index.ios.js +1 -1
- package/timer/index.ios.js.map +1 -1
- package/ui/action-bar/index.android.js +16 -18
- package/ui/action-bar/index.android.js.map +1 -1
- package/ui/action-bar/index.ios.d.ts +1 -0
- package/ui/action-bar/index.ios.js +28 -4
- package/ui/action-bar/index.ios.js.map +1 -1
- package/ui/animation/index.d.ts +14 -1
- package/ui/animation/index.ios.js +2 -3
- package/ui/animation/index.ios.js.map +1 -1
- package/ui/button/index.android.js +20 -20
- package/ui/button/index.android.js.map +1 -1
- package/ui/button/index.d.ts +1 -1
- package/ui/button/index.ios.d.ts +2 -1
- package/ui/button/index.ios.js +28 -10
- package/ui/button/index.ios.js.map +1 -1
- package/ui/core/control-state-change/index.ios.js +1 -1
- package/ui/core/control-state-change/index.ios.js.map +1 -1
- package/ui/core/properties/index.js +64 -52
- package/ui/core/properties/index.js.map +1 -1
- package/ui/core/view/index.android.d.ts +19 -2
- package/ui/core/view/index.android.js +544 -200
- package/ui/core/view/index.android.js.map +1 -1
- package/ui/core/view/index.d.ts +55 -4
- package/ui/core/view/index.ios.d.ts +19 -2
- package/ui/core/view/index.ios.js +148 -10
- package/ui/core/view/index.ios.js.map +1 -1
- package/ui/core/view/view-common.d.ts +70 -10
- package/ui/core/view/view-common.js +66 -1
- package/ui/core/view/view-common.js.map +1 -1
- package/ui/core/view/view-helper/index.d.ts +5 -0
- package/ui/core/view/view-helper/index.ios.d.ts +6 -4
- package/ui/core/view/view-helper/index.ios.js +37 -20
- package/ui/core/view/view-helper/index.ios.js.map +1 -1
- package/ui/core/view/view-helper/view-helper-common.js +7 -0
- package/ui/core/view/view-helper/view-helper-common.js.map +1 -1
- package/ui/core/view/view-interfaces.d.ts +22 -0
- package/ui/core/view-base/index.d.ts +4 -0
- package/ui/core/view-base/index.js.map +1 -1
- package/ui/date-picker/index.android.js +36 -38
- package/ui/date-picker/index.android.js.map +1 -1
- package/ui/date-picker/index.ios.js +1 -1
- package/ui/date-picker/index.ios.js.map +1 -1
- package/ui/dialogs/index.ios.js +4 -2
- package/ui/dialogs/index.ios.js.map +1 -1
- package/ui/editable-text-base/editable-text-base-common.js +1 -1
- package/ui/editable-text-base/editable-text-base-common.js.map +1 -1
- package/ui/editable-text-base/index.android.d.ts +1 -1
- package/ui/editable-text-base/index.android.js +35 -34
- package/ui/editable-text-base/index.android.js.map +1 -1
- package/ui/editable-text-base/index.ios.d.ts +1 -1
- package/ui/editable-text-base/index.ios.js +3 -0
- package/ui/editable-text-base/index.ios.js.map +1 -1
- package/ui/frame/activity.android.js +3 -0
- package/ui/frame/activity.android.js.map +1 -1
- package/ui/frame/fragment.transitions.android.d.ts +2 -1
- package/ui/frame/fragment.transitions.android.js +103 -104
- package/ui/frame/fragment.transitions.android.js.map +1 -1
- package/ui/frame/fragment.transitions.d.ts +3 -2
- package/ui/frame/frame-interfaces.d.ts +18 -8
- package/ui/frame/index.android.d.ts +2 -0
- package/ui/frame/index.android.js +57 -2
- package/ui/frame/index.android.js.map +1 -1
- package/ui/frame/index.d.ts +1 -1
- package/ui/frame/index.ios.d.ts +3 -1
- package/ui/frame/index.ios.js +94 -59
- package/ui/frame/index.ios.js.map +1 -1
- package/ui/gestures/index.android.js +129 -130
- package/ui/gestures/index.android.js.map +1 -1
- package/ui/gestures/index.ios.js +3 -5
- package/ui/gestures/index.ios.js.map +1 -1
- package/ui/gestures/touch-manager.js +32 -32
- package/ui/gestures/touch-manager.js.map +1 -1
- package/ui/image/index.android.js +17 -19
- package/ui/image/index.android.js.map +1 -1
- package/ui/image-cache/index.android.js +12 -14
- package/ui/image-cache/index.android.js.map +1 -1
- package/ui/image-cache/index.ios.js +6 -6
- package/ui/image-cache/index.ios.js.map +1 -1
- package/ui/index.d.ts +10 -4
- package/ui/index.js +4 -1
- package/ui/index.js.map +1 -1
- package/ui/label/index.android.js +4 -1
- package/ui/label/index.android.js.map +1 -1
- package/ui/label/index.ios.d.ts +2 -1
- package/ui/label/index.ios.js +12 -2
- package/ui/label/index.ios.js.map +1 -1
- package/ui/layouts/flexbox-layout/index.ios.js +3 -6
- package/ui/layouts/flexbox-layout/index.ios.js.map +1 -1
- package/ui/layouts/index.d.ts +5 -1
- package/ui/layouts/index.js +2 -0
- package/ui/layouts/index.js.map +1 -1
- package/ui/layouts/liquid-glass/index.android.d.ts +5 -0
- package/ui/layouts/liquid-glass/index.android.js +8 -0
- package/ui/layouts/liquid-glass/index.android.js.map +1 -0
- package/ui/layouts/liquid-glass/index.d.ts +10 -0
- package/ui/layouts/liquid-glass/index.ios.d.ts +10 -0
- package/ui/layouts/liquid-glass/index.ios.js +59 -0
- package/ui/layouts/liquid-glass/index.ios.js.map +1 -0
- package/ui/layouts/liquid-glass/liquid-glass-common.d.ts +3 -0
- package/ui/layouts/liquid-glass/liquid-glass-common.js +4 -0
- package/ui/layouts/liquid-glass/liquid-glass-common.js.map +1 -0
- package/ui/layouts/liquid-glass-container/index.android.d.ts +3 -0
- package/ui/layouts/liquid-glass-container/index.android.js +4 -0
- package/ui/layouts/liquid-glass-container/index.android.js.map +1 -0
- package/ui/layouts/liquid-glass-container/index.d.ts +3 -0
- package/ui/layouts/liquid-glass-container/index.ios.d.ts +14 -0
- package/ui/layouts/liquid-glass-container/index.ios.js +121 -0
- package/ui/layouts/liquid-glass-container/index.ios.js.map +1 -0
- package/ui/layouts/liquid-glass-container/liquid-glass-container-common.d.ts +4 -0
- package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js +5 -0
- package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js.map +1 -0
- package/ui/layouts/stack-layout/index.ios.js +6 -0
- package/ui/layouts/stack-layout/index.ios.js.map +1 -1
- package/ui/list-picker/index.android.js +31 -35
- package/ui/list-picker/index.android.js.map +1 -1
- package/ui/list-picker/index.ios.js +2 -2
- package/ui/list-picker/index.ios.js.map +1 -1
- package/ui/list-view/index.android.js +320 -321
- package/ui/list-view/index.android.js.map +1 -1
- package/ui/list-view/index.d.ts +7 -2
- package/ui/list-view/index.ios.d.ts +1 -1
- package/ui/list-view/index.ios.js +12 -27
- package/ui/list-view/index.ios.js.map +1 -1
- package/ui/page/index.android.d.ts +1 -10
- package/ui/page/index.android.js +1 -45
- package/ui/page/index.android.js.map +1 -1
- package/ui/page/index.d.ts +0 -8
- package/ui/page/index.ios.d.ts +1 -3
- package/ui/page/index.ios.js +33 -91
- package/ui/page/index.ios.js.map +1 -1
- package/ui/page/page-common.d.ts +0 -6
- package/ui/page/page-common.js +0 -14
- package/ui/page/page-common.js.map +1 -1
- package/ui/scroll-view/index.d.ts +1 -1
- package/ui/scroll-view/index.ios.d.ts +2 -0
- package/ui/scroll-view/index.ios.js +31 -12
- package/ui/scroll-view/index.ios.js.map +1 -1
- package/ui/scroll-view/scroll-view-common.d.ts +3 -8
- package/ui/scroll-view/scroll-view-common.js +4 -4
- package/ui/scroll-view/scroll-view-common.js.map +1 -1
- package/ui/search-bar/index.android.d.ts +2 -1
- package/ui/search-bar/index.android.js +64 -53
- package/ui/search-bar/index.android.js.map +1 -1
- package/ui/search-bar/index.d.ts +7 -0
- package/ui/search-bar/index.ios.d.ts +2 -1
- package/ui/search-bar/index.ios.js +14 -7
- package/ui/search-bar/index.ios.js.map +1 -1
- package/ui/search-bar/search-bar-common.d.ts +2 -0
- package/ui/search-bar/search-bar-common.js +7 -0
- package/ui/search-bar/search-bar-common.js.map +1 -1
- package/ui/segmented-bar/index.android.js +52 -58
- package/ui/segmented-bar/index.android.js.map +1 -1
- package/ui/segmented-bar/index.ios.js +1 -1
- package/ui/segmented-bar/index.ios.js.map +1 -1
- package/ui/slider/index.android.js +22 -25
- package/ui/slider/index.android.js.map +1 -1
- package/ui/slider/index.d.ts +1 -1
- package/ui/slider/index.ios.js +2 -2
- package/ui/slider/index.ios.js.map +1 -1
- package/ui/split-view/index.android.d.ts +4 -0
- package/ui/split-view/index.android.js +4 -0
- package/ui/split-view/index.android.js.map +1 -0
- package/ui/split-view/index.d.ts +11 -0
- package/ui/split-view/index.ios.d.ts +39 -0
- package/ui/split-view/index.ios.js +368 -0
- package/ui/split-view/index.ios.js.map +1 -0
- package/ui/split-view/split-view-common.d.ts +51 -0
- package/ui/split-view/split-view-common.js +111 -0
- package/ui/split-view/split-view-common.js.map +1 -0
- package/ui/styling/background-common.d.ts +4 -4
- package/ui/styling/background-common.js +8 -8
- package/ui/styling/background-common.js.map +1 -1
- package/ui/styling/background.d.ts +0 -3
- package/ui/styling/background.ios.d.ts +2 -1
- package/ui/styling/background.ios.js +47 -38
- package/ui/styling/background.ios.js.map +1 -1
- package/ui/styling/css-stroke.js.map +1 -1
- package/ui/styling/css-utils.d.ts +1 -0
- package/ui/styling/css-utils.js +15 -4
- package/ui/styling/css-utils.js.map +1 -1
- package/ui/styling/style/index.d.ts +3 -1
- package/ui/styling/style/index.js.map +1 -1
- package/ui/styling/style-properties.d.ts +1 -0
- package/ui/styling/style-properties.js +30 -11
- package/ui/styling/style-properties.js.map +1 -1
- package/ui/switch/index.android.js +16 -18
- package/ui/switch/index.android.js.map +1 -1
- package/ui/switch/index.ios.d.ts +1 -1
- package/ui/switch/index.ios.js +62 -25
- package/ui/switch/index.ios.js.map +1 -1
- package/ui/tab-view/index.android.js +185 -187
- package/ui/tab-view/index.android.js.map +1 -1
- package/ui/tab-view/index.d.ts +17 -1
- package/ui/tab-view/index.ios.d.ts +13 -5
- package/ui/tab-view/index.ios.js +255 -57
- package/ui/tab-view/index.ios.js.map +1 -1
- package/ui/tab-view/tab-view-common.d.ts +14 -0
- package/ui/tab-view/tab-view-common.js +15 -0
- package/ui/tab-view/tab-view-common.js.map +1 -1
- package/ui/text-base/index.android.d.ts +2 -1
- package/ui/text-base/index.android.js +134 -101
- package/ui/text-base/index.android.js.map +1 -1
- package/ui/text-base/index.d.ts +5 -0
- package/ui/text-base/index.ios.js +12 -18
- package/ui/text-base/index.ios.js.map +1 -1
- package/ui/text-base/text-base-common.d.ts +2 -1
- package/ui/text-base/text-base-common.js +1 -0
- package/ui/text-base/text-base-common.js.map +1 -1
- package/ui/text-field/index.android.js +3 -0
- package/ui/text-field/index.android.js.map +1 -1
- package/ui/text-field/index.ios.d.ts +2 -1
- package/ui/text-field/index.ios.js +9 -5
- package/ui/text-field/index.ios.js.map +1 -1
- package/ui/text-view/index.ios.d.ts +2 -1
- package/ui/text-view/index.ios.js +12 -7
- package/ui/text-view/index.ios.js.map +1 -1
- package/ui/time-picker/index.android.js +19 -21
- package/ui/time-picker/index.android.js.map +1 -1
- package/ui/time-picker/index.ios.js +1 -1
- package/ui/time-picker/index.ios.js.map +1 -1
- package/ui/transition/fade-transition.ios.js +5 -6
- package/ui/transition/fade-transition.ios.js.map +1 -1
- package/ui/transition/modal-transition.ios.js +19 -26
- package/ui/transition/modal-transition.ios.js.map +1 -1
- package/ui/transition/page-transition.android.js +18 -13
- package/ui/transition/page-transition.android.js.map +1 -1
- package/ui/transition/page-transition.ios.js +19 -25
- package/ui/transition/page-transition.ios.js.map +1 -1
- package/ui/transition/slide-transition.ios.js +5 -6
- package/ui/transition/slide-transition.ios.js.map +1 -1
- package/ui/web-view/index.android.js +58 -62
- package/ui/web-view/index.android.js.map +1 -1
- package/ui/web-view/index.ios.js +18 -18
- package/ui/web-view/index.ios.js.map +1 -1
- package/utils/common.d.ts +3 -1
- package/utils/common.js +9 -3
- package/utils/common.js.map +1 -1
- package/utils/constants.android.d.ts +1 -0
- package/utils/constants.android.js +3 -0
- package/utils/constants.android.js.map +1 -1
- package/utils/constants.d.ts +1 -0
- package/utils/constants.ios.d.ts +1 -0
- package/utils/constants.ios.js +3 -0
- package/utils/constants.ios.js.map +1 -1
- package/utils/index.d.ts +6 -0
- package/utils/layout-helper/index.android.d.ts +1 -0
- package/utils/layout-helper/index.android.js +9 -0
- package/utils/layout-helper/index.android.js.map +1 -1
- package/utils/layout-helper/index.d.ts +5 -0
- package/utils/layout-helper/index.ios.d.ts +1 -0
- package/utils/layout-helper/index.ios.js +4 -0
- package/utils/layout-helper/index.ios.js.map +1 -1
- package/utils/native-helper-for-android.d.ts +22 -0
- package/utils/native-helper-for-android.js +103 -0
- package/utils/native-helper-for-android.js.map +1 -1
- package/utils/native-helper.android.d.ts +9 -1
- package/utils/native-helper.android.js +5 -1
- package/utils/native-helper.android.js.map +1 -1
- package/utils/native-helper.d.ts +30 -0
- package/utils/native-helper.ios.js +20 -20
- package/utils/native-helper.ios.js.map +1 -1
- package/cli-hooks/postinstall.js +0 -2
- package/cli-hooks/preuninstall.js +0 -2
|
@@ -3,14 +3,32 @@ import { isEmbedded } from '../ui/embedding';
|
|
|
3
3
|
import { IOSHelper } from '../ui/core/view/view-helper';
|
|
4
4
|
import { getWindow } from '../utils/native-helper';
|
|
5
5
|
import { SDK_VERSION } from '../utils/constants';
|
|
6
|
-
import { ios as iosUtils } from '../utils/native-helper';
|
|
7
|
-
import { ApplicationCommon } from './application-common';
|
|
6
|
+
import { ios as iosUtils, dataSerialize } from '../utils/native-helper';
|
|
7
|
+
import { ApplicationCommon, initializeSdkVersionClass, SceneEvents } from './application-common';
|
|
8
8
|
import { Observable } from '../data/observable';
|
|
9
9
|
import { Trace } from '../trace';
|
|
10
10
|
import { AccessibilityServiceEnabledPropName, CommonA11YServiceEnabledObservable, SharedA11YObservable, a11yServiceClasses, a11yServiceDisabledClass, a11yServiceEnabledClass, fontScaleCategoryClasses, fontScaleExtraLargeCategoryClass, fontScaleExtraSmallCategoryClass, fontScaleMediumCategoryClass, getCurrentA11YServiceClass, getCurrentFontScaleCategory, getCurrentFontScaleClass, getFontScaleCssClasses, setCurrentA11YServiceClass, setCurrentFontScaleCategory, setCurrentFontScaleClass, setFontScaleCssClasses, FontScaleCategory, getClosestValidFontScale, VALID_FONT_SCALES, setFontScale, getFontScale, setInitFontScale, getFontScaleCategory, setInitAccessibilityCssHelper, notifyAccessibilityFocusState, AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait, isA11yEnabled, setA11yEnabled, enforceArray, } from '../accessibility/accessibility-common';
|
|
11
|
-
import {
|
|
11
|
+
import { CoreTypes } from '../core-types';
|
|
12
12
|
import { getiOSWindow, setA11yUpdatePropertiesCallback, setApplicationPropertiesCallback, setAppMainEntry, setiOSWindow, setRootView, setToggleApplicationEventListenersCallback } from './helpers-common';
|
|
13
|
-
var
|
|
13
|
+
var NotificationObserver = (function (_super) {
|
|
14
|
+
__extends(NotificationObserver, _super);
|
|
15
|
+
function NotificationObserver() {
|
|
16
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
17
|
+
}
|
|
18
|
+
NotificationObserver.initWithCallback = function (onReceiveCallback) {
|
|
19
|
+
var observer = _super.new.call(this);
|
|
20
|
+
observer._onReceiveCallback = onReceiveCallback;
|
|
21
|
+
return observer;
|
|
22
|
+
};
|
|
23
|
+
NotificationObserver.prototype.onReceive = function (notification) {
|
|
24
|
+
this._onReceiveCallback(notification);
|
|
25
|
+
};
|
|
26
|
+
NotificationObserver.ObjCExposedMethods = {
|
|
27
|
+
onReceive: { returns: interop.types.void, params: [NSNotification] },
|
|
28
|
+
};
|
|
29
|
+
return NotificationObserver;
|
|
30
|
+
}(NSObject));
|
|
31
|
+
var CADisplayLinkTarget = (function (_super) {
|
|
14
32
|
__extends(CADisplayLinkTarget, _super);
|
|
15
33
|
function CADisplayLinkTarget() {
|
|
16
34
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
@@ -40,7 +58,29 @@ var CADisplayLinkTarget = /** @class */ (function (_super) {
|
|
|
40
58
|
};
|
|
41
59
|
return CADisplayLinkTarget;
|
|
42
60
|
}(NSObject));
|
|
43
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Detect if the app supports scenes.
|
|
63
|
+
* When an app configures UIApplicationSceneManifest in Info.plist
|
|
64
|
+
* it will use scene lifecycle management.
|
|
65
|
+
*/
|
|
66
|
+
let sceneManifest;
|
|
67
|
+
function supportsScenes() {
|
|
68
|
+
if (SDK_VERSION < 13) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (typeof sceneManifest === 'undefined') {
|
|
72
|
+
// Check if scene manifest exists in Info.plist
|
|
73
|
+
sceneManifest = NSBundle.mainBundle.objectForInfoDictionaryKey('UIApplicationSceneManifest');
|
|
74
|
+
}
|
|
75
|
+
return !!sceneManifest;
|
|
76
|
+
}
|
|
77
|
+
function supportsMultipleScenes() {
|
|
78
|
+
if (SDK_VERSION < 13) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return UIApplication.sharedApplication?.supportsMultipleScenes;
|
|
82
|
+
}
|
|
83
|
+
var Responder = (function (_super) {
|
|
44
84
|
__extends(Responder, _super);
|
|
45
85
|
function Responder() {
|
|
46
86
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
@@ -50,7 +90,6 @@ var Responder = /** @class */ (function (_super) {
|
|
|
50
90
|
return Application.ios.window;
|
|
51
91
|
},
|
|
52
92
|
set: function (value) {
|
|
53
|
-
// NOOP
|
|
54
93
|
},
|
|
55
94
|
enumerable: true,
|
|
56
95
|
configurable: true
|
|
@@ -58,6 +97,95 @@ var Responder = /** @class */ (function (_super) {
|
|
|
58
97
|
Responder.ObjCProtocols = [UIApplicationDelegate];
|
|
59
98
|
return Responder;
|
|
60
99
|
}(UIResponder));
|
|
100
|
+
if (supportsScenes()) {
|
|
101
|
+
/**
|
|
102
|
+
* This method is called when a new scene session is being created.
|
|
103
|
+
* Important: When this method is implemented, the app assumes scene-based lifecycle management.
|
|
104
|
+
* Detected by the Info.plist existence 'UIApplicationSceneManifest'.
|
|
105
|
+
* If this method is implemented when there is no manifest defined,
|
|
106
|
+
* the app will boot to a white screen.
|
|
107
|
+
*/
|
|
108
|
+
Responder.prototype.applicationConfigurationForConnectingSceneSessionOptions = function (application, connectingSceneSession, options) {
|
|
109
|
+
const config = UISceneConfiguration.configurationWithNameSessionRole('Default Configuration', connectingSceneSession.role);
|
|
110
|
+
config.sceneClass = UIWindowScene;
|
|
111
|
+
config.delegateClass = SceneDelegate;
|
|
112
|
+
return config;
|
|
113
|
+
};
|
|
114
|
+
// scene session destruction handling
|
|
115
|
+
Responder.prototype.applicationDidDiscardSceneSessions = function (application, sceneSessions) {
|
|
116
|
+
// Note: we could emit an event here if needed
|
|
117
|
+
// console.log('Scene sessions discarded:', sceneSessions.count);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
var SceneDelegate = (function (_super) {
|
|
121
|
+
__extends(SceneDelegate, _super);
|
|
122
|
+
function SceneDelegate() {
|
|
123
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
124
|
+
}
|
|
125
|
+
Object.defineProperty(SceneDelegate.prototype, "window", {
|
|
126
|
+
get: function () {
|
|
127
|
+
return this._window;
|
|
128
|
+
},
|
|
129
|
+
set: function (value) {
|
|
130
|
+
this._window = value;
|
|
131
|
+
},
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true
|
|
134
|
+
});
|
|
135
|
+
SceneDelegate.prototype.sceneWillConnectToSessionOptions = function (scene, session, connectionOptions) {
|
|
136
|
+
if (Trace.isEnabled()) {
|
|
137
|
+
Trace.write("SceneDelegate.sceneWillConnectToSessionOptions called with role: ".concat(session.role), Trace.categories.NativeLifecycle);
|
|
138
|
+
}
|
|
139
|
+
if (!(scene instanceof UIWindowScene)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this._scene = scene;
|
|
143
|
+
this._window = UIWindow.alloc().initWithWindowScene(scene);
|
|
144
|
+
Application.ios._setWindowForScene(this._window, scene);
|
|
145
|
+
Application.ios._setupWindowForScene(this._window, scene);
|
|
146
|
+
Application.ios.notify({
|
|
147
|
+
eventName: SceneEvents.sceneWillConnect,
|
|
148
|
+
object: Application.ios,
|
|
149
|
+
scene: scene,
|
|
150
|
+
window: this._window,
|
|
151
|
+
connectionOptions: connectionOptions,
|
|
152
|
+
});
|
|
153
|
+
if (scene === Application.ios.getPrimaryScene()) {
|
|
154
|
+
this._window.makeKeyAndVisible();
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
Application.ios.notify({
|
|
158
|
+
eventName: SceneEvents.sceneContentSetup,
|
|
159
|
+
object: Application.ios,
|
|
160
|
+
scene: scene,
|
|
161
|
+
window: this._window,
|
|
162
|
+
connectionOptions: connectionOptions,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (!Application.ios.getPrimaryScene()) {
|
|
166
|
+
Application.ios._notifySceneAppStarted();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
SceneDelegate.prototype.sceneDidBecomeActive = function (scene) {
|
|
170
|
+
};
|
|
171
|
+
SceneDelegate.prototype.sceneWillResignActive = function (scene) {
|
|
172
|
+
Application.ios.notify({
|
|
173
|
+
eventName: SceneEvents.sceneWillResignActive,
|
|
174
|
+
object: Application.ios,
|
|
175
|
+
scene: scene,
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
SceneDelegate.prototype.sceneWillEnterForeground = function (scene) {
|
|
179
|
+
};
|
|
180
|
+
SceneDelegate.prototype.sceneDidEnterBackground = function (scene) {
|
|
181
|
+
};
|
|
182
|
+
SceneDelegate.prototype.sceneDidDisconnect = function (scene) {
|
|
183
|
+
};
|
|
184
|
+
SceneDelegate.ObjCProtocols = [UIWindowSceneDelegate];
|
|
185
|
+
return SceneDelegate;
|
|
186
|
+
}(UIResponder));
|
|
187
|
+
// ensure available globally
|
|
188
|
+
global.SceneDelegate = SceneDelegate;
|
|
61
189
|
export class iOSApplication extends ApplicationCommon {
|
|
62
190
|
/**
|
|
63
191
|
* @internal - should not be constructed by the user.
|
|
@@ -65,6 +193,10 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
65
193
|
constructor() {
|
|
66
194
|
super();
|
|
67
195
|
this._delegateHandlers = new Map();
|
|
196
|
+
this._windowSceneMap = new Map();
|
|
197
|
+
this._primaryScene = null;
|
|
198
|
+
this._openedScenesById = new Map();
|
|
199
|
+
this._notificationObservers = [];
|
|
68
200
|
this.displayedOnce = false;
|
|
69
201
|
this.addNotificationObserver(UIApplicationDidFinishLaunchingNotification, this.didFinishLaunchingWithOptions.bind(this));
|
|
70
202
|
this.addNotificationObserver(UIApplicationDidBecomeActiveNotification, this.didBecomeActive.bind(this));
|
|
@@ -72,6 +204,14 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
72
204
|
this.addNotificationObserver(UIApplicationWillTerminateNotification, this.willTerminate.bind(this));
|
|
73
205
|
this.addNotificationObserver(UIApplicationDidReceiveMemoryWarningNotification, this.didReceiveMemoryWarning.bind(this));
|
|
74
206
|
this.addNotificationObserver(UIApplicationDidChangeStatusBarOrientationNotification, this.didChangeStatusBarOrientation.bind(this));
|
|
207
|
+
// Add scene lifecycle notification observers only if scenes are supported
|
|
208
|
+
if (this.supportsScenes()) {
|
|
209
|
+
this.addNotificationObserver('UISceneWillConnectNotification', this.sceneWillConnect.bind(this));
|
|
210
|
+
this.addNotificationObserver('UISceneDidActivateNotification', this.sceneDidActivate.bind(this));
|
|
211
|
+
this.addNotificationObserver('UISceneWillEnterForegroundNotification', this.sceneWillEnterForeground.bind(this));
|
|
212
|
+
this.addNotificationObserver('UISceneDidEnterBackgroundNotification', this.sceneDidEnterBackground.bind(this));
|
|
213
|
+
this.addNotificationObserver('UISceneDidDisconnectNotification', this.sceneDidDisconnect.bind(this));
|
|
214
|
+
}
|
|
75
215
|
}
|
|
76
216
|
getRootView() {
|
|
77
217
|
return this._rootView;
|
|
@@ -118,6 +258,11 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
118
258
|
const newSystemAppearance = this.getSystemAppearanceValue(userInterfaceStyle);
|
|
119
259
|
this.setSystemAppearance(newSystemAppearance);
|
|
120
260
|
});
|
|
261
|
+
rootView.on(IOSHelper.traitCollectionLayoutDirectionChangedEvent, () => {
|
|
262
|
+
const layoutDirection = controller.traitCollection.layoutDirection;
|
|
263
|
+
const newLayoutDirection = this.getLayoutDirectionValue(layoutDirection);
|
|
264
|
+
this.setLayoutDirection(newLayoutDirection);
|
|
265
|
+
});
|
|
121
266
|
if (embedderDelegate) {
|
|
122
267
|
this.setViewControllerView(rootView);
|
|
123
268
|
embedderDelegate.presentNativeScriptApp(controller);
|
|
@@ -246,10 +391,17 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
246
391
|
return this.nativeApp;
|
|
247
392
|
}
|
|
248
393
|
addNotificationObserver(notificationName, onReceiveCallback) {
|
|
249
|
-
|
|
394
|
+
const observer = NotificationObserver.initWithCallback(onReceiveCallback);
|
|
395
|
+
NSNotificationCenter.defaultCenter.addObserverSelectorNameObject(observer, 'onReceive', notificationName, null);
|
|
396
|
+
this._notificationObservers.push(observer);
|
|
397
|
+
return observer;
|
|
250
398
|
}
|
|
251
399
|
removeNotificationObserver(observer /* NotificationObserver */, notificationName) {
|
|
252
|
-
|
|
400
|
+
const index = this._notificationObservers.indexOf(observer);
|
|
401
|
+
if (index >= 0) {
|
|
402
|
+
this._notificationObservers.splice(index, 1);
|
|
403
|
+
NSNotificationCenter.defaultCenter.removeObserverNameObject(observer, notificationName, null);
|
|
404
|
+
}
|
|
253
405
|
}
|
|
254
406
|
getSystemAppearance() {
|
|
255
407
|
// userInterfaceStyle is available on UITraitCollection since iOS 12.
|
|
@@ -268,6 +420,21 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
268
420
|
return 'light';
|
|
269
421
|
}
|
|
270
422
|
}
|
|
423
|
+
getLayoutDirection() {
|
|
424
|
+
if (!this.rootController) {
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
const layoutDirection = this.rootController.traitCollection.layoutDirection;
|
|
428
|
+
return this.getLayoutDirectionValue(layoutDirection);
|
|
429
|
+
}
|
|
430
|
+
getLayoutDirectionValue(layoutDirection) {
|
|
431
|
+
switch (layoutDirection) {
|
|
432
|
+
case 0 /* UITraitEnvironmentLayoutDirection.LeftToRight */:
|
|
433
|
+
return CoreTypes.LayoutDirection.ltr;
|
|
434
|
+
case 1 /* UITraitEnvironmentLayoutDirection.RightToLeft */:
|
|
435
|
+
return CoreTypes.LayoutDirection.rtl;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
271
438
|
getOrientation() {
|
|
272
439
|
let statusBarOrientation;
|
|
273
440
|
if (__VISIONOS__) {
|
|
@@ -303,6 +470,10 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
303
470
|
setiOSWindow(this.window);
|
|
304
471
|
}
|
|
305
472
|
}
|
|
473
|
+
// Public method for scene-based app startup
|
|
474
|
+
_notifySceneAppStarted() {
|
|
475
|
+
this.notifyAppStarted();
|
|
476
|
+
}
|
|
306
477
|
_onLivesync(context) {
|
|
307
478
|
// Handle application root module
|
|
308
479
|
const isAppRootModuleChanged = context && context.path && context.path.includes(this.getMainEntry().moduleName) && context.type !== 'style';
|
|
@@ -340,20 +511,46 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
340
511
|
const newSystemAppearance = this.getSystemAppearanceValue(userInterfaceStyle);
|
|
341
512
|
this.setSystemAppearance(newSystemAppearance);
|
|
342
513
|
});
|
|
514
|
+
rootView.on(IOSHelper.traitCollectionLayoutDirectionChangedEvent, () => {
|
|
515
|
+
const layoutDirection = controller.traitCollection.layoutDirection;
|
|
516
|
+
const newLayoutDirection = this.getLayoutDirectionValue(layoutDirection);
|
|
517
|
+
this.setLayoutDirection(newLayoutDirection);
|
|
518
|
+
});
|
|
343
519
|
}
|
|
344
520
|
// Observers
|
|
345
521
|
didFinishLaunchingWithOptions(notification) {
|
|
522
|
+
if (__DEV__) {
|
|
523
|
+
/**
|
|
524
|
+
* v9+ runtime crash handling
|
|
525
|
+
* When crash occurs during boot, we let runtime take over
|
|
526
|
+
*/
|
|
527
|
+
if (notification.userInfo) {
|
|
528
|
+
const isBootCrash = notification.userInfo.objectForKey('NativeScriptBootCrash');
|
|
529
|
+
if (isBootCrash) {
|
|
530
|
+
// fatal crash will show in console without app exiting
|
|
531
|
+
// allowing hot reload fixes to continue
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
346
536
|
this.setMaxRefreshRate();
|
|
347
|
-
//
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
//
|
|
351
|
-
setiOSWindow(
|
|
537
|
+
// Only set up window if NOT using scene-based lifecycle
|
|
538
|
+
if (!this.supportsScenes()) {
|
|
539
|
+
// Traditional single-window app setup
|
|
540
|
+
// ensures window is assigned to proper window scene
|
|
541
|
+
setiOSWindow(this.window);
|
|
542
|
+
if (!getiOSWindow()) {
|
|
543
|
+
// if still no window, create one
|
|
544
|
+
setiOSWindow(UIWindow.alloc().initWithFrame(UIScreen.mainScreen.bounds));
|
|
545
|
+
}
|
|
546
|
+
if (!__VISIONOS__) {
|
|
547
|
+
this.window.backgroundColor = SDK_VERSION <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
|
|
548
|
+
}
|
|
549
|
+
this.notifyAppStarted(notification);
|
|
352
550
|
}
|
|
353
|
-
|
|
354
|
-
|
|
551
|
+
else {
|
|
552
|
+
// Scene-based app - window creation will happen in scene delegate
|
|
355
553
|
}
|
|
356
|
-
this.notifyAppStarted(notification);
|
|
357
554
|
}
|
|
358
555
|
didBecomeActive(notification) {
|
|
359
556
|
const additionalData = {
|
|
@@ -400,6 +597,431 @@ export class iOSApplication extends ApplicationCommon {
|
|
|
400
597
|
const newOrientation = this.getOrientationValue(statusBarOrientation);
|
|
401
598
|
this.setOrientation(newOrientation);
|
|
402
599
|
}
|
|
600
|
+
// Scene lifecycle notification handlers
|
|
601
|
+
sceneWillConnect(notification) {
|
|
602
|
+
const scene = notification.object;
|
|
603
|
+
if (!scene || !(scene instanceof UIWindowScene)) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
// Store as primary scene if it's the first one
|
|
607
|
+
if (!this._primaryScene) {
|
|
608
|
+
this._primaryScene = scene;
|
|
609
|
+
}
|
|
610
|
+
this.notify({
|
|
611
|
+
eventName: SceneEvents.sceneWillConnect,
|
|
612
|
+
object: this,
|
|
613
|
+
scene: scene,
|
|
614
|
+
userInfo: notification.userInfo,
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
sceneDidActivate(notification) {
|
|
618
|
+
const scene = notification.object;
|
|
619
|
+
this.notify({
|
|
620
|
+
eventName: SceneEvents.sceneDidActivate,
|
|
621
|
+
object: this,
|
|
622
|
+
scene: scene,
|
|
623
|
+
});
|
|
624
|
+
// If this is the primary scene, trigger traditional app lifecycle
|
|
625
|
+
if (scene === this._primaryScene) {
|
|
626
|
+
const additionalData = {
|
|
627
|
+
ios: UIApplication.sharedApplication,
|
|
628
|
+
scene: scene,
|
|
629
|
+
};
|
|
630
|
+
this.setInBackground(false, additionalData);
|
|
631
|
+
this.setSuspended(false, additionalData);
|
|
632
|
+
if (this._rootView && !this._rootView.isLoaded) {
|
|
633
|
+
this._rootView.callLoaded();
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
sceneWillEnterForeground(notification) {
|
|
638
|
+
const scene = notification.object;
|
|
639
|
+
this.notify({
|
|
640
|
+
eventName: SceneEvents.sceneWillEnterForeground,
|
|
641
|
+
object: this,
|
|
642
|
+
scene: scene,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
sceneDidEnterBackground(notification) {
|
|
646
|
+
const scene = notification.object;
|
|
647
|
+
this.notify({
|
|
648
|
+
eventName: SceneEvents.sceneDidEnterBackground,
|
|
649
|
+
object: this,
|
|
650
|
+
scene: scene,
|
|
651
|
+
});
|
|
652
|
+
// If this is the primary scene, trigger traditional app lifecycle
|
|
653
|
+
if (scene === this._primaryScene) {
|
|
654
|
+
const additionalData = {
|
|
655
|
+
ios: UIApplication.sharedApplication,
|
|
656
|
+
scene: scene,
|
|
657
|
+
};
|
|
658
|
+
this.setInBackground(true, additionalData);
|
|
659
|
+
this.setSuspended(true, additionalData);
|
|
660
|
+
if (this._rootView && this._rootView.isLoaded) {
|
|
661
|
+
this._rootView.callUnloaded();
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
sceneDidDisconnect(notification) {
|
|
666
|
+
const scene = notification.object;
|
|
667
|
+
this._removeWindowForScene(scene);
|
|
668
|
+
// If primary scene disconnected, clear it
|
|
669
|
+
if (scene === this._primaryScene) {
|
|
670
|
+
this._primaryScene = null;
|
|
671
|
+
}
|
|
672
|
+
if (this._primaryScene) {
|
|
673
|
+
if (SDK_VERSION >= 17) {
|
|
674
|
+
const request = UISceneSessionActivationRequest.requestWithSession(this._primaryScene.session);
|
|
675
|
+
UIApplication.sharedApplication.activateSceneSessionForRequestErrorHandler(request, (err) => {
|
|
676
|
+
if (err) {
|
|
677
|
+
console.log('Failed to activate primary scene:', err.localizedDescription);
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
UIApplication.sharedApplication.requestSceneSessionActivationUserActivityOptionsErrorHandler(this._primaryScene.session, null, null, (err) => {
|
|
683
|
+
if (err) {
|
|
684
|
+
console.log('Failed to activate primary scene (legacy):', err.localizedDescription);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
this.notify({
|
|
690
|
+
eventName: SceneEvents.sceneDidDisconnect,
|
|
691
|
+
object: this,
|
|
692
|
+
scene: scene,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
// Scene management helper methods
|
|
696
|
+
_setWindowForScene(window, scene) {
|
|
697
|
+
this._windowSceneMap.set(scene, window);
|
|
698
|
+
}
|
|
699
|
+
_removeWindowForScene(scene) {
|
|
700
|
+
this._windowSceneMap.delete(scene);
|
|
701
|
+
// also untrack opened scene id
|
|
702
|
+
try {
|
|
703
|
+
const s = scene;
|
|
704
|
+
if (s && s.session) {
|
|
705
|
+
const id = this._getSceneId(s);
|
|
706
|
+
this._openedScenesById.delete(id);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
catch { }
|
|
710
|
+
}
|
|
711
|
+
_getWindowForScene(scene) {
|
|
712
|
+
return this._windowSceneMap.get(scene);
|
|
713
|
+
}
|
|
714
|
+
_setupWindowForScene(window, scene) {
|
|
715
|
+
if (!window) {
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
// track opened scene
|
|
719
|
+
try {
|
|
720
|
+
const id = this._getSceneId(scene);
|
|
721
|
+
this._openedScenesById.set(id, scene);
|
|
722
|
+
}
|
|
723
|
+
catch { }
|
|
724
|
+
// Set up window background
|
|
725
|
+
if (!__VISIONOS__) {
|
|
726
|
+
window.backgroundColor = SDK_VERSION <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
|
|
727
|
+
}
|
|
728
|
+
// If this is the primary scene, set up the main application content
|
|
729
|
+
if (scene === this._primaryScene || !this._primaryScene) {
|
|
730
|
+
this._primaryScene = scene;
|
|
731
|
+
if (!getiOSWindow()) {
|
|
732
|
+
setiOSWindow(window);
|
|
733
|
+
}
|
|
734
|
+
// Set up the window content for the primary scene
|
|
735
|
+
this.setWindowContent();
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
get sceneDelegate() {
|
|
739
|
+
if (!this._sceneDelegate) {
|
|
740
|
+
this._sceneDelegate = SceneDelegate.new();
|
|
741
|
+
}
|
|
742
|
+
return this._sceneDelegate;
|
|
743
|
+
}
|
|
744
|
+
set sceneDelegate(value) {
|
|
745
|
+
this._sceneDelegate = value;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Multi-window support
|
|
749
|
+
*/
|
|
750
|
+
/**
|
|
751
|
+
* Opens a new window with the specified data.
|
|
752
|
+
* @param data The data to pass to the new window.
|
|
753
|
+
*/
|
|
754
|
+
openWindow(data) {
|
|
755
|
+
if (!supportsMultipleScenes()) {
|
|
756
|
+
console.log('Cannot create a new scene - not supported on this device.');
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
try {
|
|
760
|
+
const app = UIApplication.sharedApplication;
|
|
761
|
+
// iOS 17+
|
|
762
|
+
if (SDK_VERSION >= 17) {
|
|
763
|
+
// Create a new scene activation request with proper role
|
|
764
|
+
let request;
|
|
765
|
+
try {
|
|
766
|
+
// Use the correct factory method to create request with role
|
|
767
|
+
// Based on the type definitions, this is the proper way
|
|
768
|
+
request = UISceneSessionActivationRequest.requestWithRole(UIWindowSceneSessionRoleApplication);
|
|
769
|
+
// Note: may be useful to allow user defined activity type through optional string typed data in future
|
|
770
|
+
const activity = NSUserActivity.alloc().initWithActivityType(`${NSBundle.mainBundle.bundleIdentifier}.scene`);
|
|
771
|
+
activity.userInfo = dataSerialize(data);
|
|
772
|
+
request.userActivity = activity;
|
|
773
|
+
// Set proper options with requesting scene
|
|
774
|
+
const options = UISceneActivationRequestOptions.new();
|
|
775
|
+
// Note: explore secondary windows spawning other windows
|
|
776
|
+
// and if this context needs to change in those cases
|
|
777
|
+
const mainWindow = Application.ios.getPrimaryWindow();
|
|
778
|
+
options.requestingScene = mainWindow?.windowScene;
|
|
779
|
+
/**
|
|
780
|
+
* Note: This does not work in testing but worth exploring further sometime
|
|
781
|
+
* regarding the size/dimensions of opened secondary windows.
|
|
782
|
+
* The initial size is ultimately determined by the system
|
|
783
|
+
* based on available space and user context.
|
|
784
|
+
*/
|
|
785
|
+
// Get the size restrictions from the window scene
|
|
786
|
+
// const sizeRestrictions = (options.requestingScene as UIWindowScene).sizeRestrictions;
|
|
787
|
+
// // Set your minimum and maximum dimensions
|
|
788
|
+
// sizeRestrictions.minimumSize = CGSizeMake(320, 400);
|
|
789
|
+
// sizeRestrictions.maximumSize = CGSizeMake(600, 800);
|
|
790
|
+
request.options = options;
|
|
791
|
+
}
|
|
792
|
+
catch (roleError) {
|
|
793
|
+
console.log('Error creating request:', roleError);
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
app.activateSceneSessionForRequestErrorHandler(request, (error) => {
|
|
797
|
+
if (error) {
|
|
798
|
+
console.log('Error creating new scene (iOS 17+):', error);
|
|
799
|
+
// Log additional debugging info
|
|
800
|
+
if (error.userInfo) {
|
|
801
|
+
console.error(`Error userInfo: ${error.userInfo.description}`);
|
|
802
|
+
}
|
|
803
|
+
// Handle specific error types
|
|
804
|
+
if (error.localizedDescription.includes('role') && error.localizedDescription.includes('nil')) {
|
|
805
|
+
this.createSceneWithLegacyAPI(data);
|
|
806
|
+
}
|
|
807
|
+
else if (error.domain === 'FBSWorkspaceErrorDomain' && error.code === 2) {
|
|
808
|
+
this.createSceneWithLegacyAPI(data);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
// iOS 13-16 - Use the legacy requestSceneSessionActivationUserActivityOptionsErrorHandler method
|
|
814
|
+
else if (SDK_VERSION >= 13 && SDK_VERSION < 17) {
|
|
815
|
+
app.requestSceneSessionActivationUserActivityOptionsErrorHandler(null, // session
|
|
816
|
+
null, // userActivity
|
|
817
|
+
null, // options
|
|
818
|
+
(error) => {
|
|
819
|
+
if (error) {
|
|
820
|
+
console.log('Error creating new scene (legacy):', error);
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
// Fallback for older iOS versions or unsupported configurations
|
|
825
|
+
else {
|
|
826
|
+
console.log('Neither new nor legacy scene activation methods are available');
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
catch (error) {
|
|
830
|
+
console.error('Error requesting new scene:', error);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Closes a secondary window/scene.
|
|
835
|
+
* Usage examples:
|
|
836
|
+
* - Application.ios.closeWindow() // best-effort close of a non-primary scene
|
|
837
|
+
* - Application.ios.closeWindow(button) // from a tap handler within the scene
|
|
838
|
+
* - Application.ios.closeWindow(window)
|
|
839
|
+
* - Application.ios.closeWindow(scene)
|
|
840
|
+
* - Application.ios.closeWindow('scene-id')
|
|
841
|
+
*/
|
|
842
|
+
closeWindow(target) {
|
|
843
|
+
if (!__APPLE__) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
try {
|
|
847
|
+
const scene = this._resolveScene(target);
|
|
848
|
+
if (!scene) {
|
|
849
|
+
console.log('closeWindow: No scene resolved for target');
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
// Don't allow closing the primary scene
|
|
853
|
+
if (scene === this._primaryScene) {
|
|
854
|
+
console.log('closeWindow: Refusing to close the primary scene');
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
const session = scene.session;
|
|
858
|
+
if (!session) {
|
|
859
|
+
console.log('closeWindow: Scene has no session to destroy');
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
const app = UIApplication.sharedApplication;
|
|
863
|
+
if (app.requestSceneSessionDestructionOptionsErrorHandler) {
|
|
864
|
+
app.requestSceneSessionDestructionOptionsErrorHandler(session, null, (error) => {
|
|
865
|
+
if (error) {
|
|
866
|
+
console.log('closeWindow: destruction error', error);
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
// clean up tracked id
|
|
870
|
+
const id = this._getSceneId(scene);
|
|
871
|
+
this._openedScenesById.delete(id);
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
console.info('closeWindow: Scene destruction API not available on this iOS version');
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
catch (err) {
|
|
880
|
+
console.log('closeWindow: Unexpected error', err);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
getAllWindows() {
|
|
884
|
+
return Array.from(this._windowSceneMap.values());
|
|
885
|
+
}
|
|
886
|
+
getAllScenes() {
|
|
887
|
+
return Array.from(this._windowSceneMap.keys());
|
|
888
|
+
}
|
|
889
|
+
getWindowScenes() {
|
|
890
|
+
return this.getAllScenes().filter((scene) => scene instanceof UIWindowScene);
|
|
891
|
+
}
|
|
892
|
+
getPrimaryWindow() {
|
|
893
|
+
if (this._primaryScene) {
|
|
894
|
+
return this._getWindowForScene(this._primaryScene) || getiOSWindow();
|
|
895
|
+
}
|
|
896
|
+
return getiOSWindow();
|
|
897
|
+
}
|
|
898
|
+
getPrimaryScene() {
|
|
899
|
+
return this._primaryScene;
|
|
900
|
+
}
|
|
901
|
+
// Scene lifecycle management
|
|
902
|
+
supportsScenes() {
|
|
903
|
+
return supportsScenes();
|
|
904
|
+
}
|
|
905
|
+
supportsMultipleScenes() {
|
|
906
|
+
return supportsMultipleScenes();
|
|
907
|
+
}
|
|
908
|
+
isUsingSceneLifecycle() {
|
|
909
|
+
return this.supportsScenes() && this._windowSceneMap.size > 0;
|
|
910
|
+
}
|
|
911
|
+
// Call this to set up scene-based configuration
|
|
912
|
+
configureForScenes() {
|
|
913
|
+
if (!this.supportsScenes()) {
|
|
914
|
+
console.warn('Scene-based lifecycle is only supported on iOS 13+ iPad or visionOS with multi-scene enabled apps.');
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
// Additional scene configuration can be added here
|
|
918
|
+
// For now, the notification observers are already set up in the constructor
|
|
919
|
+
}
|
|
920
|
+
// Stable scene id for lookups
|
|
921
|
+
_getSceneId(scene) {
|
|
922
|
+
try {
|
|
923
|
+
if (!scene) {
|
|
924
|
+
return 'Unknown';
|
|
925
|
+
}
|
|
926
|
+
// Prefer session persistentIdentifier when available (stable across lifetime)
|
|
927
|
+
const session = scene.session;
|
|
928
|
+
const persistentId = session && session.persistentIdentifier;
|
|
929
|
+
if (persistentId) {
|
|
930
|
+
return `${persistentId}`;
|
|
931
|
+
}
|
|
932
|
+
// Fallbacks
|
|
933
|
+
if (scene.hash != null) {
|
|
934
|
+
return `${scene.hash}`;
|
|
935
|
+
}
|
|
936
|
+
const desc = scene.description;
|
|
937
|
+
if (desc) {
|
|
938
|
+
return `${desc}`;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
catch (err) {
|
|
942
|
+
// ignore
|
|
943
|
+
}
|
|
944
|
+
return 'Unknown';
|
|
945
|
+
}
|
|
946
|
+
// Resolve a UIWindowScene from various input types
|
|
947
|
+
_resolveScene(target) {
|
|
948
|
+
if (!__APPLE__) {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
951
|
+
if (!target) {
|
|
952
|
+
// Try to pick a non-primary foreground active scene, else last known scene
|
|
953
|
+
const scenes = this.getWindowScenes?.() || [];
|
|
954
|
+
const nonPrimary = scenes.filter((s) => s !== this._primaryScene);
|
|
955
|
+
return nonPrimary[0] || scenes[0] || null;
|
|
956
|
+
}
|
|
957
|
+
// If a View was passed, derive its window.scene
|
|
958
|
+
if (target && typeof target === 'object') {
|
|
959
|
+
// UIWindowScene
|
|
960
|
+
if (target.session && target.activationState !== undefined) {
|
|
961
|
+
return target;
|
|
962
|
+
}
|
|
963
|
+
// UIWindow
|
|
964
|
+
if (target.windowScene) {
|
|
965
|
+
return target.windowScene;
|
|
966
|
+
}
|
|
967
|
+
// NativeScript View
|
|
968
|
+
if (target?.nativeViewProtected) {
|
|
969
|
+
const uiView = target.nativeViewProtected;
|
|
970
|
+
const win = uiView?.window;
|
|
971
|
+
return win?.windowScene || null;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
// String id lookup
|
|
975
|
+
if (typeof target === 'string') {
|
|
976
|
+
if (this._openedScenesById.has(target)) {
|
|
977
|
+
return this._openedScenesById.get(target);
|
|
978
|
+
}
|
|
979
|
+
// Try matching by persistentIdentifier or hash among known scenes
|
|
980
|
+
const scenes = this.getWindowScenes?.() || [];
|
|
981
|
+
for (const s of scenes) {
|
|
982
|
+
const sid = this._getSceneId(s);
|
|
983
|
+
if (sid === target) {
|
|
984
|
+
return s;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
createSceneWithLegacyAPI(data) {
|
|
991
|
+
const windowScene = this.window?.windowScene;
|
|
992
|
+
if (!windowScene) {
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
// Create user activity for the new scene
|
|
996
|
+
const userActivity = NSUserActivity.alloc().initWithActivityType(`${NSBundle.mainBundle.bundleIdentifier}.scene`);
|
|
997
|
+
userActivity.userInfo = dataSerialize(data);
|
|
998
|
+
// Use the legacy API
|
|
999
|
+
const options = UISceneActivationRequestOptions.new();
|
|
1000
|
+
options.requestingScene = windowScene;
|
|
1001
|
+
UIApplication.sharedApplication.requestSceneSessionActivationUserActivityOptionsErrorHandler(null, // session - null for new scene
|
|
1002
|
+
userActivity, options, (error) => {
|
|
1003
|
+
if (error) {
|
|
1004
|
+
console.error(`Legacy scene API failed: ${error.localizedDescription}`);
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Creates a simple view controller with a NativeScript view for a scene window.
|
|
1010
|
+
* @param window The UIWindow to set content for
|
|
1011
|
+
* @param view The NativeScript View to set as root content
|
|
1012
|
+
*/
|
|
1013
|
+
setWindowRootView(window, view) {
|
|
1014
|
+
if (!window || !view) {
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
if (view.ios) {
|
|
1018
|
+
window.rootViewController = view.viewController;
|
|
1019
|
+
window.makeKeyAndVisible();
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
console.warn('View does not have a native iOS implementation');
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
403
1025
|
get ios() {
|
|
404
1026
|
// ensures Application.ios is defined when running on iOS
|
|
405
1027
|
return this;
|
|
@@ -758,6 +1380,8 @@ export function ensureClasses() {
|
|
|
758
1380
|
}
|
|
759
1381
|
setFontScaleCssClasses(new Map(VALID_FONT_SCALES.map((fs) => [fs, `a11y-fontscale-${Number(fs * 100).toFixed(0)}`])));
|
|
760
1382
|
accessibilityServiceObservable = new AccessibilityServiceEnabledObservable();
|
|
1383
|
+
// Initialize SDK version CSS class once
|
|
1384
|
+
initializeSdkVersionClass(Application.getRootView());
|
|
761
1385
|
}
|
|
762
1386
|
export function updateCurrentHelperClasses(applyRootCssClass) {
|
|
763
1387
|
const fontScale = getFontScale();
|
|
@@ -827,6 +1451,8 @@ function applyFontScaleToRootViews() {
|
|
|
827
1451
|
}
|
|
828
1452
|
export function initAccessibilityCssHelper() {
|
|
829
1453
|
ensureClasses();
|
|
1454
|
+
updateCurrentHelperClasses(applyRootCssClass);
|
|
1455
|
+
applyFontScaleToRootViews();
|
|
830
1456
|
Application.on(Application.fontScaleChangedEvent, () => {
|
|
831
1457
|
updateCurrentHelperClasses(applyRootCssClass);
|
|
832
1458
|
applyFontScaleToRootViews();
|