UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

1,924 lines 83.2 kB
import { profile } from '../profiling';
import { isEmbedded } from '../ui/embedding';
import { IOSHelper } from '../ui/core/view/view-helper';
import { getWindow } from '../utils/native-helper';
import { SDK_VERSION } from '../utils/constants';
import { ios as iosUtils, dataSerialize, dataDeserialize } from '../utils/native-helper';
import { ApplicationCommon } from './application-common';
import { deliverShortcutItem, forwardContinueUserActivity, forwardOpenURLContexts, oneShotCompletion } from './scene-delegate-bridge';
import { Observable } from '../data/observable';
import { Trace } from '../trace';
import { IOSNativeWindow } from '../native-window/native-window.ios';
import { NativeWindow } from '../native-window/native-window-common';
import { NativeWindowEvents } from '../native-window/native-window-interfaces';
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';
import { CoreTypes } from '../core-types';
import { getiOSWindow, setA11yUpdatePropertiesCallback, setApplicationPropertiesCallback, setAppMainEntry, setiOSWindow, setRootView, setToggleApplicationEventListenersCallback } from './helpers-common';
var NotificationObserver = (function (_super) {
    __extends(NotificationObserver, _super);
    function NotificationObserver() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    NotificationObserver.initWithCallback = function (onReceiveCallback) {
        var observer = _super.new.call(this);
        observer._onReceiveCallback = onReceiveCallback;
        return observer;
    };
    NotificationObserver.prototype.onReceive = function (notification) {
        this._onReceiveCallback(notification);
    };
    NotificationObserver.ObjCExposedMethods = {
        onReceive: { returns: interop.types.void, params: [NSNotification] },
    };
    return NotificationObserver;
}(NSObject));
var CADisplayLinkTarget = (function (_super) {
    __extends(CADisplayLinkTarget, _super);
    function CADisplayLinkTarget() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    CADisplayLinkTarget.initWithOwner = function (owner) {
        var target = CADisplayLinkTarget.new();
        target._owner = owner;
        return target;
    };
    CADisplayLinkTarget.prototype.onDisplayed = function (link) {
        var _a;
        link.invalidate();
        var owner = this._owner.deref();
        if (!owner) {
            return;
        }
        owner.displayedOnce = true;
        owner.notify({
            eventName: owner.displayedEvent,
            object: owner,
            ios: UIApplication.sharedApplication,
        });
        (_a = owner.primaryWindow) === null || _a === void 0 ? void 0 : _a._notifyEvent(NativeWindowEvents.displayed);
        owner.displayedLinkTarget = null;
        owner.displayedLink = null;
    };
    CADisplayLinkTarget.ObjCExposedMethods = {
        onDisplayed: { returns: interop.types.void, params: [CADisplayLink] },
    };
    return CADisplayLinkTarget;
}(NSObject));
/**
 * Detect if the app supports scenes.
 * When an app configures UIApplicationSceneManifest in Info.plist
 * it will use scene lifecycle management.
 */
let sceneManifest;
function supportsScenes() {
    if (SDK_VERSION < 13) {
        return false;
    }
    if (typeof sceneManifest === 'undefined') {
        // Check if scene manifest exists in Info.plist
        sceneManifest = NSBundle.mainBundle.objectForInfoDictionaryKey('UIApplicationSceneManifest');
    }
    return !!sceneManifest;
}
function supportsMultipleScenes() {
    if (SDK_VERSION < 13) {
        return false;
    }
    return UIApplication.sharedApplication?.supportsMultipleScenes;
}
/**
 * Number of times the JS runtime has been soft-rebooted in this process via
 * NativeScriptRuntime.reloadApplication / restartWithConfig. 0 on first boot.
 * Provided as a global by the iOS runtime (v9+); older runtimes report 0.
 */
function getRuntimeReloadCount() {
    const runtime = globalThis.NativeScriptRuntime;
    return runtime && typeof runtime.reloadCount === 'number' ? runtime.reloadCount : 0;
}
var Responder = (function (_super) {
    __extends(Responder, _super);
    function Responder() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Object.defineProperty(Responder.prototype, "window", {
        get: function () {
            return Application.ios.window;
        },
        set: function (value) {
        },
        enumerable: true,
        configurable: true
    });
    Responder.ObjCProtocols = [UIApplicationDelegate];
    return Responder;
}(UIResponder));
const delegateWindowKey = Symbol('nativescript.delegateWindow');
/**
 * Installs NativeScript's default `UIApplicationDelegate` members on the class that will
 * be handed to `UIApplicationMain`, so scenes keep working with a custom delegate.
 *
 * Each member is installed only when the class does not already provide one (its own or
 * inherited), so a delegate that implements a method keeps it and can forward to
 * `Application.ios.defaultSceneConfiguration` / `defaultDiscardSceneSessions` itself.
 *
 * @internal
 */
function installSceneDelegateDefaults(delegateClass) {
    const proto = delegateClass?.prototype;
    if (!proto) {
        return;
    }
    // Implementing the scene methods makes the app assume scene-based lifecycle management,
    // which boots to a white screen when Info.plist has no UIApplicationSceneManifest.
    // Configuring the delegate here is also why UISceneConfigurations does not have to be
    // declared in Info.plist — UIApplicationSceneManifest on its own is enough.
    if (supportsScenes()) {
        if (!proto.applicationConfigurationForConnectingSceneSessionOptions) {
            proto.applicationConfigurationForConnectingSceneSessionOptions = function (application, connectingSceneSession, options) {
                return Application.ios.defaultSceneConfiguration(application, connectingSceneSession, options);
            };
        }
        if (!proto.applicationDidDiscardSceneSessions) {
            proto.applicationDidDiscardSceneSessions = function (application, sceneSessions) {
                Application.ios.defaultDiscardSceneSessions(application, sceneSessions);
            };
        }
    }
    if (!('window' in proto)) {
        Object.defineProperty(proto, 'window', {
            get() {
                return this[delegateWindowKey] ?? Application.ios.window;
            },
            // UIKit assigns `delegate.window` on non-scene apps and a delegate may assign it
            // itself, so the value has to be kept: a discarding setter would leave the
            // delegate reporting a window it never set.
            set(value) {
                this[delegateWindowKey] = value;
            },
            enumerable: true,
            configurable: true,
        });
    }
}
installSceneDelegateDefaults(Responder);
let warnedAboutDelegateProtocols = false;
let warnedAboutDelegateAfterStart = false;
function warnAboutDelegate(message) {
    Trace.write(message, Trace.categories.Error, Trace.messageType.warn);
    console.warn(message);
}
/**
 * Reports the two custom-delegate mistakes NativeScript cannot correct on the app's behalf:
 * a delegate class that never declared `UIApplicationDelegate` conformance, and a delegate
 * assigned once `UIApplicationMain` has already been given a class.
 */
function warnAboutDelegateClass(delegateClass, alreadyStarted) {
    const protocols = delegateClass?.ObjCProtocols;
    if (!warnedAboutDelegateProtocols && !(Array.isArray(protocols) && protocols.indexOf(UIApplicationDelegate) !== -1)) {
        warnedAboutDelegateProtocols = true;
        warnAboutDelegate('Application.ios.delegate was set to a class that does not list UIApplicationDelegate in its static ObjCProtocols. Add `static ObjCProtocols = [UIApplicationDelegate];` to the class body: the Objective-C class is built from ObjCProtocols and cached, so conformance cannot be declared from here and UIKit may never dispatch the delegate methods.');
    }
    if (alreadyStarted && !warnedAboutDelegateAfterStart) {
        warnedAboutDelegateAfterStart = true;
        warnAboutDelegate('Application.ios.delegate was set after the application started. UIApplicationMain has already been given a delegate class, so this assignment has no effect — set Application.ios.delegate before calling Application.run().');
    }
}
/**
 * Reads the payload `openWindow()` put on the activating NSUserActivity.
 */
