Visitar URL original
GitHub - iletai/AppUpdateKit: ๐Ÿš€ Ultra-lightweight, zero-dependency Swift Package for force update, optional update, and maintenance mode via microCMS or JSON config ยท GitHub
Skip to content

About

๐Ÿš€ Ultra-lightweight, zero-dependency Swift Package for force update, optional update, and maintenance mode via microCMS or JSON config

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

6 Commits

Folders and files

Repository files navigation

AppUpdateKit Banner

CI Status Swift Version Platforms Zero Dependencies License

๐ŸŒ Language Selection / Chแปn ngรดn ngแปฏ / ่จ€่ชž้ธๆŠž:
๐Ÿ‡ฌ๐Ÿ‡ง English ย |ย  ๐Ÿ‡ป๐Ÿ‡ณ Tiแบฟng Viแป‡t ย |ย  ๐Ÿ‡ฏ๐Ÿ‡ต ๆ—ฅๆœฌ่ชž


AppUpdateKit

AppUpdateKit is an ultra-lightweight, zero-dependency, headless-first Swift Package for evaluating app versions, enforcing Force Updates, presenting Optional Updates (with release notes), and activating Maintenance Mode remotely via microCMS, Raw JSON (GitHub Raw, S3, Cloudflare Workers), or any backend endpoint.

๐Ÿ›ก๏ธ Core Values & Design Principles

  • 100% Headless-First (UI is strictly optional): AppUpdateKit is built as a pure business logic engine (AppUpdateChecker, AppUpdateEvaluator, AppVersion, AppUpdateConfig). You are never forced to use our UI. All raw models, metadata, version objects, and event streams are exposed so you can render your own custom dialogs, sheets, or bridges (React Native, Flutter).
  • Zero Third-Party Dependencies: Pure Swift Standard Library (Foundation, SwiftUI, Combine, UIKit).
  • O(N) SemVer Normalizer: Vector integer comparator ("1.2" == "1.2.0" == "1.2.0.0", "1.10.0" > "1.2.0"), stripping prerelease tags and build metadata.
  • Fail-Safe by Default: Network errors, timeouts, or corrupt JSON gracefully fallback to .none without crashing or blocking users.
  • Full Lifecycle Events & Analytics: Emits granular events (checkStarted, configFetched, evaluated, presented, userAction, checkFailed) for Firebase, Mixpanel, and custom logging.
  • Swift 6 & Sendable Compliant: Fully concurrency-safe with @MainActor safety and Task deduplication.

