### Perform Minimal Setup Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Integrate the basic update check within the application lifecycle methods. ```swift import Siren // In AppDelegate.swift or SceneDelegate.swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Siren.shared.wail() window?.makeKeyAndVisible() return true } ``` -------------------------------- ### AppStoreCountry Initialization Examples Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Demonstrates creating instances using raw strings, case-insensitive inputs, and nil defaults. ```swift let us = AppStoreCountry(code: "US") let japan = AppStoreCountry(code: "jp") // Case-insensitive let custom = AppStoreCountry(code: nil) // Defaults to US ``` -------------------------------- ### Configure PresentationManager instances Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Examples showing default initialization, custom tinting, forced localization, and full text overrides. ```swift // Default presentation let manager = PresentationManager() // Custom tint color and app name let manager = PresentationManager( alertTintColor: UIColor(red: 0.2, green: 0.8, blue: 0.4, alpha: 1.0), appName: "MyAwesomeApp" ) // Force all strings to Japanese regardless of device locale let manager = PresentationManager( forceLanguageLocalization: .japanese ) // Fully custom English strings let manager = PresentationManager( alertTitle: "New Version Released", alertMessage: "%@ version %@ is now available. Update now?", updateButtonTitle: "Get Update", nextTimeButtonTitle: "Later", skipButtonTitle: "Never" ) Siren.shared.presentationManager = manager ``` -------------------------------- ### Configure Siren at Runtime Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Update rules and perform checks dynamically after initial setup. ```swift // Start with defaults Siren.shared.wail() // Later, change to force updates Siren.shared.rulesManager = RulesManager(globalRules: .critical) // Perform another check with new rules Siren.shared.wail(performCheck: .onDemand) ``` -------------------------------- ### Default Alert Message Example Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Example of the default alert message string generated by the PresentationManager. ```text "MyApp version 2.5.0 is now available. Would you like to update it now?" ``` -------------------------------- ### Example usage of performVersionCheckRequest Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Demonstrates calling the version check within an async Task and handling potential errors. ```swift Task { do { let apiModel = try await Siren.shared.apiManager.performVersionCheckRequest() print("Latest version: \(apiModel.results.first?.version ?? "unknown")") } catch let error as KnownError { print("API Error: \(error.localizedDescription)") } } ``` -------------------------------- ### Initiate Version Check Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Use the wail method to start the version checking process. The completion handler provides the result of the check or any encountered errors. ```swift import Siren // In AppDelegate.swift or SceneDelegate.swift Siren.shared.wail() { result in switch result { case .success(let updateResults): print("Update available: \(updateResults.model.version)") print("User action: \(updateResults.alertAction)") case .failure(let error): print("Version check failed: \(error.localizedDescription)") } } ``` -------------------------------- ### Install Siren via Swift Package Manager Source: https://github.com/artsabintsev/siren/blob/master/README.md Add this dependency to your Package.swift file to include Siren in your project. ```swift .package(url: "https://github.com/ArtSabintsev/Siren.git", from: "7.0.0") ``` -------------------------------- ### Customize Siren Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Configure update rules and API settings before initiating a check. This example demonstrates setting specific rules for different update types and targeting a specific App Store region. ```swift // Set update rules for different version types let rulesManager = RulesManager( majorUpdateRules: .critical, // Force major updates immediately minorUpdateRules: .annoying, // Prompt daily for minor updates patchUpdateRules: .default, // Prompt daily, allow skip revisionUpdateRules: .relaxed, // Prompt weekly, allow skip showAlertAfterCurrentVersionHasBeenReleasedForDays: 1 ) Siren.shared.rulesManager = rulesManager // Configure for a specific App Store region Siren.shared.apiManager = APIManager(country: .japan, language: "ja") // Check on demand only Siren.shared.wail(performCheck: .onDemand) ``` -------------------------------- ### Access Supported AppStoreCountry Constants Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Examples of static properties available on AppStoreCountry for specifying the target region. ```swift AppStoreCountry.unitedStates // US (default) AppStoreCountry.japan // JP AppStoreCountry.germany // DE AppStoreCountry.france // FR AppStoreCountry.unitedKingdom // GB AppStoreCountry.china // CN AppStoreCountry.india // IN // ... 170+ more ``` -------------------------------- ### Access AppStoreCountry Constants Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md Examples of accessing predefined country constants for App Store region configuration. ```swift AppStoreCountry.unitedStates // "US" AppStoreCountry.japan // "JP" AppStoreCountry.germany // "DE" AppStoreCountry.france // "FR" AppStoreCountry.unitedKingdom // "GB" AppStoreCountry.china // "CN" AppStoreCountry.india // "IN" AppStoreCountry.australia // "AU" AppStoreCountry.canada // "CA" AppStoreCountry.mexico // "MX" // ... and 170 more ``` -------------------------------- ### GET https://itunes.apple.com/lookup Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Constructs a request to the iTunes Lookup API to retrieve app metadata based on the provided bundle ID and regional settings. ```APIDOC ## GET https://itunes.apple.com/lookup ### Description Constructs an HTTPS URL to query the iTunes App Store for application metadata. ### Method GET ### Endpoint https://itunes.apple.com/lookup ### Parameters #### Query Parameters - **bundleId** (string) - Required - The app's Bundle ID. - **country** (string) - Optional - The country code (defaults to US). - **lang** (string) - Optional - The language code (IETF language tag). - **entity** (string) - Optional - Set to 'tvSoftware' on tvOS, omitted on iOS. ### Request Example https://itunes.apple.com/lookup?bundleId=com.example.app&country=JP&lang=ja ``` -------------------------------- ### Constructed iTunes Lookup URL Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Example of a generated HTTPS URL for the iTunes lookup service including bundle ID, country, and language parameters. ```text https://itunes.apple.com/lookup?bundleId=com.example.app&country=JP&lang=ja ``` -------------------------------- ### Initialize APIManager with various configurations Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Demonstrates creating instances with default settings, specific regions and languages, or custom bundle IDs. ```swift // Default: US App Store, English language let manager = APIManager() // Japanese App Store, Japanese language let manager = APIManager(country: .japan, language: "ja") // German App Store, German language let manager = APIManager(country: .germany, language: "de") // Custom bundle ID for testing let manager = APIManager(bundleID: "com.example.testapp") ``` -------------------------------- ### Initialize Siren and Launch App Store Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md The primary entry points for checking for updates and opening the App Store. ```swift Siren.shared.wail(performCheck: .onForeground, completion: handler) Siren.shared.launchAppStore() ``` -------------------------------- ### init(code:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Initializes a new AppStoreCountry instance using a two-letter ISO country code string. ```APIDOC ## init(code:) ### Description Creates an AppStoreCountry instance from a raw country code. If the code is nil, it defaults to US behavior. ### Signature `public init(code: String?)` ### Parameters - **code** (String?) - Optional - Two-letter ISO country code. Case-insensitive (internally normalized to uppercase). ### Example ```swift let us = AppStoreCountry(code: "US") let japan = AppStoreCountry(code: "jp") let custom = AppStoreCountry(code: nil) ``` ``` -------------------------------- ### init(alertTintColor:appName:alertTitle:alertMessage:updateButtonTitle:nextTimeButtonTitle:skipButtonTitle:forceLanguageLocalization:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Initializes a new PresentationManager instance with optional custom configurations for alert UI and text. ```APIDOC ## init(alertTintColor:appName:alertTitle:alertMessage:updateButtonTitle:nextTimeButtonTitle:skipButtonTitle:forceLanguageLocalization:) ### Description Creates a customized PresentationManager with optional overrides for all text and appearance settings used in update alerts. ### Signature `public init(alertTintColor: UIColor? = nil, appName: String? = nil, alertTitle: String = AlertConstants.alertTitle, alertMessage: String = AlertConstants.alertMessage, updateButtonTitle: String = AlertConstants.updateButtonTitle, nextTimeButtonTitle: String = AlertConstants.nextTimeButtonTitle, skipButtonTitle: String = AlertConstants.skipButtonTitle, forceLanguageLocalization forceLanguage: Localization.Language? = nil)` ### Parameters - **alertTintColor** (UIColor?) - Optional - The tint color for alert buttons and interactive elements. - **appName** (String?) - Optional - Override app name used in alert text. - **alertTitle** (String) - Optional - The main alert title text. - **alertMessage** (String) - Optional - The alert message body. - **updateButtonTitle** (String) - Optional - "Update" button text. - **nextTimeButtonTitle** (String) - Optional - "Next time" button text. - **skipButtonTitle** (String) - Optional - "Skip this version" button text. - **forceLanguageLocalization** (Localization.Language?) - Optional - Force alert strings to a specific language. ``` -------------------------------- ### Initialize APIManager with full configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Defines the initializer signature for configuring country, language, and bundle ID. ```swift public init(country: AppStoreCountry = .unitedStates, language: String? = nil, bundleID: String? = Bundle.main.bundleIdentifier) ``` -------------------------------- ### init(country:language:bundleID:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Initializes an APIManager instance with specific configuration for the App Store region, language, and bundle identifier. ```APIDOC ## init(country:language:bundleID:) ### Description Creates an APIManager with full configuration for querying the iTunes Lookup API. ### Signature `public init(country: AppStoreCountry = .unitedStates, language: String? = nil, bundleID: String? = Bundle.main.bundleIdentifier)` ### Parameters - **country** (AppStoreCountry) - Optional - The App Store region to query. Defaults to .unitedStates. - **language** (String?) - Optional - Optional language code for API response localization. Defaults to nil. - **bundleID** (String?) - Optional - The app's Bundle ID. Defaults to the main app bundle. ``` -------------------------------- ### init(countryCode:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Convenience initializer for APIManager that accepts a raw ISO country code string. ```APIDOC ## init(countryCode:) ### Description Creates an APIManager instance using a two-letter ISO country code string. ### Signature `public init(countryCode: String?)` ### Parameters - **countryCode** (String?) - Optional - Two-letter ISO country code (e.g., "US", "JP"). Defaults to US App Store if nil. ``` -------------------------------- ### init(majorUpdateRules:minorUpdateRules:patchUpdateRules:revisionUpdateRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/rules-manager.md Initializes a RulesManager with specific rules for each update type and a release delay. ```APIDOC ## init(majorUpdateRules:minorUpdateRules:patchUpdateRules:revisionUpdateRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:) ### Description Creates a RulesManager instance with separate rules for major, minor, patch, and revision version changes, along with a release delay period. ### Parameters - **majorUpdateRules** (Rules) - Optional - Rules for major version changes (default: .default) - **minorUpdateRules** (Rules) - Optional - Rules for minor version changes (default: .default) - **patchUpdateRules** (Rules) - Optional - Rules for patch version changes (default: .default) - **revisionUpdateRules** (Rules) - Optional - Rules for revision version changes (default: .default) - **showAlertAfterCurrentVersionHasBeenReleasedForDays** (Int) - Optional - Days to wait after release before prompting (default: 1) ``` -------------------------------- ### Siren.shared.launchAppStore Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Directly opens the App Store page for the application. ```APIDOC ## Siren.shared.launchAppStore() ### Description Forces the application to open the App Store page for the current app. ``` -------------------------------- ### init(globalRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/rules-manager.md Initializes a RulesManager with a single set of rules applied to all update types. ```APIDOC ## init(globalRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:) ### Description Creates a RulesManager instance where the same rules are applied to all four update types (major, minor, patch, revision). ### Parameters - **globalRules** (Rules) - Optional - The Rules to apply to all update types (default: .default) - **showAlertAfterCurrentVersionHasBeenReleasedForDays** (Int) - Optional - Days to wait after release before prompting (default: 1) ``` -------------------------------- ### Initialize AppStoreCountry Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Constructor for creating an instance with a specific ISO country code. ```swift public init(code: String?) ``` -------------------------------- ### Initialize PresentationManager Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md The initializer signature for configuring alert appearance and text overrides. ```swift public init(alertTintColor tintColor: UIColor? = nil, appName: String? = nil, alertTitle: String = AlertConstants.alertTitle, alertMessage: String = AlertConstants.alertMessage, updateButtonTitle: String = AlertConstants.updateButtonTitle, nextTimeButtonTitle: String = AlertConstants.nextTimeButtonTitle, skipButtonTitle: String = AlertConstants.skipButtonTitle, forceLanguageLocalization forceLanguage: Localization.Language? = nil) ``` -------------------------------- ### Initialize APIManager using country code string Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Demonstrates creating an instance using a two-letter ISO country code. ```swift // Using country code string let manager = APIManager(countryCode: "FR") ``` -------------------------------- ### Initialize RulesManager with specific rules Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/rules-manager.md Configures distinct update rules for each version component and sets a global delay for prompt activation. ```swift public init(majorUpdateRules: Rules = .default, minorUpdateRules: Rules = .default, patchUpdateRules: Rules = .default, revisionUpdateRules: Rules = .default, showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1) ``` ```swift let rulesManager = RulesManager( majorUpdateRules: .critical, // Force major updates immediately minorUpdateRules: .persistent, // Daily prompt for minor updates patchUpdateRules: .relaxed, // Weekly prompt for patches revisionUpdateRules: .hinting, // Weekly prompt for revisions showAlertAfterCurrentVersionHasBeenReleasedForDays: 3 ) Siren.shared.rulesManager = rulesManager ``` -------------------------------- ### APIManager Initialization Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Configuring the APIManager with specific country and language settings. ```APIDOC ## APIManager(country:language:) ### Description Initializes the APIManager to query a specific App Store country and optionally define the language for returned metadata. ### Parameters - **country** (AppStoreCountry) - Required - The ISO 3166-1 two-letter country code for the App Store to query. - **language** (String?) - Optional - The language code for returned metadata (e.g., "ja"). If nil, defaults to English. ### Example ```swift // Query Japanese App Store, return Japanese metadata Siren.shared.apiManager = APIManager( country: .japan, language: "ja" ) ``` ``` -------------------------------- ### Siren.shared.wail() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Initializes the version check process using the shared singleton instance. ```APIDOC ## Siren.shared.wail() ### Description Initiates the version check process. This method should be called on the shared Siren instance to check for app updates. ### Signature `func wail(completion: ResultsHandler? = nil)` ### Parameters - **completion** (ResultsHandler) - Optional - A closure that receives a Result containing either UpdateResults or a KnownError. ``` -------------------------------- ### Siren.launchAppStore() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Manually launches the App Store to the app's update page. This is typically called automatically by Siren's alerts but can be invoked manually for custom implementations. ```APIDOC ## launchAppStore() ### Description Launches the App Store to the app's update page. Opens the App Store app (or browser if unavailable) to the app's page using the app ID retrieved from the iTunes Lookup API. ### Example ```swift Siren.shared.launchAppStore() ``` ``` -------------------------------- ### Apply Custom Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Customize update rules, API region, and alert appearance before triggering an on-demand update check. ```swift // Different rules for different update types Siren.shared.rulesManager = RulesManager( majorUpdateRules: .critical, minorUpdateRules: .annoying, patchUpdateRules: .default, revisionUpdateRules: .relaxed ) // Query a specific App Store region Siren.shared.apiManager = APIManager(country: .japan, language: "ja") // Customize appearance Siren.shared.presentationManager = PresentationManager( alertTintColor: UIColor.systemBlue, appName: "MyApp", forceLanguageLocalization: .spanish ) // Check for updates Siren.shared.wail(performCheck: .onDemand) ``` -------------------------------- ### Initialize APIManager with country code string Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Defines the convenience initializer signature using a raw country code string. ```swift public init(countryCode: String?) ``` -------------------------------- ### Configure Manager Types Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Use default static properties or custom initializers to configure API, Rules, and Presentation managers. ```swift APIManager.default APIManager(country: .japan, language: "ja") RulesManager.default RulesManager(globalRules: .critical, showAlertAfterCurrentVersionHasBeenReleasedForDays: 1) PresentationManager.default PresentationManager(alertTintColor: .systemBlue, forceLanguageLocalization: .spanish) ``` -------------------------------- ### Configure predefined global update rules Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Applies specific update strategies ranging from critical forced updates to gentle weekly nudges. ```swift Siren.shared.rulesManager = RulesManager( globalRules: .critical, showAlertAfterCurrentVersionHasBeenReleasedForDays: 0 ) // AlertType: .force (1 button: Update) // Frequency: .immediately (every launch) ``` ```swift Siren.shared.rulesManager = RulesManager( globalRules: .annoying, showAlertAfterCurrentVersionHasBeenReleasedForDays: 1 ) // AlertType: .option (2 buttons: Next Time, Update) // Frequency: .immediately ``` ```swift Siren.shared.rulesManager = RulesManager( globalRules: .default ) // AlertType: .skip (3 buttons: Update, Next Time, Skip) // Frequency: .daily (once per 24 hours) ``` ```swift Siren.shared.rulesManager = RulesManager( globalRules: .hinting ) // AlertType: .option // Frequency: .weekly (once per 7 days) ``` -------------------------------- ### Compare AppStoreCountry instances Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Demonstrates equality comparison for AppStoreCountry, which is case-insensitive. ```swift AppStoreCountry.japan == AppStoreCountry(code: "JP") // true AppStoreCountry.japan == AppStoreCountry(code: "jp") // true (case-insensitive) AppStoreCountry.japan == AppStoreCountry.china // false ``` -------------------------------- ### Initialize RulesManager with global rules Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/rules-manager.md Applies a single set of rules to all update types simultaneously. ```swift public init(globalRules rules: Rules = .default, showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1) ``` ```swift // All updates prompt daily and allow skip let rulesManager = RulesManager(globalRules: .default) // All updates force update immediately let rulesManager = RulesManager(globalRules: .critical) // All updates prompt immediately but allow next-time/skip let rulesManager = RulesManager(globalRules: .annoying) ``` -------------------------------- ### String Literal Initializer Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Allows direct assignment of a string literal to an AppStoreCountry variable. ```APIDOC ## String Literal Initializer ### Description AppStoreCountry conforms to ExpressibleByStringLiteral, enabling direct assignment from string literals for convenience. ### Example ```swift let germany: AppStoreCountry = "DE" let brazil: AppStoreCountry = "BR" ``` ``` -------------------------------- ### Initialize AppStoreCountry with string literals Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Creates country instances directly from string literals for use in the APIManager. ```swift // Create country from string literal let uk: AppStoreCountry = "GB" let france: AppStoreCountry = "FR" Siren.shared.apiManager = APIManager(country: france) ``` -------------------------------- ### Accessing the Default PresentationManager Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md The default instance uses system defaults for tint color, app name, and localization. This instance is utilized by Siren when no custom manager is provided. ```swift public static let `default` = PresentationManager() ``` -------------------------------- ### Comprehensive PresentationManager Customization Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Applies multiple custom settings simultaneously to the PresentationManager. ```swift Siren.shared.presentationManager = PresentationManager( alertTintColor: UIColor.systemGreen, appName: "ProApp", alertTitle: "Update Available", alertMessage: "%@ has released version %@. Install now?", updateButtonTitle: "Install", nextTimeButtonTitle: "Later", skipButtonTitle: "No Thanks", forceLanguageLocalization: nil // Use device locale ) ``` -------------------------------- ### Configure Siren in AppDelegate Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Initializes Siren with custom API, rules, and presentation managers within the application lifecycle. ```swift import Siren import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Configure for Brazilian Portuguese App Store with Portuguese language Siren.shared.apiManager = APIManager( country: .brazil, language: "pt-BR" ) // Different rules per update type Siren.shared.rulesManager = RulesManager( majorUpdateRules: .critical, // Force major immediately minorUpdateRules: .annoying, // Prompt daily, allow next-time patchUpdateRules: .default, // Prompt daily, allow skip revisionUpdateRules: .relaxed, // Prompt weekly, allow skip showAlertAfterCurrentVersionHasBeenReleasedForDays: 1 ) // Custom appearance and localization Siren.shared.presentationManager = PresentationManager( alertTintColor: UIColor.systemBlue, appName: "MyProApp", forceLanguageLocalization: .portugueseBrazil ) // Start checking for updates Siren.shared.wail(performCheck: .onForeground) { result in switch result { case .success(let updateResults): print("Update available: \(updateResults.model.version)") case .failure(let error as KnownError): switch error { case .noUpdateAvailable: print("App is current") case .recentlyPrompted: print("Already prompted user recently") default: print("Update check error: \(error.localizedDescription)") } } } window?.makeKeyAndVisible() return true } } ``` -------------------------------- ### Localization Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md A structure for managing string localization and language configuration for update alerts, supporting 40+ languages. ```APIDOC ## Localization ### Description Provides localized strings for alert UI components. Automatically detects device language and defaults to English if unsupported. ### Methods - **alertTitle()** -> String: Returns localized "Update Available" text. - **alertMessage(forCurrentAppStoreVersion: String)** -> String: Returns localized message with app name and version interpolated. - **updateButtonTitle()** -> String: Returns localized "Update" button text. - **nextTimeButtonTitle()** -> String: Returns localized "Next Time" button text. - **skipButtonTitle()** -> String: Returns localized "Skip this version" button text. ``` -------------------------------- ### Define Localization structure Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md Interface for handling localized alert strings and language configuration. ```swift public struct Localization { public enum Language: String { ... } public func alertTitle() -> String public func alertMessage(forCurrentAppStoreVersion: String) -> String public func updateButtonTitle() -> String public func nextTimeButtonTitle() -> String public func skipButtonTitle() -> String } ``` -------------------------------- ### Compare Country Codes Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Demonstrates that country code initialization is case-insensitive. ```swift AppStoreCountry(code: "us") == AppStoreCountry(code: "US") // true ``` -------------------------------- ### Configure APIManager for Testing Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Use a known bundle ID to test update prompts without requiring a published app update. ```swift Siren.shared.apiManager = APIManager(bundleID: "com.facebook.Facebook") ``` -------------------------------- ### Configure Custom Localization in Swift Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Use PresentationManager to force a specific language or provide custom alert strings for the update prompt. ```swift import Siren // Force Spanish strings for all users Siren.shared.presentationManager = PresentationManager( forceLanguageLocalization: .spanish ) // Custom French strings Siren.shared.presentationManager = PresentationManager( alertTitle: "Mise à jour disponible", alertMessage: "La version %@ de %@ est désormais disponible.", updateButtonTitle: "Mettre à jour", nextTimeButtonTitle: "Plus tard", skipButtonTitle: "Ignorer", forceLanguageLocalization: .french ) ``` -------------------------------- ### Set Default PresentationManager Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Applies the default configuration using system tint color and app name from Info.plist. ```swift Siren.shared.presentationManager = PresentationManager.default // System tint color (blue), app name from Info.plist // Localized to device's preferred language (or English) ``` -------------------------------- ### Perform version check request Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md This async method retrieves and decodes app metadata from the iTunes Lookup API. ```swift func performVersionCheckRequest() async throws -> APIModel ``` -------------------------------- ### Initialize Siren via Singleton Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Access the Siren instance using the shared property. Avoid manual instantiation via Siren(). ```swift let siren = Siren.shared siren.wail() ``` -------------------------------- ### Access the default APIManager Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md The default instance queries the US App Store with English language settings. ```swift public static let `default` = APIManager() ``` -------------------------------- ### presentAlert(withRules:forCurrentAppStoreVersion:completion:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Constructs and presents the update alert UIAlertController based on the provided rules and App Store version. ```APIDOC ## presentAlert(withRules:forCurrentAppStoreVersion:completion:) ### Description Constructs and presents the update alert UIAlertController. If an alert is already on-screen, this method does nothing to prevent duplicate alerts. ### Signature `func presentAlert(withRules rules: Rules, forCurrentAppStoreVersion currentAppStoreVersion: String, completion handler: CompletionHandler?)` ### Parameters - **rules** (Rules) - Required - The Rules object that determines alert button configuration and behavior. - **currentAppStoreVersion** (String) - Required - The latest version available on the App Store (e.g., "2.5.0"). - **handler** ((AlertAction, String?) -> Void) - Optional - Completion handler called when user taps a button or alert is dismissed. ### Returns - **Void** ``` -------------------------------- ### Integrate Siren in AppDelegate Source: https://github.com/artsabintsev/siren/blob/master/README.md Initialize the update check by calling Siren.shared.wail() inside the didFinishLaunchingWithOptions method. ```swift import Siren // Line 1 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { window?.makeKeyAndVisible() Siren.shared.wail() // Line 2 return true } } ``` -------------------------------- ### Configure Custom Tint Color Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Sets a custom tint color for alert buttons. ```swift Siren.shared.presentationManager = PresentationManager( alertTintColor: UIColor(red: 0.2, green: 0.8, blue: 0.4, alpha: 1.0) ) // Green tint for buttons ``` -------------------------------- ### Configure release delay Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Sets the number of days to wait after a version release before prompting, ensuring the binary is available on all App Store CDNs. ```swift // 0 days: Prompt immediately (risky with .force) RulesManager(showAlertAfterCurrentVersionHasBeenReleasedForDays: 0) // 1 day: Prompt after 1 day (default, safe) RulesManager(showAlertAfterCurrentVersionHasBeenReleasedForDays: 1) // 3 days: For staged rollouts, wait 3 days RulesManager(showAlertAfterCurrentVersionHasBeenReleasedForDays: 3) // 7 days: For phased releases, wait for rollout to complete RulesManager(showAlertAfterCurrentVersionHasBeenReleasedForDays: 7) ``` -------------------------------- ### Configure Country and Language Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Distinguishes between the App Store region and the language used for returned metadata. ```swift // Query Japanese App Store, return English metadata Siren.shared.apiManager = APIManager( country: .japan, language: nil // English ) // Query Japanese App Store, return Japanese metadata Siren.shared.apiManager = APIManager( country: .japan, language: "ja" ) ``` -------------------------------- ### Presenting an Update Alert Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Constructs and displays a UIAlertController based on the provided rules and App Store version. If an alert is already visible, this method will not trigger a duplicate. ```swift func presentAlert(withRules rules: Rules, forCurrentAppStoreVersion currentAppStoreVersion: String, completion handler: CompletionHandler?) ``` -------------------------------- ### performVersionCheckRequest() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/api-manager.md Performs an asynchronous request to the iTunes Lookup API to retrieve app metadata. ```APIDOC ## performVersionCheckRequest() ### Description Performs an async request to the iTunes Lookup API and returns decoded version data. This method constructs a URL to the iTunes Lookup API endpoint with the configured country, language, and bundle ID, makes a URLRequest with a 30-second timeout, and decodes the JSON response. ### Signature `func performVersionCheckRequest() async throws -> APIModel` ### Returns - **APIModel** - The decoded iTunes Lookup API response containing app metadata including version, release date, minimum iOS version, and release notes. ### Throws - **KnownError.missingBundleID** - The bundleID property is nil. - **KnownError.malformedURL** - The constructed iTunes Lookup API URL is invalid. - **KnownError.appStoreDataRetrievalFailure(underlyingError:)** - Network request failed or no response data received. - **KnownError.appStoreJSONParsingFailure(underlyingError:)** - API response JSON could not be decoded into APIModel. - **KnownError.appStoreDataRetrievalEmptyResults** - API returned empty results array. ### Example ```swift Task { do { let apiModel = try await Siren.shared.apiManager.performVersionCheckRequest() print("Latest version: \(apiModel.results.first?.version ?? "unknown")") } catch let error as KnownError { print("API Error: \(error.localizedDescription)") } } ``` ``` -------------------------------- ### Manually Launch App Store Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Trigger the App Store update page manually. This is typically handled automatically by Siren's built-in alerts but can be invoked for custom UI implementations. ```swift // This is called automatically by Siren's built-in alerts. // For custom alerts, you can call it manually: if let model = updateResults?.model { Siren.shared.launchAppStore() } ``` -------------------------------- ### alertMessage(forCurrentAppStoreVersion:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Returns the localized alert message with app name and version interpolated. ```APIDOC ## alertMessage(forCurrentAppStoreVersion:) ### Description Returns the localized alert message with the app name and the provided version number interpolated. ### Signature `public func alertMessage(forCurrentAppStoreVersion currentAppStoreVersion: String) -> String` ### Parameters - **currentAppStoreVersion** (String) - Required - The App Store version number to interpolate (e.g., "2.5.0"). ### Returns - **String** - The localized message with format string applied. ``` -------------------------------- ### Manager Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Configures the behavior and appearance of the Siren update prompts. ```APIDOC ## Manager Configuration ### Description Use the following managers to customize update behavior: - **apiManager**: Configures App Store region and language. - **rulesManager**: Configures update prompt frequency and rules. - **presentationManager**: Customizes the appearance of the alert. ``` -------------------------------- ### Handle Update Results Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Implement a completion handler to process success or failure states during an update check. ```swift Siren.shared.wail { result in switch result { case .success(let updateResults): print("Update available: \(updateResults.model.version)") case .failure(let error): switch error { case .noUpdateAvailable: print("App is up-to-date") case .recentlyPrompted: print("Already prompted user recently") default: print("Error: \(error.localizedDescription)") } } } ``` -------------------------------- ### Rules Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md The Rules struct defines the alert presentation configuration, specifying the alert type and the frequency of update prompts. ```APIDOC ## Rules Configuration ### Description Defines the configuration for how and when update alerts are presented to the user. ### Fields - **alertType** (AlertType) - Required - The type of alert UI to present (force update, optional, allow skip, or none). - **frequency** (UpdatePromptFrequency) - Required - How often users are prompted (immediately, daily, or weekly). ### Predefined Presets - **.critical**: Prompt immediately, force update. - **.annoying**: Prompt immediately, allow next-time deferral. - **.default**: Prompt daily, allow skip or deferral. - **.persistent**: Prompt daily, allow next-time but not skip. - **.relaxed**: Prompt weekly, allow skip or deferral. - **.hinting**: Prompt weekly, allow next-time but not skip. ``` -------------------------------- ### Handle completion results Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Use a switch statement to handle success cases and differentiate between normal outcomes and actual errors. ```swift case .success(let results): // Update available and alert shown print("User action: \(results.alertAction)") case .failure(.noUpdateAvailable): // Normal: app is up-to-date break case .failure(.recentlyPrompted): // Normal: frequency rules suppress alert break case .failure(.appStoreDataRetrievalFailure): // Problem: network issue print("Network error") case .failure(.missingBundleID): // Problem: configuration issue print("Set Bundle ID in Xcode") case .failure(let error): // Handle other errors print("Error: \(error.localizedDescription)") ``` -------------------------------- ### Define PerformCheck Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md Configures the trigger mechanism for version checks, either manual or automatic on foreground. ```swift public enum PerformCheck { case onDemand // Check when wail() is called case onForeground // Check every time app enters foreground } ``` -------------------------------- ### alertTitle() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Returns the localized 'Update Available' title. ```APIDOC ## alertTitle() ### Description Returns the localized 'Update Available' title based on the device locale or forced language. ### Signature `public func alertTitle() -> String` ### Returns - **String** - The localized alert title. ``` -------------------------------- ### PresentationManager(forceLanguageLocalization:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Configures the localization behavior by forcing a specific language or reverting to the device's default locale. ```APIDOC ## PresentationManager(forceLanguageLocalization:) ### Description Overrides the device's locale and forces a specific language for all users. Setting this to nil restores the default behavior of using the device's preferred language. ### Parameters - **forceLanguageLocalization** (Localization.Language?) - Optional - The language to force, or nil to use device locale. ### Request Example ```swift // Force Spanish for all users Siren.shared.presentationManager = PresentationManager( forceLanguageLocalization: .spanish ) ``` ``` -------------------------------- ### Load rules for a specific update type Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/rules-manager.md Determines the applicable rules for a detected update type, driving alert presentation logic. ```swift func loadRulesForUpdateType(_ type: UpdateType) throws -> Rules ``` -------------------------------- ### Define custom rules Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Creates a custom Rules object for advanced control over prompt frequency and alert types. ```swift let customRule = Rules( promptFrequency: .daily, forAlertType: .skip ) Siren.shared.rulesManager = RulesManager( globalRules: customRule, showAlertAfterCurrentVersionHasBeenReleasedForDays: 1 ) ``` -------------------------------- ### skipButtonTitle() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Returns the localized 'Skip this version' button text. ```APIDOC ## skipButtonTitle() ### Description Returns the localized text for the skip button. ### Signature `public func skipButtonTitle() -> String` ### Returns - **String** - The localized text for the skip button. ``` -------------------------------- ### Configure per-update-type rules Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Assigns distinct update behaviors based on the semantic versioning type (major, minor, patch, revision). ```swift Siren.shared.rulesManager = RulesManager( majorUpdateRules: .critical, // Force major updates minorUpdateRules: .annoying, // Daily prompt for minors patchUpdateRules: .persistent, // Daily prompt, no skip revisionUpdateRules: .relaxed, // Weekly prompt with skip showAlertAfterCurrentVersionHasBeenReleasedForDays: 1 ) ``` -------------------------------- ### Define Rules for Alert Presentation Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md The Rules struct configures the alert type and prompt frequency for update notifications. Use the provided static properties for common preset configurations. ```swift public struct Rules { let alertType: AlertType let frequency: UpdatePromptFrequency public init(promptFrequency frequency: UpdatePromptFrequency, forAlertType alertType: AlertType) public static var annoying: Rules public static var critical: Rules public static var `default`: Rules public static var hinting: Rules public static var persistent: Rules public static var relaxed: Rules } ``` -------------------------------- ### Siren.wail(performCheck:completion:) Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/siren-main-class.md Initiates the version checking and alert presentation flow. This method can be configured to check automatically when the app enters the foreground or on-demand. ```APIDOC ## wail(performCheck:completion:) ### Description Executes the Siren version checking and alert presentation flow. This is the primary method called to initiate the library's functionality. ### Parameters - **performCheck** (PerformCheck) - Optional - Defines when the version check occurs: `.onForeground` (default) or `.onDemand`. - **completion** ((Result) -> Void) - Optional - Completion handler returning metadata about the version check result and user interaction. ### Example ```swift Siren.shared.wail() { result in switch result { case .success(let updateResults): print("Update available: \(updateResults.model.version)") case .failure(let error): print("Version check failed: \(error.localizedDescription)") } } ``` ``` -------------------------------- ### Retrieve localized next time button title in Swift Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Fetches the localized text for the defer button. ```swift public func nextTimeButtonTitle() -> String ``` ```swift let localization = Siren.shared.presentationManager.localization let buttonText = localization.nextTimeButtonTitle() ``` -------------------------------- ### Define Model Structure Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/types.md Represents the validated App Store metadata for an application. ```swift public struct Model { public let appID: Int public let currentVersionReleaseDate: String public let minimumOSVersion: String public let releaseNotes: String? public let version: String } ``` -------------------------------- ### Configure Custom Button Text Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Sets custom labels for update buttons. Note that custom text values bypass automatic localization. ```swift Siren.shared.presentationManager = PresentationManager( updateButtonTitle: "Get Update", nextTimeButtonTitle: "Later", skipButtonTitle: "Never" ) ``` -------------------------------- ### AppStoreCountry Structure Definition Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md The base structure for representing an App Store region. ```swift public struct AppStoreCountry { public let code: String? } ``` -------------------------------- ### nextTimeButtonTitle() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Returns the localized 'Next Time' button text. ```APIDOC ## nextTimeButtonTitle() ### Description Returns the localized text for the defer button. ### Signature `public func nextTimeButtonTitle() -> String` ### Returns - **String** - The localized text for the defer button. ``` -------------------------------- ### Set Default APIManager Configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Applies the default APIManager settings, which query the US App Store in English using the main bundle identifier. ```swift Siren.shared.apiManager = APIManager.default // Queries US App Store, English language, uses Bundle.main.bundleIdentifier ``` -------------------------------- ### Configure Custom Alert Title and Message Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Sets custom strings for the alert title and message. The message string supports interpolation for app name and version. ```swift Siren.shared.presentationManager = PresentationManager( alertTitle: "New Version Released", alertMessage: "%@ version %@ is now available. Update now?" ) ``` -------------------------------- ### AppStoreCountry Static Properties Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Accessing country-specific instances via static properties on the AppStoreCountry class. ```APIDOC ## AppStoreCountry Static Properties ### Description The `AppStoreCountry` class provides static properties for over 180 countries. Each property returns an `AppStoreCountry` instance corresponding to the specific country. ### Usage Access these properties directly from the `AppStoreCountry` class: ```swift let country = AppStoreCountry.unitedStates // Returns US instance let country = AppStoreCountry.japan // Returns JP instance ``` ### Available Regions - **Americas**: Includes properties like `unitedStates`, `canada`, `mexico`, `brazil`, etc. - **Europe**: Includes properties like `unitedKingdom`, `france`, `germany`, `italy`, etc. - **Asia-Pacific**: Includes properties like `japan`, `china`, `hongKong`, `australia`, etc. - **Middle East & Africa**: Includes properties like `unitedArabEmirates`, `saudiArabia`, `israel`, `southAfrica`, etc. ``` -------------------------------- ### Retrieve localized skip button title in Swift Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/localization.md Fetches the localized text for the skip version button. ```swift public func skipButtonTitle() -> String ``` ```swift let localization = Siren.shared.presentationManager.localization let buttonText = localization.skipButtonTitle() ``` -------------------------------- ### cleanUp() Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/presentation-manager.md Dismisses the alert and releases associated resources. ```APIDOC ## cleanUp() ### Description Removes the alert controller from the screen, dismisses the alert window, and nullifies all references. This method is safe to call multiple times. ### Signature `func cleanUp()` ### Returns - **Void** ``` -------------------------------- ### Set default RulesManager configuration Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/configuration.md Applies the default daily frequency and skip-enabled alert settings. ```swift Siren.shared.rulesManager = RulesManager.default // Daily frequency, allows skip, 1-day release delay ``` -------------------------------- ### Access Middle East & Africa AppStoreCountry instances Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Use these static properties to reference App Store regions in the Middle East and Africa. ```swift AppStoreCountry.unitedArabEmirates // AE AppStoreCountry.saudiArabia // SA AppStoreCountry.israel // IL AppStoreCountry.egypt // EG AppStoreCountry.southAfrica // ZA AppStoreCountry.kenya // KE AppStoreCountry.nigeria // NG AppStoreCountry.morocco // MA AppStoreCountry.algeria // DZ AppStoreCountry.tunisia // TN AppStoreCountry.kuwait // KW AppStoreCountry.qatar // QA AppStoreCountry.bahrain // BH AppStoreCountry.lebanon // LB AppStoreCountry.jordan // JO AppStoreCountry.iraq // IQ AppStoreCountry.iran // (Sanctioned) AppStoreCountry.turkey // TR AppStoreCountry.oman // OM AppStoreCountry.yemen // YE // ... more ``` -------------------------------- ### Select country dynamically from locale Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/api-reference/app-store-country.md Determines the country based on the current device locale identifier. ```swift // Select country based on device locale let currentLocale = Locale.current let countryCode = currentLocale.region?.identifier let country = AppStoreCountry(code: countryCode) Siren.shared.apiManager = APIManager(country: country) ``` -------------------------------- ### Test Siren with a Known App Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md Use an existing App Store bundle ID to verify Siren functionality without publishing your own app. ```swift Siren.shared.apiManager = APIManager( bundleID: "com.facebook.Facebook" ) Siren.shared.wail(performCheck: .onDemand) ``` -------------------------------- ### Define Model structure Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/README.md The Model struct contains specific app metadata retrieved from the App Store. ```swift public struct Model { public let appID: Int // Unique App ID public let currentVersionReleaseDate: String // ISO 8601 date public let minimumOSVersion: String // Required iOS version public let releaseNotes: String? // What's new public let version: String // Latest version (e.g., "2.5.0") } ``` -------------------------------- ### Integrate Siren in SceneDelegate Source: https://github.com/artsabintsev/siren/blob/master/README.md Initialize the update check by calling Siren.shared.wail() inside the willConnectTo method. ```swift import Siren // Line 1 import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window?.makeKeyAndVisible() Siren.shared.wail() // Line 2 return true } } ``` -------------------------------- ### Define skipVersionUpdate error case Source: https://github.com/artsabintsev/siren/blob/master/_autodocs/errors.md Represents the error case when a user has previously opted to skip the current App Store version. ```swift case skipVersionUpdate(installedVersion: String, appStoreVersion: String) ```