function getSceneConnectionData(connectionOptions) {
    const activities = connectionOptions?.userActivities;
    if (!activities || activities.count === 0) {
        return undefined;
    }
    const activity = activities.allObjects.objectAtIndex(0);
    return activity?.userInfo ? dataDeserialize(activity.userInfo) : undefined;
}
var SceneDelegate = (function (_super) {
    __extends(SceneDelegate, _super);
    function SceneDelegate() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Object.defineProperty(SceneDelegate.prototype, "window", {
        get: function () {
            return this._window;
        },
        set: function (value) {
            this._window = value;
        },
        enumerable: true,
        configurable: true
    });
    SceneDelegate.prototype.sceneWillConnectToSessionOptions = function (scene, session, connectionOptions) {
        if (Trace.isEnabled()) {
            Trace.write("SceneDelegate.sceneWillConnectToSessionOptions called with role: ".concat(session.role), Trace.categories.NativeLifecycle);
        }
        if (!(scene instanceof UIWindowScene)) {
            return;
        }
        var windowScene = scene;
        var isFirstScene = Application.ios._getWindows().length === 0;
        this._scene = windowScene;
        this._window = UIWindow.alloc().initWithWindowScene(windowScene);
        if (!__VISIONOS__) {
            this._window.backgroundColor = SDK_VERSION <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
        }
        var nativeWindowId = IOSNativeWindow.getSceneId(windowScene);
        var knownWindow = nativeWindowId ? Application.ios.getWindowById(nativeWindowId) : undefined;
        var nativeWindow;
        if ((knownWindow === null || knownWindow === void 0 ? void 0 : knownWindow.state) === "detached") {
            nativeWindow = knownWindow;
            nativeWindow._reattach(windowScene, this._window);
        }
        else {
            var isPrimary_1 = isFirstScene || !Application.ios.primaryWindow;
            nativeWindow = new IOSNativeWindow(windowScene, this._window, nativeWindowId, isPrimary_1);
            Application.ios._registerWindow(nativeWindow);
        }
        var isPrimary = nativeWindow.isPrimary;
        nativeWindow._notifyEvent(NativeWindowEvents.attached);
        if (isPrimary) {
            setiOSWindow(this._window);
        }
        nativeWindow.notify({
            eventName: NativeWindowEvents.sceneWillConnect,
            object: nativeWindow,
            window: nativeWindow,
            scene: windowScene,
            uiWindow: this._window,
            connectionOptions: connectionOptions,
        });
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneWillConnect,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
            uiWindow: this._window,
            connectionOptions: connectionOptions,
        });
        if (isPrimary) {
            this._window.makeKeyAndVisible();
        }
        if (nativeWindow.role === "application") {
            Application.ios._resolveWindowContent(nativeWindow, {
                window: nativeWindow,
                isPrimary: isPrimary,
                data: getSceneConnectionData(connectionOptions),
                ios: { connectionOptions: connectionOptions },
            });
        }
    };
    SceneDelegate.prototype.sceneDidBecomeActive = function (scene) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow._notifyEvent(NativeWindowEvents.activate);
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneDidActivate,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneDidActivate,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
        });
        Application.ios._setWindowActive(nativeWindow, true, windowScene);
        var rootView = nativeWindow === null || nativeWindow === void 0 ? void 0 : nativeWindow.rootView;
        if (rootView && !rootView.isLoaded) {
            rootView.callLoaded();
        }
    };
    SceneDelegate.prototype.sceneWillResignActive = function (scene) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow._notifyEvent(NativeWindowEvents.deactivate);
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneWillResignActive,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneWillResignActive,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
        });
        Application.ios._setWindowActive(nativeWindow, false, windowScene);
    };
    SceneDelegate.prototype.sceneWillEnterForeground = function (scene) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow._notifyEvent(NativeWindowEvents.foreground);
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneWillEnterForeground,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneWillEnterForeground,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
        });
        Application.ios._setWindowInForeground(nativeWindow, true, windowScene);
    };
    SceneDelegate.prototype.sceneDidEnterBackground = function (scene) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow._notifyEvent(NativeWindowEvents.background);
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneDidEnterBackground,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneDidEnterBackground,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
        });
        Application.ios._setWindowInForeground(nativeWindow, false, windowScene);
        var rootView = nativeWindow === null || nativeWindow === void 0 ? void 0 : nativeWindow.rootView;
        if (rootView && rootView.isLoaded) {
            rootView.callUnloaded();
        }
    };
    SceneDelegate.prototype.sceneDidDisconnect = function (scene) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        Application.ios._setWindowActive(nativeWindow, false, windowScene);
        Application.ios._setWindowInForeground(nativeWindow, false, windowScene);
        if (nativeWindow) {
            nativeWindow._surfaceGone = true;
            var isClosing = nativeWindow._closeRequested || !nativeWindow._hasSessionIdentity;
            if (isClosing) {
                nativeWindow._notifyEvent(NativeWindowEvents.close);
            }
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneDidDisconnect,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
            });
            if (isClosing) {
                Application.ios._unregisterWindow(nativeWindow);
            }
            else {
                nativeWindow._detach();
            }
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneDidDisconnect,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
        });
    };
    SceneDelegate.prototype.sceneOpenURLContexts = function (scene, URLContexts) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneOpenURLContexts,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
                urlContexts: URLContexts,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneOpenURLContexts,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
            urlContexts: URLContexts,
        });
        forwardOpenURLContexts(Application.ios.delegate, UIApplication.sharedApplication, URLContexts);
    };
    SceneDelegate.prototype.sceneContinueUserActivity = function (scene, userActivity) {
        var windowScene = scene;
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        if (nativeWindow) {
            nativeWindow.notify({
                eventName: NativeWindowEvents.sceneContinueUserActivity,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
                userActivity: userActivity,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.sceneContinueUserActivity,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
            userActivity: userActivity,
        });
        forwardContinueUserActivity(Application.ios.delegate, UIApplication.sharedApplication, userActivity);
    };
    SceneDelegate.prototype.windowScenePerformActionForShortcutItemCompletionHandler = function (windowScene, shortcutItem, completionHandler) {
        var nativeWindow = Application.ios._getWindowForScene(windowScene);
        var deliver = oneShotCompletion(completionHandler);
        if (nativeWindow) {
            nativeWindow.notify({
                eventName: NativeWindowEvents.scenePerformActionForShortcutItem,
                object: nativeWindow,
                window: nativeWindow,
                scene: windowScene,
                shortcutItem: shortcutItem,
                completionHandler: deliver,
            });
        }
        Application.ios.notify({
            eventName: NativeWindowEvents.scenePerformActionForShortcutItem,
            object: Application.ios,
            window: nativeWindow,
            scene: windowScene,
            shortcutItem: shortcutItem,
            completionHandler: deliver,
        });
        deliverShortcutItem(Application.ios.delegate, UIApplication.sharedApplication, shortcutItem, deliver);
    };
    SceneDelegate.ObjCProtocols = [UIWindowSceneDelegate];
    return SceneDelegate;
}(UIResponder));
// ensure available globally
global.SceneDelegate = SceneDelegate;
export class iOSApplication extends ApplicationCommon {
    /**
     * @internal - should not be constructed by the user.
     */
    constructor() {
        super();
        this._delegateHandlers = new Map();
        // Application-role windows currently in the foreground / currently active. Membership,
        // not a count, so a repeated or missing scene callback cannot drift the aggregate.
        this._foregroundWindows = new Set();
        this._activeWindows = new Set();
        this._notificationObservers = [];
        this._softRebootSceneDelegates = new Map();
        this.displayedOnce = false;
        /**
         * Delays the 'launch' event, and with it the creation of the first window's content, until the
         * app first becomes active, instead of raising it while the app finishes launching.
         *
         * Applies to non-scene apps only. It has no effect in a scene-based app, where each window's
         * content is resolved as its scene connects.
         *
         * @deprecated Use the 'ready' event for application initialization, and
         * Application.setWindowContentResolver() to provide window UI.
         */
        this.shouldDelayLaunchEvent = false;
        this.addNotificationObserver(UIApplicationDidFinishLaunchingNotification, this.didFinishLaunchingWithOptions.bind(this));
        this.addNotificationObserver(UIApplicationDidBecomeActiveNotification, this.didBecomeActive.bind(this));
        this.addNotificationObserver(UIApplicationDidEnterBackgroundNotification, this.didEnterBackground.bind(this));
        this.addNotificationObserver(UIApplicationWillTerminateNotification, this.willTerminate.bind(this));
        this.addNotificationObserver(UIApplicationDidReceiveMemoryWarningNotification, this.didReceiveMemoryWarning.bind(this));
        this.addNotificationObserver(UIApplicationDidChangeStatusBarOrientationNotification, this.didChangeStatusBarOrientation.bind(this));
    }
    getRootView() {
        return this._rootView;
    }
    resetRootView(entry) {
        super.resetRootView(entry);
        this.setWindowContent();
    }
    run(entry) {
        setAppMainEntry(typeof entry === 'string' ? { moduleName: entry } : entry);
        this.started = true;
        if (this.nativeApp) {
            // During Vite HMR dev boot, the placeholder has already started
            // the app lifecycle. A second run() with an entry should replace
            // the placeholder root, NOT present a modal via runAsEmbeddedApp.
            // The HTTP ESM realm creates a separate @nativescript/core instance,
            // so JS-level patching of Application.run can't intercept this call.
            // Detect HMR mode via the placeholder's global flag and use
            // setWindowContent on the PRIMARY Application singleton (bundled realm)
            // which has the actual window and root view hierarchy.
            const g = globalThis;
            if (g.__NS_DEV_PLACEHOLDER_ROOT_VIEW__ || g.__NS_DEV_PLACEHOLDER_ROOT_EARLY__) {
                if (entry) {
                    // Defer to next run loop tick so resetRootView executes outside the
                    // HTTP ESM import context. Direct calls can fail with
                    // "ReferenceError: __COMMONJS__ is not defined" because the JS
                    // execution stack is in the HTTP realm when Builder loads modules.
                    const resolvedEntry = typeof entry === 'string' ? { moduleName: entry } : entry;
                    setTimeout(() => {
                        try {
                            const primaryApp = g.Application;
                            if (primaryApp && typeof primaryApp.resetRootView === 'function') {
                                primaryApp.resetRootView(resolvedEntry);
                            }
                        }
                        catch (e) {
                            if (__DEV__)
                                console.warn('[app-ios] deferred resetRootView failed:', e);
                        }
                        delete g.__NS_DEV_PLACEHOLDER_ROOT_VIEW__;
                        delete g.__NS_DEV_PLACEHOLDER_ROOT_EARLY__;
                    }, 0);
                }
                else {
                    // Framework (e.g. Angular) calls run() with no entry — it manages
                    // root views itself via resetRootView(). No-op to avoid presenting
                    // a modal via runAsEmbeddedApp or throwing "Main entry is missing".
                    if (__DEV__)
                        console.info('[app-ios] run() called with no entry during HMR placeholder; framework manages root view');
                }
                return;
            }
            this.runAsEmbeddedApp();
        }
        else {
            this.runAsMainApp();
        }
    }
    runAsMainApp() {
        UIApplicationMain(0, null, null, this.delegate ? NSStringFromClass(this.delegate) : NSStringFromClass(Responder));
    }
    runAsEmbeddedApp() {
        this.notifyReady();
        this._reattachNativeDelegatesAfterSoftReboot();
        // TODO: this rootView should be held alive until rootController dismissViewController is called.
        const rootView = this.createRootView(this._rootView, true);
        if (!rootView) {
            return;
        }
        this._rootView = rootView;
        setRootView(rootView);
        // Attach to the existing iOS app
        let window = getWindow();
        if (!window) {
            // In-process soft reboot with OTAs.
            // Original UIWindow is deallocated when the old JS isolate is torn down.
            // Recreate a window bound to the active UIWindowScene so the
            // root has somewhere to attach.
            const app = UIApplication.sharedApplication;
            const all = app && app.connectedScenes ? app.connectedScenes.allObjects : null;
            let targetScene;
            if (all) {
                for (let i = 0; i < all.count; i++) {
                    const s = all.objectAtIndex(i);
                    // Only UIWindowScene exposes `windows`; prefer a foreground-active one.
                    if (s && typeof s.windows !== 'undefined') {
                        targetScene = s;
                        if (s.activationState === 0 /* UISceneActivationState.ForegroundActive */) {
                            break;
                        }
                    }
                }
            }
            if (targetScene) {
                window = UIWindow.alloc().initWithWindowScene(targetScene);
                if (!__VISIONOS__) {
                    window.backgroundColor = SDK_VERSION <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
                }
                // The registry lives in JS and was lost with the previous isolate, so
                // the still-connected scene needs a fresh NativeWindow to be reachable.
                const isPrimary = !this.primaryWindow;
                const nativeWindow = new IOSNativeWindow(targetScene, window, IOSNativeWindow.getSceneId(targetScene), isPrimary);
                this._registerWindow(nativeWindow);
                if (isPrimary) {
                    setiOSWindow(window);
                }
                // If the scene's delegate was recreated after a soft reboot, point it
                // at the new window so `scene.delegate.window` queries resolve.
                const freshSceneDelegate = this._softRebootSceneDelegates.get(targetScene);
                if (freshSceneDelegate) {
                    freshSceneDelegate.window = window;
                }
            }
        }
        if (!window) {
            return;
        }
        // May be null on a freshly recreated window — expected; the replace-root
        // path below sets it. Only the embedder path needs an existing controller.
        const rootController = window.rootViewController;
        const embedderDelegate = NativeScriptEmbedder.sharedInstance().delegate;
        // Embed into host app requires an existing root view controller
        if (embedderDelegate && !rootController) {
            return;
        }
        let hostWindow = this.primaryWindow;
        if (!hostWindow) {
            // Only an embedder delegate makes this window a guest: without one NativeScript
            // owns the UIApplication and the window has to attach its own content.
            const role = embedderDelegate ? 'embedded' : 'application';
            hostWindow = new IOSNativeWindow(window.windowScene ?? undefined, window, 'embedded-main', true, role);
            this._registerWindow(hostWindow);
            hostWindow._notifyEvent(NativeWindowEvents.attached);
        }
        hostWindow.setContent(rootView);
        this.notifyAppStarted();
    }
    /**
     * After an in-process soft reboot (NativeScriptRuntime.reloadApplication /
     * restartWithConfig), the Objective-C delegate classes created by the
     * previous JS isolate still exist and UIKit keeps dispatching to their
     * now-inert instances: their method callbacks bail out because the isolate
     * that implemented them is gone. Notification-center observers are
     * re-registered by the new isolate, but delegate-based dispatch (custom
     * UIApplicationDelegate methods like push-token/openURL callbacks, and the
     * UIScene delegates used by scene-lifecycle apps) stays pinned to the old
     * bundle. Recreate those delegates from this bundle's classes and re-point
     * UIKit at them.
     */
    _reattachNativeDelegatesAfterSoftReboot() {
        if (getRuntimeReloadCount() <= 0) {
            // First boot: UIApplicationMain (or the host app) set up delegates.
            return;
        }
        if (isEmbedded()) {
            // The host app owns the UIApplication delegate; never touch it.
            return;
        }
        const app = UIApplication.sharedApplication;
        if (!app) {
            return;
        }
        // Fresh application delegate from the new bundle. Assigning `delegate`
        // does not retain (unlike the UIApplicationMain launch path), so keep a
        // strong reference ourselves.
        this.delegate ?? (this.delegate = Responder);
        const freshDelegate = this.delegate.new();
        this._softRebootAppDelegate = freshDelegate;
        app.delegate = freshDelegate;
        // Re-point already-connected scenes at fresh scene delegates so scene
        // lifecycle and user-implemented scene delegate methods (shortcuts,
        // openURLContexts, userActivity continuation, etc.) reach this isolate.
        // Newly connecting scenes are covered by the fresh application delegate's
        // applicationConfigurationForConnectingSceneSessionOptions, which returns
        // this bundle's SceneDelegate class.
        if (this.supportsScenes()) {
            this._softRebootSceneDelegates.clear();
            const scenes = app.connectedScenes?.allObjects;
            for (let i = 0; scenes && i < scenes.count; i++) {
                const scene = scenes.objectAtIndex(i);
                if (!(scene instanceof UIWindowScene)) {
                    continue;
                }
                const freshSceneDelegate = SceneDelegate.new();
                scene.delegate = freshSceneDelegate;
                this._softRebootSceneDelegates.set(scene, freshSceneDelegate);
            }
        }
        if (Trace.isEnabled()) {
            Trace.write(`Reattached application delegate${this._softRebootSceneDelegates.size ? ` and ${this._softRebootSceneDelegates.size} scene delegate(s)` : ''} after soft reboot (reloadCount: ${getRuntimeReloadCount()})`, Trace.categories.NativeLifecycle);
        }
    }
    getViewController(rootView) {
        let viewController = rootView.viewController || rootView.ios;
        if (!(viewController instanceof UIViewController)) {
            // We set UILayoutViewController dynamically to the root view if it doesn't have a view controller
            // At the moment the root view doesn't have its native view created. We set it in the setViewControllerView func
            viewController = IOSHelper.UILayoutViewController.initWithOwner(new WeakRef(rootView));
            rootView.viewController = viewController;
        }
        return viewController;
    }
    setViewControllerView(view) {
        const viewController = view.viewController || view.ios;
        const nativeView = view.ios || view.nativeViewProtected;
        if (!nativeView || !viewController) {
            throw new Error('Root should be either UIViewController or UIView');
        }
        if (viewController instanceof IOSHelper.UILayoutViewController) {
            viewController.view.addSubview(nativeView);
        }
    }
    setMaxRefreshRate(options) {
        const adjustRefreshRate = () => {
            if (!this.displayedLink) {
                return;
            }
            const minFrameRateDisabled = NSBundle.mainBundle.objectForInfoDictionaryKey('CADisableMinimumFrameDurationOnPhone');
            if (minFrameRateDisabled) {
                let max = 120;
                const deviceMaxFrames = iosUtils.getMainScreen().maximumFramesPerSecond;
                if (options?.max) {
                    if (deviceMaxFrames) {
                        // iOS 10.3
                        max = options.max <= deviceMaxFrames ? options.max : deviceMaxFrames;
                    }
                    else if (this.displayedLink.preferredFramesPerSecond) {
                        // iOS 10.0
                        max = options.max <= this.displayedLink.preferredFramesPerSecond ? options.max : this.displayedLink.preferredFramesPerSecond;
                    }
                }
                if (SDK_VERSION >= 15 || __VISIONOS__) {
                    const min = options?.min || max / 2;
                    const preferred = options?.preferred || max;
                    this.displayedLink.preferredFrameRateRange = CAFrameRateRangeMake(min, max, preferred);
                }
                else {
                    this.displayedLink.preferredFramesPerSecond = max;
                }
            }
        };
        if (this.displayedOnce) {
            adjustRefreshRate();
            return;
        }
        this.displayedLinkTarget = CADisplayLinkTarget.initWithOwner(new WeakRef(this));
        this.displayedLink = CADisplayLink.displayLinkWithTargetSelector(this.displayedLinkTarget, 'onDisplayed');
        adjustRefreshRate();
        this.displayedLink.addToRunLoopForMode(NSRunLoop.mainRunLoop, NSDefaultRunLoopMode);
        this.displayedLink.addToRunLoopForMode(NSRunLoop.mainRunLoop, UITrackingRunLoopMode);
    }
    get rootController() {
        return this.window?.rootViewController;
    }
    get nativeApp() {
        return UIApplication.sharedApplication;
    }
    get window() {
        // TODO: consideration
        // may not want to cache this value given the potential of multiple scenes
        // particularly with SwiftUI app lifecycle based apps
        if (!getiOSWindow()) {
            // Note: NativeScriptViewFactory.getKeyWindow will always be used in SwiftUI app lifecycle based apps
            setiOSWindow(getWindow());
        }
        return getiOSWindow();
    }
    get delegate() {
        return this._delegate;
    }
    set delegate(value) {
        if (this._delegate !== value) {
            this._delegate = value;
            if (value) {
                warnAboutDelegateClass(value, this.started);
                installSceneDelegateDefaults(value);
            }
        }
    }
    /**
     * NativeScript's default implementation of the `UIApplicationDelegate`
     * `applicationConfigurationForConnectingSceneSessionOptions` method.
     *
     * It is installed automatically on the application delegate class unless that class
     * already implements the method. A delegate that does implement it can handle the
     * scenes it cares about and forward the rest here:
     *
     * ```ts
     * applicationConfigurationForConnectingSceneSessionOptions(app, session, options) {
     *   if (session.role === myCustomRole) {
     *     return myConfig;
     *   }
     *   return Application.ios.defaultSceneConfiguration(app, session, options);
     * }
     * ```
     *
     * `onSceneConfiguration` is consulted first. Scenes with the
     * `UIWindowSceneSessionRoleApplication` role then get a configuration backed by
     * NativeScript's SceneDelegate; every other role gets a bare configuration that
     * NativeScript does not manage.
     */
    defaultSceneConfiguration(application, connectingSceneSession, options) {
        // Let the user intercept scene configuration for any/all scenes
        const userHandler = this._onSceneConfiguration;
        if (userHandler) {
            const userConfig = userHandler(application, connectingSceneSession, options);
            if (userConfig) {
                return userConfig;
            }
        }
        // Only handle the standard window scene role — skip CarPlay, external displays, etc.
        if (connectingSceneSession.role !== UIWindowSceneSessionRoleApplication) {
            // Return a bare configuration so iOS doesn't crash, but NativeScript won't manage it
            return UISceneConfiguration.configurationWithNameSessionRole('Unmanaged', connectingSceneSession.role);
        }
        const config = UISceneConfiguration.configurationWithNameSessionRole('Default Configuration', connectingSceneSession.role);
        config.sceneClass = UIWindowScene;
        config.delegateClass = SceneDelegate;
        return config;
    }
    /**
     * NativeScript's default implementation of the `UIApplicationDelegate`
     * `applicationDidDiscardSceneSessions` method, which retires the `NativeWindow`s
     * belonging to the discarded sessions.
     *
     * It is installed automatically on the application delegate class unless that class
     * already implements the method, in which case forward to it from there so window
     * bookkeeping stays correct.
     */
    defaultDiscardSceneSessions(application, sceneSessions) {
        this._onSceneSessionsDiscarded(sceneSessions);
    }
    addDelegateHandler(methodName, handler) {
        // safe-guard against invalid handlers
        if (typeof handler !== 'function') {
            return;
        }
        // ensure we have a delegate; Responder already carries the defaults, so it is
        // stored directly rather than through the setter, whose warnings only apply to
        // a delegate class the app supplied.
        this._delegate ?? (this._delegate = Responder);
        const handlers = this._delegateHandlers.get(methodName) ?? [];
        if (!this._delegateHandlers.has(methodName)) {
            const originalHandler = this.delegate.prototype[methodName];
            if (originalHandler) {
                // if there is an original handler, we add it to the handlers array to be called first.
                handlers.push(originalHandler);
            }
            // replace the original method implementation with one that will call all handlers.
            this.delegate.prototype[methodName] = function (...args) {
                let res;
                for (const handler of handlers) {
                    if (typeof handler !== 'function') {
                        continue;
                    }
                    res = handler.apply(this, args);
                }
                return res;
            };
            // store the handlers
            this._delegateHandlers.set(methodName, handlers);
        }
        handlers.push(handler);
    }
    getNativeApplication() {
        return this.nativeApp;
    }
    addNotificationObserver(notificationName, onReceiveCallback) {
        const observer = NotificationObserver.initWithCallback(onReceiveCallback);
        NSNotificationCenter.defaultCenter.addObserverSelectorNameObject(observer, 'onReceive', notificationName, null);
        this._notificationObservers.push(observer);
        return observer;
    }
    removeNotificationObserver(observer /* NotificationObserver */, notificationName) {
        const index = this._notificationObservers.indexOf(observer);
        if (index >= 0) {
            this._notificationObservers.splice(index, 1);
            NSNotificationCenter.defaultCenter.removeObserverNameObject(observer, notificationName, null);
        }
    }
    getSystemAppearance() {
        // userInterfaceStyle is available on UITraitCollection since iOS 12.
        if ((!__VISIONOS__ && SDK_VERSION <= 11) || !this.rootController) {
            return null;
        }
        const userInterfaceStyle = this.rootController.traitCollection.userInterfaceStyle;
        return this.getSystemAppearanceValue(userInterfaceStyle);
    }
    getSystemAppearanceValue(userInterfaceStyle) {
        switch (userInterfaceStyle) {
            case 2 /* UIUserInterfaceStyle.Dark */:
                return 'dark';
            case 1 /* UIUserInterfaceStyle.Light */:
            case 0 /* UIUserInterfaceStyle.Unspecified */:
                return 'light';
        }
    }
    getLayoutDirection() {
        if (!this.rootController) {
            return null;
        }
        const layoutDirection = this.rootController.traitCollection.layoutDirection;
        return this.getLayoutDirectionValue(layoutDirection);
    }
    getLayoutDirectionValue(layoutDirection) {
        switch (layoutDirection) {
            case 0 /* UITraitEnvironmentLayoutDirection.LeftToRight */:
                return CoreTypes.LayoutDirection.ltr;
            case 1 /* UITraitEnvironmentLayoutDirection.RightToLeft */:
                return CoreTypes.LayoutDirection.rtl;
        }
    }
    getOrientation() {
        let statusBarOrientation;
        if (__VISIONOS__) {
            statusBarOrientation = NativeScriptEmbedder.sharedInstance().windowScene.interfaceOrientation;
        }
        else {
            statusBarOrientation = UIApplication.sharedApplication.statusBarOrientation;
        }
        return this.getOrientationValue(statusBarOrientation);
    }
    getOrientationValue(orientation) {
        switch (orientation) {
            case 3 /* UIInterfaceOrientation.LandscapeRight */:
            case 4 /* UIInterfaceOrientation.LandscapeLeft */:
                return 'landscape';
            case 2 /* UIInterfaceOrientation.PortraitUpsideDown */:
            case 1 /* UIInterfaceOrientation.Portrait */:
                return 'portrait';
            case 0 /* UIInterfaceOrientation.Unknown */:
                return 'unknown';
        }
    }
    notifyAppStarted(notification) {
        const root = this.notifyLaunch({
            ios: notification?.userInfo?.objectForKey('UIApplicationLaunchOptionsLocalNotificationKey') ?? null,
        });
        if (getiOSWindow()) {
            if (root !== null && !isEmbedded()) {
                this.setWindowContent(root);
            }
        }
        else {
            setiOSWindow(this.window);
        }
    }
    _onLivesync(context) {
        // Handle application root module
        const isAppRootModuleChanged = context && context.path && context.path.includes(this.getMainEntry().moduleName) && context.type !== 'style';
        // Set window content when:
        // + Application root module is changed
        // + View did not handle the change
        // Note:
        // The case when neither app root module is changed, nor livesync is handled on View,
        // then changes will not apply until navigate forward to the module.
        if (isAppRootModuleChanged || (this._rootView && !this._rootView._onLivesync(context))) {
            this.setWindowContent();
        }
    }
    setWindowContent(view) {
        const rootView = this.createRootView(view);
        const primaryWindow = this.primaryWindow;
        if (primaryWindow) {
            primaryWindow.setContent(rootView);
            return;
        }
        this.setWindowContentFallback(rootView);
    }
    /**
     * Attaches content to the raw `UIWindow`. Every launch path registers a primary
     * NativeWindow, so this only runs when no window is left to own the content.
     */
    setWindowContentFallback(rootView) {
        if (this._rootView) {
            this._rootView._onRootViewReset();
        }
        const controller = this.getViewController(rootView);
        // setup view as styleScopeHost
        rootView._setupAsRootView({});
        this.setViewControllerView(rootView);
        const win = this.window;
        const haveController = win.rootViewController !== null;
        win.rootViewController = controller;
        if (!haveController) {
            win.makeKeyAndVisible();
        }
        this.adoptRootView(rootView);
    }
    // Observers
    didFinishLaunchingWithOptions(notification) {
        if (__DEV__) {
            /**
             * v9+ runtime crash handling
             * When crash occurs during boot, we let runtime take over
             */
            if (notification.userInfo) {
                const isBootCrash = notification.userInfo.objectForKey('NativeScriptBootCrash');
                if (isBootCrash) {
                    // fatal crash will show in console without app exiting
                    // allowing hot reload fixes to continue
                    return;
                }
            }
        }
        // Must precede every window registration below and every scene connect that follows.
        this.notifyReady();
        this.setMaxRefreshRate();
        // Only set up window if NOT using scene-based lifecycle
        if (!this.supportsScenes()) {
            // Traditional single-window app setup
            // ensures window is assigned to proper window scene
            setiOSWindow(this.window);
            if (!getiOSWindow()) {
                // if still no window, create one
                setiOSWindow(UIWindow.alloc().initWithFrame(UIScreen.mainScreen.bounds));
            }
            if (!__VISIONOS__) {
                this.window.backgroundColor = SDK_VERSION <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
            }
            if (!this.primaryWindow) {
                const nativeWindow = new IOSNativeWindow(undefined, this.window, 'main', true, 'application');
                this._registerWindow(nativeWindow);
                nativeWindow._notifyEvent(NativeWindowEvents.attached);
            }
            const primaryWindow = this.primaryWindow;
            const resolveContent = () => this._resolveWindowContent(primaryWindow, {
                window: primaryWindow,
                isPrimary: true,
            }, {
                launchData: {
                    ios: notification?.userInfo?.objectForKey('UIApplicationLaunchOptionsLocalNotificationKey') ?? null,
                },
            });
            if (this.shouldDelayLaunchEvent) {
                this._pendingWindowContentResolve = resolveContent;
            }
            else {
                resolveContent();
            }
        }
        else {
            // Scene-based app - window creation will happen in scene delegate
        }
    }
    didBecomeActive(notification) {
        const pendingWindowContentResolve = this._pendingWindowContentResolve;
        if (pendingWindowContentResolve) {
            this._pendingWindowContentResolve = null;
            pendingWindowContentResolve();
        }
        // A scene app derives app-level state from its windows, so this notification must not
        // drive it as well. In scene mode the root view belongs to a window too, so the scene
        // delegate loads it.
        if (!this.supportsScenes()) {
            const additionalData = {
                ios: UIApplication.sharedApplication,
            };
            this.setInBackground(false, additionalData);
            this.setSuspended(false, additionalData);
            const rootView = this._rootView;
            if (rootView && !rootView.isLoaded) {
                rootView.callLoaded();
            }
        }
    }
    didEnterBackground(notification) {
        // See didBecomeActive: in scene mode the windows drive app-level state.
        if (!this.supportsScenes()) {
            const additionalData = {
                ios: UIApplication.sharedApplication,
            };
            this.setInBackground(true, additionalData);
            this.setSuspended(true, additionalData);
            const rootView = this._rootView;
            if (rootView && rootView.isLoaded) {
                rootView.callUnloaded();
            }
        }
    }
    willTerminate(notification) {
        this.notify({
            eventName: this.exitEvent,
            object: this,
            ios: this.ios,
        });
        // const rootView = this._rootView;
        // if (rootView && rootView.isLoaded) {
        // 	rootView.callUnloaded();
        // }
    }
    didReceiveMemoryWarning(notification) {
        this.notify({
            eventName: this.lowMemoryEvent,
            object: this,
            ios: this.ios,
        });
    }
    didChangeStatusBarOrientation(notification) {
        // The notification is app-wide, but scenes rotate independently, so every attached
        // window is refreshed from its own scene.
        for (const nativeWindow of this._windows) {
            if (nativeWindow.state !== 'attached') {
                continue;
            }
            const orientation = nativeWindow.ios?.scene?.interfaceOrientation ?? UIApplication.sharedApplication.statusBarOrientation;
            nativeWindow._setOrientation(this.getOrientationValue(orientation));
        }
    }
    // --- App-level root view mirror ---
    /**
     * Keeps the app-level root view state (`getRootView()`, the global root view and the
     * `initRootView` event) following whatever the primary window shows.
     */
    mirrorPrimaryWindow(nativeWindow) {
        if (this._mirroredWindow === nativeWindow) {
            return;
        }
        this._mirroredWindow?.off(NativeWindowEvents.contentLoaded, this.onPrimaryWindowContentLoaded, this);
        this._mirroredWindow = nativeWindow;
        nativeWindow.on(NativeWindowEvents.contentLoaded, this.onPrimaryWindowContentLoaded, this);
        if (nativeWindow.rootView && nativeWindow.rootView !== this._rootView) {
            this.adoptRootView(nativeWindow.rootView);
        }
    }
    onPrimaryWindowContentLoaded(data) {
        this.adoptRootView(data.window.rootView);
    }
    adoptRootView(rootView) {
        if (!rootView) {
            return;
        }
        this._rootView = rootView;
        setRootView(rootView);
        this.initRootView(rootView, this._mirroredWindow);
    }
    // --- NativeWindow registry ---
    /**
     * @internal - hands the discarded sessions' ids to the window registry, which decides
     * which of them name a window that is actually finished with.
     */
    _onSceneSessionsDiscarded(sessions) {
        const all = sessions?.allObjects;
        if (!all) {
            return;
        }
        const ids = [];
        for (let i = 0; i < all.count; i++) {
            const persistentIdentifier = all.objectAtIndex(i)?.persistentIdentifier;
            if (persistentIdentifier) {
                ids.push(`${persistentIdentifier}`);
            }
        }
        this._retireDiscardedWindows(ids);
    }
    /**
     * @internal - Get a NativeWindow by its scene.
     */
    _getWindowForScene(scene) {
        return this._windows.find((nw) => nw.ios?.scene === scene);
    }
    /**
     * @internal - Feeds a window's foreground state into the application-level
     * 'foreground'/'background' events, which describe the app as a whole: they are raised
     * when the first application-role window enters the foreground and when the last one
     * leaves it. Windows in any other role never speak for the app.
     */
    _setWindowInForeground(nativeWindow, inForeground, scene) {
        if (this._trackWindowState(this._foregroundWindows, nativeWindow, inForeground)) {
            this.setInBackground(!inForeground, {
                ios: UIApplication.sharedApplication,
                scene,
            });
        }
    }
    /**
     * @internal - Feeds a window's active state into the application-level 'resume'/'suspend'
     * events, raised when the first application-role window becomes active and when the last
     * active one resigns.
     */
    _setWindowActive(nativeWindow, active, scene) {
        if (this._trackWindowState(this._activeWindows, nativeWindow, active)) {
            this.setSuspended(!active, {
                ios: UIApplication.sharedApplication,
                scene,
            });
        }
    }
    /**
     * @returns whether the set flipped between empty and non-empty, which is the only point
     * at which app-level state changes.
     */
    _trackWindowState(windows, nativeWindow, member) {
        if (nativeWindow?.role !== 'application') {
            return false;
        }
        const wasPopulated = windows.size > 0;
        if (member) {
            windows.add(nativeWindow);
        }
        else {
            windows.delete(nativeWindow);
        }
        return wasPopulated !== windows.size > 0;
    }
    _onWindowRegistered(nativeWindow) {
        if (nativeWindow.isPrimary) {
            this.mirrorPrimaryWindow(nativeWindow);
        }
    }
    _onPrimaryWindowPromoted(nativeWindow) {
        const promotedWindow = nativeWindow.ios?.uiWindow;
        if (promotedWindow) {
            setiOSWindow(promotedWindow);
        }
        this.mirrorPrimaryWindow(nativeWindow);
    }
    /**
     * Register a callback to intercept scene configuration.
     *
     * Called for every new scene session. Return a `UISceneConfiguration` to handle
     * the scene yourself (e.g. CarPlay, external display), or return `null`/`undefined`
     * to let NativeScript handle it with the default SceneDelegate.
     *
     * NativeScript only auto-manages `UIWindowSceneSessionRoleApplication` scenes.
     * All other scene roles are ignored unless you provide a configuration here.
     *
     * @example
     * ```ts
     * Application.ios.onSceneConfiguration = (app, session, options) => {
     *   if (session.role === CPTemplateApplicationSceneSessionRoleApplication) {
     *     const config = UISceneConfiguration.configurationWithNameSessionRole('CarPlay', session.role);
     *     config.delegateClass = MyCarPlaySceneDelegate;
     *     return config;
     *   }
     *   // Return null to let NativeScript handle the default window scene
     *   return null;
     * };
     * ```
     */
    set onSceneConfiguration(handler) {
        this._onSceneConfiguration = handler;
    }
    get onSceneConfiguration() {
        return this._onSceneConfiguration;
    }
    // Scene management helper methods (kept for backward compat)
    get sceneDelegate() {
        if (!this._sceneDelegate) {
            this._sceneDelegate = SceneDelegate.new();
        }
        return this._sceneDelegate;
    }
    set sceneDelegate(value) {
        this._sceneDelegate = value;
    }
    /**
     * Multi-window support
     */
    /**
     * Opens a new window (scene).
     *
     * @param options Options for the new window. `options.data` is serialized into the
     * activating scene's `NSUserActivity.userInfo`.
     */
    openWindow(options) {
        if (!supportsMultipleScenes()) {
            console.log('Cannot create a new scene - not supported on this device.');
            return;
        }
        try {
            const app = UIApplication.sharedApplication;
            // iOS 17+
            if (SDK_VERSION >= 17) {
                let request;
                try {
                    request = UISceneSessionActivationRequest.requestWithRole(UIWindowSceneSessionRoleApplication);
                    const activity = NSUserActivity.alloc().initWithActivityType(`${NSBundle.mainBundle.bundleIdentifier}.scene`);
                    activity.userInfo = dataSerialize(options?.data ?? {});
                    request.userActivity = activity;
                    const activationOptions = UISceneActivationRequestOptions.new();
                    const primary = this.primaryWindow;
                    if (primary?.ios?.scene) {
                        activationOptions.requestingScene = primary.ios.scene;
                    }
                    request.options = activationOptions;
                }
                catch (roleError) {
                    console.log('Error creating request:', roleError);
                    return;
                }
                app.activateSceneSessionForRequestErrorHandler(request, (error) => {
                    if (error) {
                        console.log('Error creating new scene (iOS 17+):', error);
                        if (error.userInfo) {
                            console.error(`Error userInfo: ${error.userInfo.description}`);
                        }
                        if (error.localizedDescription.includes('role') && error.localizedDescription.includes('nil')) {
                            this.createSceneWithLegacyAPI(options?.data);
                        }
                        else if (error.domain === 'FBSWorkspaceErrorDomain' && error.code === 2) {
                            this.createSceneWithLegacyAPI(options?.data);
                        }
                    }
                });
            }
            else if (SDK_VERSION >= 13 && SDK_VERSION < 17) {
                app.requestSceneSessionActivationUserActivityOptionsErrorHandler(null, null, null, (error) => {
                    if (error) {
                        console.log('Error creating new scene (legacy):', error);
                    }
                });
            }
            else {
                console.log('Neither new nor legacy scene activation methods are available');
            }
        }
        catch (error) {
            console.error('Error requesting new scene:', error);
        }
    }
    /**
     * Closes a secondary window/scene.
     * Accepts a NativeWindow, View, UIWindow, UIWindowScene, or string id.
     */
    closeWindow(target) {
        if (!__APPLE__) {
            return;
        }
        try {
            let nativeWindow;
            if (target instanceof NativeWindow) {
                nativeWindow = target;
            }
            else {
                const scene = this._resolveScene(target);
                if (scene) {
                    nativeWindow = this._getWindowForScene(scene);
                }
            }
            if (!nativeWindow) {
                console.log('closeWindow: No window resolved for target');
                return;
            }
            nativeWindow.close();
        }
        catch (err) {
            console.log('closeWindow: Unexpected error', err);
        }
    }
    /**
     * @deprecated Use `getWindows()` instead.
     */
    getAllWindows() {
        return this._windows.map((nw) => nw.ios?.uiWindow).filter(Boolean);
    }
    /**
     * @deprecated Use `getWindows()` instead.
     */
    getAllScenes() {
        return this._windows.map((nw) => nw.ios?.scene).filter(Boolean);
    }
    /**
     * @deprecated Use `getWindows()` instead.
     */
    getWindowScenes() {
        return this.getAllScenes().filter((scene) => scene instanceof UIWindowScene);
    }
    /**
     * @deprecated Use `primaryWindow?.ios?.uiWindow` instead.
     */
    getPrimaryWindow() {
        const primary = this.primaryWindow;
        if (primary?.ios?.uiWindow) {
            return primary.ios.uiWindow;
        }
        return getiOSWindow();
    }
    /**
     * @deprecated Use `primaryWindow?.ios?.scene` instead.
     */
    getPrimaryScene() {
        return this.primaryWindow?.ios?.scene || null;
    }
    // Scene lifecycle management
    supportsScenes() {
        return supportsScenes();
    }
    supportsMultipleScenes() {
        return supportsMultipleScenes();
    }
    isUsingSceneLifecycle() {
        return this.supportsScenes() && this._windows.length > 0;
    }
    // Call this to set up scene-based configuration
    configureForScenes() {
        if (!this.supportsScenes()) {
            console.warn('Scene-based lifecycle is only supported on iOS 13+ iPad or visionOS with multi-scene enabled apps.');
            return;
        }
    }
    // Resolve a UIWindowScene from various input types
    _resolveScene(target) {
        if (!__APPLE__) {
            return null;
        }
        if (!target) {
            // Try to pick a non-primary window's scene
            const nonPrimary = this._windows.filter((nw) => !nw.isPrimary);
            return nonPrimary[0]?.ios?.scene || this.primaryWindow?.ios?.scene || null;
        }
        if (target && typeof target === 'object') {
            // UIWindowScene
            if (target.session && target.activationState !== undefined) {
                return target;
            }
            // UIWindow
            if (target.windowScene) {
                return target.windowScene;
            }
            // NativeScript View
            if (target?.nativeViewProtected) {
                const uiView = target.nativeViewProtected;
                const win = uiView?.window;
                return win?.windowScene || null;
            }
        }
        // String id lookup
        if (typeof target === 'string') {
            const found = this.getWindowById(target);
            if (found) {
                return found.ios?.scene || null;
            }
            // Try matching among known scenes
            for (const nw of this._windows) {
                const scene = nw.ios?.scene;
                if (scene && IOSNativeWindow.getSceneId(scene) === target) {
                    return scene;
                }
            }
        }
        return null;
    }
    createSceneWithLegacyAPI(data) {
        const windowScene = this.window?.windowScene;
        if (!windowScene) {
            return;
        }
        // Create user activity for the new scene
        const userActivity = NSUserActivity.alloc().initWithActivityType(`${NSBundle.mainBundle.bundleIdentifier}.scene`);
        userActivity.userInfo = dataSerialize(data ?? {});
        // Use the legacy API
        const options = UISceneActivationRequestOptions.new();
        options.requestingScene = windowScene;
        UIApplication.sharedApplication.requestSceneSessionActivationUserActivityOptionsErrorHandler(null, // session - null for new scene
        userActivity, options, (error) => {
            if (error) {
                console.error(`Legacy scene API failed: ${error.localizedDescription}`);
            }
        });
    }
    /**
     * Creates a simple view controller with a NativeScript view for a scene window.
     * @param window The UIWindow to set content for
     * @param view The NativeScript View to set as root content
     */
    setWindowRootView(window, view) {
        if (!window || !view) {
            return;
        }
        if (view.ios) {
            window.rootViewController = view.viewController;
            window.makeKeyAndVisible();
        }
        else {
            console.warn('View does not have a native iOS implementation');
        }
    }
    get ios() {
        // ensures Application.ios is defined when running on iOS
        return this;
    }
}
__decorate([
    profile,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [NSNotification]),
    __metadata("design:returntype", void 0)
], iOSApplication.prototype, "didFinishLaunchingWithOptions", null);
__decorate([
    profile,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [NSNotification]),
    __metadata("design:returntype", void 0)
], iOSApplication.prototype, "didBecomeActive", null);
const iosApp = new iOSApplication();
// Attach on global, so it can also be overwritten to implement different logic based on flavor
global.__onLiveSyncCore = function (context) {
    iosApp._onLivesync(context);
};
export * from './application-common';
export * from './application-interfaces';
export const Application = iosApp;
export const AndroidApplication = undefined;
function fontScaleChanged(origFontScale) {
    const oldValue = getFontScale();
    setFontScale(getClosestValidFontScale(origFontScale));
    const currentFontScale = getFontScale();
    if (oldValue !== currentFontScale) {
        Application.notify({
            eventName: Application.fontScaleChangedEvent,
            object: Application,
            newValue: currentFontScale,
        });
    }
}
export function getCurrentFontScale() {
    setupConfigListener();
    return getFontScale();
}
const sizeMap = new Map([
    [UIContentSizeCategoryExtraSmall, 0.5],
    [UIContentSizeCategorySmall, 0.7],
    [UIContentSizeCategoryMedium, 0.85],
    [UIContentSizeCategoryLarge, 1],
    [UIContentSizeCategoryExtraLarge, 1.15],
    [UIContentSizeCategoryExtraExtraLarge, 1.3],
    [UIContentSizeCategoryExtraExtraExtraLarge, 1.5],
    [UIContentSizeCategoryAccessibilityMedium, 2],
    [UIContentSizeCategoryAccessibilityLarge, 2.5],
    [UIContentSizeCategoryAccessibilityExtraLarge, 3],
    [UIContentSizeCategoryAccessibilityExtraExtraLarge, 3.5],
    [UIContentSizeCategoryAccessibilityExtraExtraExtraLarge, 4],
]);
function contentSizeUpdated(fontSize) {
    if (sizeMap.has(fontSize)) {
        fontScaleChanged(sizeMap.get(fontSize));
        return;
    }
    fontScaleChanged(1);
}
function useIOSFontScale() {
    if (Application.ios.nativeApp) {
        contentSizeUpdated(Application.ios.nativeApp.preferredContentSizeCategory);
    }
    else {
        fontScaleChanged(1);
    }
}
let fontSizeObserver;
function setupConfigListener(attempt = 0) {
    if (fontSizeObserver) {
        return;
    }
    if (!Application.ios.nativeApp) {
        if (attempt > 100) {
            fontScaleChanged(1);
            return;
        }
        // Couldn't get launchEvent to trigger.
        setTimeout(() => setupConfigListener(attempt + 1), 1);
        return;
    }
    fontSizeObserver = Application.ios.addNotificationObserver(UIContentSizeCategoryDidChangeNotification, (args) => {
        const fontSize = args.userInfo.valueForKey(UIContentSizeCategoryNewValueKey);
        contentSizeUpdated(fontSize);
    });
    Application.on(Application.exitEvent, () => {
        if (fontSizeObserver) {
            Application.ios.removeNotificationObserver(fontSizeObserver, UIContentSizeCategoryDidChangeNotification);
            fontSizeObserver = null;
        }
        Application.off(Application.resumeEvent, useIOSFontScale);
    });
    Application.on(Application.resumeEvent, useIOSFontScale);
    useIOSFontScale();
}
setInitFontScale(setupConfigListener);
/**
 * Convert array of values into a bitmask.
 *
 * @param values string values
 * @param map    map lower-case name to integer value.
 */