๐Ÿ“ฑ Visual UI Preview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚             Update Available           โ”‚       โ”‚             โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ             โ”‚
โ”‚                                        โ”‚       โ”‚             โ”‚     ๐Ÿ”„     โ”‚             โ”‚
โ”‚  A new version (2.1.0) is available on โ”‚       โ”‚             โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ             โ”‚
โ”‚  the App Store. Would you like to get  โ”‚       โ”‚         Bแบฃn Cแบญp Nhแบญt Mแป›i 2.1.0         โ”‚
โ”‚  the latest features?                  โ”‚       โ”‚  Trแบฃi nghiแป‡m giao diแป‡n mแป›i vร  sแปญa lแป—i. โ”‚
โ”‚                                        โ”‚       โ”‚                                        โ”‚
โ”‚                                        โ”‚       โ”‚  โ”Œโ”€โ”€ Cรณ gรฌ mแป›i: โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚                                        โ”‚       โ”‚  โ”‚ โ€ข โœจ Giao diแป‡n Liquid Glass      โ”‚  โ”‚
โ”‚                                        โ”‚       โ”‚  โ”‚ โ€ข โšก๏ธ Tแป‘i ฦฐu tแป‘c ฤ‘แป™ tแบฃi 40%      โ”‚  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚       โ”‚  โ”‚ โ€ข ๐Ÿ› Sแปญa lแป—i offline sync        โ”‚  โ”‚
โ”‚  โ”‚    ฤแปƒ sau (Later)โ”‚โ”‚Cแบญp nhแบญt(Updateโ”‚ โ”‚       โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚       โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚                                        โ”‚       โ”‚  โ”‚      Cแบญp nhแบญt ngay (Update)      โ”‚  โ”‚
โ”‚                                        โ”‚       โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                        โ”‚       โ”‚              ฤแปƒ sau                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        [ SwiftUI / UIKit Alert ]                        [ Custom SwiftUI Card Sheet ]

๐Ÿš€ Quick Start (100% Headless / Custom UI)

Use pure evaluation logic without touching any UI code:

import AppUpdateKit

let fetcher = AppUpdateFetcher.microCMS(
    endpoint: URL(string: "https://your-service.microcms.io/api/v1/app-update")!,
    apiKey: "YOUR_API_KEY"
)

// Check update status asynchronously (fail-safe)
let action: AppUpdateAction = await AppUpdateChecker.check(
    onEvent: { event in
        Analytics.logEvent("app_update_lifecycle", parameters: ["event": "\(event)"])
    },
    fetcher: fetcher
)

// Handle action in your own custom View, Modal, or Coordinator
switch action {
case .none:
    print("App is up-to-date")
case .optionalUpdate(let title, let message, let storeURL, let version, let releaseNotes, let metadata):
    MyCustomDialogPresenter.showOptionalUpdate(title: title, version: version?.description, url: storeURL)
case .forceUpdate(let title, let message, let storeURL, let version, let releaseNotes, let metadata):
    MyCustomDialogPresenter.showBlockingUpdate(title: title, url: storeURL)
case .maintenance(let title, let message, let metadata):
    MyCustomDialogPresenter.showMaintenanceScreen(message: message)
case .custom(let id, let title, let message, let storeURL, _, _, _):
    MyCustomDialogPresenter.handleCustomAction(id: id)
}

๐ŸŽจ Optional Pre-built UI Modifiers

1. SwiftUI Native Alert

ContentView()
    .appUpdateAlert(
        action: $updateAction,
        configuration: AppUpdateUIConfiguration(
            updateButtonTitle: "Update Now",
            laterButtonTitle: "Later",
            dismissButtonTitle: "OK"
        ),
        onEvent: { event in
            print("[AppUpdateKit] Event: \(event)")
        }
    )

2. SwiftUI Custom Card Sheet

ContentView()
    .appUpdateSheet(
        action: $updateAction,
        accentColor: .indigo,
        onEvent: { event in
            if case .userAction(let action, let choice) = event {
                print("User tapped \(choice) for \(action.title ?? "")")
            }
        }
    )

3. UIKit Integration (UIViewController)

class ViewController: UIViewController {
    func checkVersion() {
        Task { [weak self] in
            let action = await AppUpdateChecker.check(fetcher: fetcher)
            self?.presentAppUpdate(action: action)
        }
    }
}

๐Ÿ“Š Semantic Versioning Comparison Matrix

Current Version Remote Minimum Remote Latest Evaluated Action Application Behavior
1.0.0 2.0.0 2.5.0 .forceUpdate ๐Ÿšจ Blocking update required to proceed
2.0.0 1.5.0 2.1.0 .optionalUpdate ๐Ÿ’ก Show update prompt (with "Later" button)
2.1.0 1.5.0 2.1.0 .none โœ… App is on latest version
2.1.0.0 1.5.0 2.1 .none โœ… Vector-normalized match
any any any (is_maintenance: true) .maintenance ๐Ÿ› ๏ธ Lock app, show maintenance screen
1.0.0 Network Error (404/500/Timeout) N/A .none ๐Ÿ›ก๏ธ Fail-safe: app functions normally

๐Ÿ› ๏ธ microCMS API Schema

Field ID Display Name Type Description
minimum_version Minimum Version Text Versions below this trigger force update
latest_version Latest Version Text Current latest version on App Store
store_url Store URL Text App Store or TestFlight link
is_maintenance Is Maintenance Boolean System maintenance toggle flag
title Title Text (Optional) Custom dialog title
message Message Multi-line Text (Optional) Custom explanation message
release_notes Release Notes Multi-line Text / Array Bullet list of release notes

๐Ÿ“ฆ Installation (SPM)

dependencies: [
    .package(url: "https://github.com/iletai/AppUpdateKit.git", from: "1.1.0")
]

๐Ÿ“„ License

AppUpdateKit is released under the MIT License. Copyright (c) 2026 iletai.

About

๐Ÿš€ Ultra-lightweight, zero-dependency Swift Package for force update, optional update, and maintenance mode via microCMS or JSON config

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages