import Foundation import Capacitor @objc(AppPlugin) public class AppPlugin: CAPPlugin, CAPBridgedPlugin { public let identifier = "AppPlugin" public let jsName = "App" public let pluginMethods: [CAPPluginMethod] = [ CAPPluginMethod(name: "exitApp", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "getInfo", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "getLaunchUrl", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "getState", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "minimizeApp", returnType: CAPPluginReturnPromise) ] private var observers: [NSObjectProtocol] = [] override public func load() { NotificationCenter.default.addObserver(self, selector: #selector(self.handleUrlOpened(notification:)), name: Notification.Name.capacitorOpenURL, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.handleUniversalLink(notification:)), name: Notification.Name.capacitorOpenUniversalLink, object: nil) observers.append(NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: OperationQueue.main) { [weak self] (_) in self?.notifyListeners("appStateChange", data: [ "isActive": true ]) }) observers.append(NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: OperationQueue.main) { [weak self] (_) in self?.notifyListeners("appStateChange", data: [ "isActive": false ]) }) observers.append(NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: OperationQueue.main) { [weak self] (_) in self?.notifyListeners("pause", data: nil) }) observers.append(NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: OperationQueue.main) { [weak self] (_) in self?.notifyListeners("resume", data: nil) }) } deinit { NotificationCenter.default.removeObserver(self) for observer in observers { NotificationCenter.default.removeObserver(observer) } } @objc func handleUrlOpened(notification: NSNotification) { guard let object = notification.object as? [String: Any?] else { return } notifyListeners("appUrlOpen", data: makeUrlOpenObject(object), retainUntilConsumed: true) } @objc func handleUniversalLink(notification: NSNotification) { guard let object = notification.object as? [String: Any?] else { return } notifyListeners("appUrlOpen", data: makeUrlOpenObject(object), retainUntilConsumed: true) } func makeUrlOpenObject(_ object: [String: Any?]) -> JSObject { guard let url = object["url"] as? NSURL else { return [:] } let options = object["options"] as? [String: Any?] ?? [:] return [ "url": url.absoluteString ?? "", "iosSourceApplication": options[UIApplication.OpenURLOptionsKey.sourceApplication.rawValue] as? String ?? "", "iosOpenInPlace": options[UIApplication.OpenURLOptionsKey.openInPlace.rawValue] as? String ?? "" ] } @objc func exitApp(_ call: CAPPluginCall) { call.unimplemented() } @objc func getInfo(_ call: CAPPluginCall) { if let info = Bundle.main.infoDictionary { call.resolve([ "name": info["CFBundleDisplayName"] as? String ?? "", "id": info["CFBundleIdentifier"] as? String ?? "", "build": info["CFBundleVersion"] as? String ?? "", "version": info["CFBundleShortVersionString"] as? String ?? "" ]) } else { call.reject("Unable to get App Info") } } @objc func getLaunchUrl(_ call: CAPPluginCall) { if let lastUrl = ApplicationDelegateProxy.shared.lastURL { let urlValue = lastUrl.absoluteString call.resolve([ "url": urlValue ]) } call.resolve() } @objc func getState(_ call: CAPPluginCall) { DispatchQueue.main.async { call.resolve([ "isActive": UIApplication.shared.applicationState == UIApplication.State.active ]) } } @objc func minimizeApp(_ call: CAPPluginCall) { call.unimplemented() } }