function inputArrayToBitMask(values, map) {
    return (enforceArray(values)
        .filter((value) => !!value)
        .map((value) => `${value}`.toLocaleLowerCase())
        .filter((value) => map.has(value))
        .reduce((res, value) => res | map.get(value), 0) || 0);
}
let AccessibilityTraitsMap;
let RoleTypeMap;
let nativeFocusedNotificationObserver;
let lastFocusedView;
function ensureNativeClasses() {
    if (AccessibilityTraitsMap && nativeFocusedNotificationObserver) {
        return;
    }
    AccessibilityTraitsMap = new Map([
        [AccessibilityTrait.AllowsDirectInteraction, UIAccessibilityTraitAllowsDirectInteraction],
        [AccessibilityTrait.CausesPageTurn, UIAccessibilityTraitCausesPageTurn],
        [AccessibilityTrait.NotEnabled, UIAccessibilityTraitNotEnabled],
        [AccessibilityTrait.Selected, UIAccessibilityTraitSelected],
        [AccessibilityTrait.UpdatesFrequently, UIAccessibilityTraitUpdatesFrequently],
    ]);
    RoleTypeMap = new Map([
        [AccessibilityRole.Adjustable, UIAccessibilityTraitAdjustable],
        [AccessibilityRole.Button, UIAccessibilityTraitButton],
        [AccessibilityRole.Checkbox, UIAccessibilityTraitButton],
        [AccessibilityRole.Header, UIAccessibilityTraitHeader],
        [AccessibilityRole.KeyboardKey, UIAccessibilityTraitKeyboardKey],
        [AccessibilityRole.Image, UIAccessibilityTraitImage],
        [AccessibilityRole.ImageButton, UIAccessibilityTraitImage | UIAccessibilityTraitButton],
        [AccessibilityRole.Link, UIAccessibilityTraitLink],
        [AccessibilityRole.None, UIAccessibilityTraitNone],
        [AccessibilityRole.PlaysSound, UIAccessibilityTraitPlaysSound],
        [AccessibilityRole.RadioButton, UIAccessibilityTraitButton],
        [AccessibilityRole.Search, UIAccessibilityTraitSearchField],
        [AccessibilityRole.StaticText, UIAccessibilityTraitStaticText],
        [AccessibilityRole.StartsMediaSession, UIAccessibilityTraitStartsMediaSession],
        [AccessibilityRole.Summary, UIAccessibilityTraitSummaryElement],
        [AccessibilityRole.Switch, UIAccessibilityTraitButton],
    ]);
    nativeFocusedNotificationObserver = Application.ios.addNotificationObserver(UIAccessibilityElementFocusedNotification, (args) => {
        const uiView = args.userInfo?.objectForKey(UIAccessibilityFocusedElementKey);
        if (!uiView?.tag) {
            return;
        }
        const rootView = Application.getRootView();
        // We use the UIView's tag to find the NativeScript View by its domId.
        let view = rootView.getViewByDomId(uiView?.tag);
        if (!view) {
            for (const modalView of rootView._getRootModalViews()) {
                view = modalView.getViewByDomId(uiView?.tag);
                if (view) {
                    break;
                }
            }
        }
        if (!view) {
            return;
        }
        const lastView = lastFocusedView?.deref();
        if (lastView && view !== lastView) {
            const lastFocusedUIView = lastView.nativeViewProtected;
            if (lastFocusedUIView) {
                lastFocusedView = null;
                notifyAccessibilityFocusState(lastView, false, true);
            }
        }
        lastFocusedView = new WeakRef(view);
        notifyAccessibilityFocusState(view, true, false);
    });
    Application.on(Application.exitEvent, () => {
        if (nativeFocusedNotificationObserver) {
            Application.ios.removeNotificationObserver(nativeFocusedNotificationObserver, UIAccessibilityElementFocusedNotification);
        }
        nativeFocusedNotificationObserver = null;
        lastFocusedView = null;
    });
}
export function updateAccessibilityProperties(view) {
    const uiView = view.nativeViewProtected;
    if (!uiView) {
        return;
    }
    ensureNativeClasses();
    const accessibilityRole = view.accessibilityRole;
    const accessibilityState = view.accessibilityState;
    if (!view.accessible || view.accessibilityHidden) {
        uiView.accessibilityTraits = UIAccessibilityTraitNone;
        return;
    }
    // NOTE: left here for various core inspection passes while running the toolbox app
    // console.log('--- Accessible element: ', view.constructor.name);
    // console.log('accessibilityLabel: ', view.accessibilityLabel);
    // console.log('accessibilityRole: ', accessibilityRole);
    // console.log('accessibilityState: ', accessibilityState);
    // console.log('accessibilityValue: ', view.accessibilityValue);
    let a11yTraits = UIAccessibilityTraitNone;
    if (RoleTypeMap.has(accessibilityRole)) {
        a11yTraits |= RoleTypeMap.get(accessibilityRole);
    }
    switch (accessibilityRole) {
        case AccessibilityRole.Checkbox:
        case AccessibilityRole.RadioButton:
        case AccessibilityRole.Switch: {
            if (accessibilityState === AccessibilityState.Checked) {
                a11yTraits |= AccessibilityTraitsMap.get(AccessibilityTrait.Selected);
            }
            break;
        }
        default: {
            if (accessibilityState === AccessibilityState.Selected) {
                a11yTraits |= AccessibilityTraitsMap.get(AccessibilityTrait.Selected);
            }
            if (accessibilityState === AccessibilityState.Disabled) {
                a11yTraits |= AccessibilityTraitsMap.get(AccessibilityTrait.NotEnabled);
            }
            break;
        }
    }
    const UpdatesFrequentlyTrait = AccessibilityTraitsMap.get(AccessibilityTrait.UpdatesFrequently);
    switch (view.accessibilityLiveRegion) {
        case AccessibilityLiveRegion.Polite:
        case AccessibilityLiveRegion.Assertive: {
            a11yTraits |= UpdatesFrequentlyTrait;
            break;
        }
        default: {
            a11yTraits &= ~UpdatesFrequentlyTrait;
            break;
        }
    }
    // NOTE: left here for various core inspection passes while running the toolbox app
    // if (view.accessibilityLiveRegion) {
    // 	console.log('accessibilityLiveRegion:', view.accessibilityLiveRegion);
    // }
    if (view.accessibilityMediaSession) {
        a11yTraits |= RoleTypeMap.get(AccessibilityRole.StartsMediaSession);
    }
    // NOTE: There were duplicated types in traits and roles previously which we conslidated
    // not sure if this is still needed
    // accessibilityTraits used to be stored on {N} view component but if the above
    // is combining all traits fresh each time through, don't believe we need to keep track or previous traits
    // if (view.accessibilityTraits) {
    // 	a11yTraits |= inputArrayToBitMask(view.accessibilityTraits, AccessibilityTraitsMap);
    // }
    // NOTE: left here for various core inspection passes while running the toolbox app
    // console.log('a11yTraits:', a11yTraits);
    // console.log('    ');
    uiView.accessibilityTraits = a11yTraits;
}
setA11yUpdatePropertiesCallback(updateAccessibilityProperties);
export const sendAccessibilityEvent = () => { };
export function isAccessibilityServiceEnabled() {
    const accessibilityServiceEnabled = isA11yEnabled();
    if (typeof accessibilityServiceEnabled === 'boolean') {
        return accessibilityServiceEnabled;
    }
    let isVoiceOverRunning;
    if (typeof UIAccessibilityIsVoiceOverRunning === 'function') {
        isVoiceOverRunning = UIAccessibilityIsVoiceOverRunning;
    }
    else {
        // iOS is too old to tell us if voice over is enabled
        if (typeof UIAccessibilityIsVoiceOverRunning !== 'function') {
            setA11yEnabled(false);
            return isA11yEnabled();
        }
    }
    setA11yEnabled(isVoiceOverRunning());
    let voiceOverStatusChangedNotificationName = null;
    if (typeof UIAccessibilityVoiceOverStatusDidChangeNotification !== 'undefined') {
        voiceOverStatusChangedNotificationName = UIAccessibilityVoiceOverStatusDidChangeNotification;
    }
    else if (typeof UIAccessibilityVoiceOverStatusChanged !== 'undefined') {
        voiceOverStatusChangedNotificationName = UIAccessibilityVoiceOverStatusChanged;
    }
    if (voiceOverStatusChangedNotificationName) {
        nativeObserver = Application.ios.addNotificationObserver(voiceOverStatusChangedNotificationName, () => {
            setA11yEnabled(isVoiceOverRunning());
        });
        Application.on(Application.exitEvent, () => {
            if (nativeObserver) {
                Application.ios.removeNotificationObserver(nativeObserver, voiceOverStatusChangedNotificationName);
            }
            setA11yEnabled(undefined);
            nativeObserver = null;
        });
    }
    Application.on(Application.resumeEvent, () => {
        setA11yEnabled(isVoiceOverRunning());
    });
    return isA11yEnabled();
}
export function getAndroidAccessibilityManager() {
    return null;
}
let sharedA11YObservable;
let nativeObserver;
function getSharedA11YObservable() {
    if (sharedA11YObservable) {
        return sharedA11YObservable;
    }
    sharedA11YObservable = new SharedA11YObservable();
    let isVoiceOverRunning;
    if (typeof UIAccessibilityIsVoiceOverRunning === 'function') {
        isVoiceOverRunning = UIAccessibilityIsVoiceOverRunning;
    }
    else {
        if (typeof UIAccessibilityIsVoiceOverRunning !== 'function') {
            Trace.write(`UIAccessibilityIsVoiceOverRunning() - is not a function`, Trace.categories.Accessibility, Trace.messageType.error);
            isVoiceOverRunning = () => false;
        }
    }
    sharedA11YObservable.set(AccessibilityServiceEnabledPropName, isVoiceOverRunning());
    let voiceOverStatusChangedNotificationName = null;
    if (typeof UIAccessibilityVoiceOverStatusDidChangeNotification !== 'undefined') {
        // iOS 11+
        voiceOverStatusChangedNotificationName = UIAccessibilityVoiceOverStatusDidChangeNotification;
    }
    else if (typeof UIAccessibilityVoiceOverStatusChanged !== 'undefined') {
        // iOS <11
        voiceOverStatusChangedNotificationName = UIAccessibilityVoiceOverStatusChanged;
    }
    if (voiceOverStatusChangedNotificationName) {
        nativeObserver = Application.ios.addNotificationObserver(voiceOverStatusChangedNotificationName, () => {
            sharedA11YObservable?.set(AccessibilityServiceEnabledPropName, isVoiceOverRunning());
        });
        Application.on(Application.exitEvent, () => {
            if (nativeObserver) {
                Application.ios.removeNotificationObserver(nativeObserver, voiceOverStatusChangedNotificationName);
            }
            nativeObserver = null;
            if (sharedA11YObservable) {
                sharedA11YObservable.removeEventListener(Observable.propertyChangeEvent);
                sharedA11YObservable = null;
            }
        });
    }
    Application.on(Application.resumeEvent, () => sharedA11YObservable.set(AccessibilityServiceEnabledPropName, isVoiceOverRunning()));
    return sharedA11YObservable;
}
export class AccessibilityServiceEnabledObservable extends CommonA11YServiceEnabledObservable {
    constructor() {
        super(getSharedA11YObservable());
    }
}
let accessibilityServiceObservable;
export function ensureA11yClasses() {
    if (accessibilityServiceObservable) {
        return;
    }
    setFontScaleCssClasses(new Map(VALID_FONT_SCALES.map((fs) => [fs, `a11y-fontscale-${Number(fs * 100).toFixed(0)}`])));
    accessibilityServiceObservable = new AccessibilityServiceEnabledObservable();
}
export function updateCurrentHelperClasses(applyRootCssClass) {
    const fontScale = getFontScale();
    const fontScaleCategory = getFontScaleCategory();
    const fontScaleCssClasses = getFontScaleCssClasses();
    const oldFontScaleClass = getCurrentFontScaleClass();
    if (fontScaleCssClasses.has(fontScale)) {
        setCurrentFontScaleClass(fontScaleCssClasses.get(fontScale));
    }
    else {
        setCurrentFontScaleClass(fontScaleCssClasses.get(1));
    }
    if (oldFontScaleClass !== getCurrentFontScaleClass()) {
        applyRootCssClass([...fontScaleCssClasses.values()], getCurrentFontScaleClass());
    }
    const oldActiveFontScaleCategory = getCurrentFontScaleCategory();
    switch (fontScaleCategory) {
        case FontScaleCategory.ExtraSmall: {
            setCurrentFontScaleCategory(fontScaleExtraSmallCategoryClass);
            break;
        }
        case FontScaleCategory.Medium: {
            setCurrentFontScaleCategory(fontScaleMediumCategoryClass);
            break;
        }
        case FontScaleCategory.ExtraLarge: {
            setCurrentFontScaleCategory(fontScaleExtraLargeCategoryClass);
            break;
        }
        default: {
            setCurrentFontScaleCategory(fontScaleMediumCategoryClass);
            break;
        }
    }
    if (oldActiveFontScaleCategory !== getCurrentFontScaleCategory()) {
        applyRootCssClass(fontScaleCategoryClasses, getCurrentFontScaleCategory());
    }
    const oldA11YStatusClass = getCurrentA11YServiceClass();
    if (accessibilityServiceObservable.accessibilityServiceEnabled) {
        setCurrentA11YServiceClass(a11yServiceEnabledClass);
    }
    else {
        setCurrentA11YServiceClass(a11yServiceDisabledClass);
    }
    if (oldA11YStatusClass !== getCurrentA11YServiceClass()) {
        applyRootCssClass(a11yServiceClasses, getCurrentA11YServiceClass());
    }
}
function applyRootCssClass(cssClasses, newCssClass) {
    const rootView = Application.getRootView();
    if (!rootView) {
        return;
    }
    Application.applyCssClass(rootView, cssClasses, newCssClass);
    const rootModalViews = rootView._getRootModalViews();
    rootModalViews.forEach((rootModalView) => Application.applyCssClass(rootModalView, cssClasses, newCssClass));
}
function applyFontScaleToRootViews() {
    const rootView = Application.getRootView();
    if (!rootView) {
        return;
    }
    const fontScale = getCurrentFontScale();
    rootView.style.fontScaleInternal = fontScale;
    const rootModalViews = rootView._getRootModalViews();
    rootModalViews.forEach((rootModalView) => (rootModalView.style.fontScaleInternal = fontScale));
}
export function initAccessibilityCssHelper() {
    ensureA11yClasses();
    updateCurrentHelperClasses(applyRootCssClass);
    applyFontScaleToRootViews();
    Application.on(Application.fontScaleChangedEvent, () => {
        updateCurrentHelperClasses(applyRootCssClass);
        applyFontScaleToRootViews();
    });
    accessibilityServiceObservable.on(AccessibilityServiceEnabledObservable.propertyChangeEvent, () => updateCurrentHelperClasses(applyRootCssClass));
}
setInitAccessibilityCssHelper(initAccessibilityCssHelper);
const applicationEvents = [Application.orientationChangedEvent, Application.systemAppearanceChangedEvent];
function toggleApplicationEventListeners(toAdd, callback) {
    for (const eventName of applicationEvents) {
        if (toAdd) {
            Application.on(eventName, callback);
        }
        else {
            Application.off(eventName, callback);
        }
    }
}
setToggleApplicationEventListenersCallback(toggleApplicationEventListeners);
setApplicationPropertiesCallback(() => {
    return {
        orientation: Application.orientation(),
        systemAppearance: Application.systemAppearance(),
    };
});
//# sourceMappingURL=application.ios.js.map