{"id":20297517,"url":"https://github.com/dtrenz/launchgate","last_synced_at":"2025-04-11T12:14:44.444Z","repository":{"id":3638259,"uuid":"49987076","full_name":"dtrenz/LaunchGate","owner":"dtrenz","description":"LaunchGate makes it easy to let users know when an update to your app is available.","archived":false,"fork":false,"pushed_at":"2023-04-12T05:22:28.000Z","size":668,"stargazers_count":60,"open_issues_count":14,"forks_count":16,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-03-20T05:22:13.591Z","etag":null,"topics":["gandalf","ios","version-check"],"latest_commit_sha":null,"homepage":"http://dtrenz.github.io/LaunchGate","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dtrenz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-01-19T22:17:17.000Z","updated_at":"2024-08-12T03:06:57.000Z","dependencies_parsed_at":"2022-08-08T08:15:17.644Z","dependency_job_id":null,"html_url":"https://github.com/dtrenz/LaunchGate","commit_stats":{"total_commits":118,"total_committers":9,"mean_commits":13.11111111111111,"dds":0.4576271186440678,"last_synced_commit":"f8948c16c9b0ecf8cd618847abcbc74edc4bc129"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtrenz%2FLaunchGate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtrenz%2FLaunchGate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtrenz%2FLaunchGate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtrenz%2FLaunchGate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dtrenz","download_url":"https://codeload.github.com/dtrenz/LaunchGate/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248399112,"owners_count":21097295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gandalf","ios","version-check"],"created_at":"2024-11-14T15:47:46.570Z","updated_at":"2025-04-11T12:14:44.424Z","avatar_url":"https://github.com/dtrenz.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LaunchGate\n\n[![CI Status](http://img.shields.io/travis/dtrenz/LaunchGate.svg?style=flat)](https://travis-ci.org/dtrenz/LaunchGate)\n[![Version](https://img.shields.io/cocoapods/v/LaunchGate.svg?style=flat)](http://cocoapods.org/pods/LaunchGate)\n[![License](https://img.shields.io/cocoapods/l/LaunchGate.svg?style=flat)](http://cocoapods.org/pods/LaunchGate)\n[![Platform](https://img.shields.io/cocoapods/p/LaunchGate.svg?style=flat)](http://cocoapods.org/pods/LaunchGate)\n[![codecov.io](https://codecov.io/github/dtrenz/LaunchGate/coverage.svg?branch=develop)](https://codecov.io/github/dtrenz/LaunchGate?branch=develop)\n[![Sponsored by Detroit Labs](https://img.shields.io/badge/sponsor-Detroit%20Labs-000000.svg?style=flat)](http://www.detroitlabs.com)\n\nLaunchGate makes it easy to let users know when an update\nto your app is available.\n\nYou can also block access to the app for older versions,\nwhich is useful in the event of a severe bug or security\nissue that requires users to update the app.\n\nAdditionally, you can use LaunchGate to display a remotely\nconfigured message to users at launch which can also be\nused to temporarily block access to the app (i.e. during\nback-end maintenance).\n\n#### Need an Android version?\nYou're in luck! LaunchGate was built in parallel with its Android counterpart,\n[Gandalf](http://btkelly.github.io/gandalf/).\n\n\n## Installation\n\nLaunchGate is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod \"LaunchGate\"\n```\n\n\n## Usage\n\nLaunchGate downloads \u0026 parses a remotely hosted JSON configuration file at launch,\nthen takes appropriate action.\n\nBy default, LaunchGate expects a configuration file that looks something like this:\n\n```json\n{\n  \"ios\": {\n    \"requiredUpdate\": {\n      \"minimumVersion\": \"1.1\",\n      \"message\": \"An update is required to continue using this app.\"\n    }\n  }\n}\n```\n\nIf you want to use a different configuration structure than the default, you can!\nSee the section below, for instructions on [how to provide a custom parser](#custom-configuration-parser).\n\n#### Enabling LaunchGate\n\n1. Import it into your `AppDelegate`.\n2. Instantiate it, passing in the location of your configuration file and the\nApp Store URI of your app.\n3. Lastly, call `launchGate?.check()` in `applicationDidBecomeActive` or `sceneDidBecomeActive` if you are using scene based windowing.\n\n```swift\nimport LaunchGate\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n  lazy var launchGate = LaunchGate(\n    configURI: \"https://www.example.com/config.json\",\n    appStoreURI: \"itms-apps://itunes.apple.com/us/app/yourapp/id123456789\"\n  )\n\n  func applicationDidBecomeActive(application: UIApplication) {\n    launchGate?.check()\n  }\n\n}\n```\n\nor if you have a Application Scene Manifest setup:\n\n```swift\nimport LaunchGate\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n  var window: UIWindow?\n\n  func sceneDidBecomeActive(_ scene: UIScene) {\n    launchGate?.check()\n  }\n\n}\n```\n\n## The Configuration File\n\nThe JSON configuration file is loaded by LaunchGate when `check()` is called.\nUsing this file you can trigger a few different behaviors in your app.\n\n\u003e _**\"What's with the top-level `ios` object in the JSON? Why is that necessary?\"**_\n\u003e\n\u003e The top level `\"ios\"` object exists because LaunchGate was created in parallel\nwith [Gandalf](http://btkelly.github.io/gandalf/), its Android counterpart project.\nAs [cross-platform mobile developers](http://www.detroitlabs.com), we understand\nhow annoying it can be to get two completely separate iOS \u0026 Android libraries\nsatisfy the same feature requirements. By developing an LaunchGate (iOS) \u0026\n[Gandalf](http://btkelly.github.io/gandalf/) (Android) together, we are able to\nprovide teams that build \u0026 maintained cross-platform apps a solution that should\nwork similarly on both iOS \u0026 Android:\n\u003e\n\u003e\n\u003e Example cross-platform configuration:\n\u003e\n```json \n{\n  \"android\": {\n    \"requiredUpdate\": {\n      \"minimumVersion\": \"1.1\",\n      \"message\": \"An update is required to continue using this app.\"\n    }\n  },\n  \"ios\": {\n    \"requiredUpdate\": {\n      \"minimumVersion\": \"1.1\",\n      \"message\": \"An update is required to continue using this app.\"\n    }\n  }\n}\n```\n\n### Required Update\n\nBy including a `requiredUpdate` object you can specify a minimum app\nversion and a message that will be displayed to users that have a version that\nis too old. Users with an older version will be locked out of app until they\nupdate.\n\n\u003e **Scenario:** A previous version of your app had a critical bug or security\nvulnerability that you have patched in the current version of the app, but you\nstill need to prevent users from continuing to use the older compromised version.\n\n\n\nIn this example, users with a version of the app less than \"1.1\" will see an\nalert dialog when the app is opened, with an \"Update\" button that will take them\nto the App Store so that they can download the latest version.\n\n![Required Update Screenshot](https://raw.githubusercontent.com/dtrenz/LaunchGate/develop/Screenshots/required-update.png)\n\n\n### Optional Update\n\nBy including an `optionalUpdate` object you can specify the current version of\nthe app in the App Store and a message to display to the user, possibly to\nencourage them to update the app.\n\nOptional updates can be dismissed by the user and do not block the user from\nusing the app. Also, an optional update dialog is only showed to the user once\nper version. That way users aren't nagged relentlessly every time they open the app.\n\n\u003e **Scenario:** You've released a significant update to your app and want to\nencourage users that do not have automatic updates enabled to upgrade.\n\n```json\n{\n  \"ios\": {\n    \"optionalUpdate\": {\n      \"optionalVersion\": \"1.2\",\n      \"message\": \"A new version of the app is available.\"\n    }\n  }\n}\n```\n\n![Optional Update Screenshot](https://raw.githubusercontent.com/dtrenz/LaunchGate/develop/Screenshots/optional-update.png)\n\n\n### Alert Messages\n\nLastly, besides providing features related to specific app versions and updates,\nyou can also use LaunchGate to display an informative message to your users when\nthey open the app.\n\n#### Blocking Alert\n\nA \"blocking\" alert (`\"blocking\": true`) is an alert that is displayed to the\nuser when they open the app but does not give the user any option to proceed\ninto the app.\n\n_**IMPORTANT** \u0026rarr; As long as you have `blocking` set to `true` users will\nbe prevented from using your app, so make sure to remove or disable the blocking\nalert as soon as possible._\n\n\u003e **Scenario:** Your app relies on a back-end web service that is temporarily down\nfor maintenance, and you don't want users of the app to be affected.\n\n```json\n{\n  \"ios\": {\n    \"alert\": {\n      \"message\": \"We are currently performing server maintenance. Please try again later.\",\n      \"blocking\": true\n    }\n  }\n}\n```\n\n![Blocking Alert Screenshot](https://raw.githubusercontent.com/dtrenz/LaunchGate/develop/Screenshots/alert-blocking.png)\n\n\n#### Non-Blocking Alert\n\nLike the optional update dialog, non-blocking alert messages are only displayed once per message.\n\n\u003e **Scenario:** Your app relies on a back-end web service that is experiencing\nintermittent connectivity issues and you want to warn users that they the app\nexperience may be degraded.\n\n```json\n{\n  \"ios\": {\n    \"alert\": {\n      \"message\": \"We are currently working to resolve intermittent web service issues. We apologize if your app experience is affected.\",\n      \"blocking\": false\n    }\n  }\n}\n```\n\n![Non-Blocking Alert Screenshot](https://raw.githubusercontent.com/dtrenz/LaunchGate/develop/Screenshots/alert-nonblocking.png)\n\n\n## Custom Configuration Parser\n\nIf you need to use something other than the default configuration JSON object,\nyou can write your own parser that conforms to the `LaunchGateParser` protocol,\nand set it on the LaunchGate instance before calling `check()`.\n\nSee the [example project](https://github.com/dtrenz/LaunchGate/blob/master/Example/Example/AppDelegate.swift#L24-L27).\n\n\n## Author\n\nDan Trenz ([@dtrenz](http://www.twitter.com/dtrenz)) c/o [Detroit Labs](http://www.detroitlabs.com)\n\n\n## License\n\nLaunchGate is available under the Apache License, Version 2.0. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtrenz%2Flaunchgate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdtrenz%2Flaunchgate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtrenz%2Flaunchgate/lists"}