diff --git a/airborne-react-native/android/src/main/java/in/juspay/airborneplugin/Airborne.kt b/airborne-react-native/android/src/main/java/in/juspay/airborneplugin/Airborne.kt index b77c267e..0ff8819b 100644 --- a/airborne-react-native/android/src/main/java/in/juspay/airborneplugin/Airborne.kt +++ b/airborne-react-native/android/src/main/java/in/juspay/airborneplugin/Airborne.kt @@ -1,6 +1,8 @@ package `in`.juspay.airborneplugin import android.content.Context +import android.content.pm.PackageManager +import android.os.Build import androidx.annotation.Keep import `in`.juspay.airborne.HyperOTAServices import `in`.juspay.airborne.LazyDownloadCallback @@ -46,14 +48,31 @@ class Airborne( } } - private val hyperOTAServices = HyperOTAServices( - context, - airborneInterface.getNamespace(), - "", - releaseConfigUrl, - trackerCallback, - this::bootComplete - ) + private val hyperOTAServices = run { + val appVersion = try { + val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + context.packageManager.getPackageInfo( + context.packageName, + PackageManager.PackageInfoFlags.of(0) + ) + } else { + @Suppress("DEPRECATION") + context.packageManager.getPackageInfo(context.packageName, 0) + } + packageInfo.versionName ?: "" + } catch (_: Exception) { + "" + } + + HyperOTAServices( + context, + airborneInterface.getNamespace(), + appVersion, + releaseConfigUrl, + trackerCallback, + this::bootComplete + ) + } private val applicationManager = hyperOTAServices.createApplicationManager(airborneInterface.getDimensions()) diff --git a/airborne-react-native/ios/AirborneReact.mm b/airborne-react-native/ios/AirborneReact.mm index 8025632d..cd4a62af 100644 --- a/airborne-react-native/ios/AirborneReact.mm +++ b/airborne-react-native/ios/AirborneReact.mm @@ -1,8 +1,6 @@ #import "AirborneReact.h" #import "Airborne.h" #import -#import -#import #import @implementation AirborneReact diff --git a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManager.swift b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManager.swift index 4840e358..344b2142 100644 --- a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManager.swift +++ b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManager.swift @@ -276,6 +276,22 @@ public typealias AJPReleaseConfigCompletionHandler = (AJPApplicationManifest?, E } self.utils = AJPApplicationManagerUtils(fileUtil: self.fileUtil, tracker: self.tracker, remoteFileUtil: self.remoteFileUtil) + + let majorVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" + let minorVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" + let appVersion = "\(majorVersion).\(minorVersion)" + + let storedVersion = UserDefaults.standard.string(forKey: AJPApplicationConstants.APP_VERSION_USER_DEFAULTS_KEY) + if let storedVersion = storedVersion, storedVersion != appVersion { + self.utils.cleanupManifestDirectory() + self.utils.cleanupPackageDirectory() + let cleanupLog = NSMutableDictionary() + cleanupLog["previous_version"] = storedVersion + cleanupLog["current_version"] = appVersion + self.tracker.trackInfo("app_version_changed_cleanup", value: cleanupLog) + } + + UserDefaults.standard.set(appVersion, forKey: AJPApplicationConstants.APP_VERSION_USER_DEFAULTS_KEY) // Handle if any previously downloaded packages are available. self.handleTempPackageInstallation() diff --git a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManagerUtils.swift b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManagerUtils.swift index da20c6ed..42c064f4 100644 --- a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManagerUtils.swift +++ b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwift/AJPApplicationManagerUtils.swift @@ -48,7 +48,15 @@ class AJPApplicationManagerUtils { try? fileManager.removeItem(atPath: tempDirPath) } } - + + func cleanupPackageDirectory() { + fileUtil.cleanupEntireDirectory(AJPApplicationConstants.JUSPAY_PACKAGE_DIR) + } + + func cleanupManifestDirectory() { + fileUtil.cleanupEntireDirectory(AJPApplicationConstants.JUSPAY_MANIFEST_DIR) + } + // MARK: - File System Helpers func getAllFilesInDirectory(_ directory: String, subFolder: String, includeSubfolders: Bool) -> [String] { diff --git a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftCore/AJPFileUtil.swift b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftCore/AJPFileUtil.swift index eca1f914..fb89ffde 100644 --- a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftCore/AJPFileUtil.swift +++ b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftCore/AJPFileUtil.swift @@ -246,4 +246,22 @@ import Foundation let path = fullPathInStorageForFilePath(fileName, inFolder: folder) try FileManager.default.removeItem(atPath: path) } + + /// Removes an entire top-level directory from the application's Library folder. + /// Unlike workspace-scoped deletions, this does not insert the workspace segment. + /// - Parameter dirName: The name of the directory to remove (e.g. "JuspayManifests"). + @objc public func cleanupEntireDirectory(_ dirName: String) { + let paths = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true) + guard var rootPath = paths.first else { return } + + let subPaths = dirName.components(separatedBy: "/") + for subPath in subPaths { + rootPath = (rootPath as NSString).appendingPathComponent(subPath) + } + + let fileManager = FileManager.default + if fileManager.fileExists(atPath: rootPath) { + try? fileManager.removeItem(atPath: rootPath) + } + } } diff --git a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftModel/AJPApplicationConstants.swift b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftModel/AJPApplicationConstants.swift index c6adff1a..829f86ef 100644 --- a/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftModel/AJPApplicationConstants.swift +++ b/airborne_sdk_iOS/hyper-ota/Airborne/AirborneSwiftModel/AJPApplicationConstants.swift @@ -35,6 +35,9 @@ import Foundation public static let RELEASE_CONFIG_TIMEOUT_NOTIFICATION = Notification.Name("AJPReleaseConfigTimeoutNotification") public static let LAZY_PACKAGE_NOTIFICATION = Notification.Name("AJPLazyPackageNotification") + // MARK: - UserDefaults Keys + public static let APP_VERSION_USER_DEFAULTS_KEY = "in.juspay.airborne.appVersion" + // MARK: - Misc public static let APPL_MANAGER_SUB_CAT = "hyperota" }