Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX)

Overview

Mission Control

Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX)

Language Swift 2.2 Platforms iOS | watchOS | tvOS | OSX License MIT

CocoaPods Version Carthage compatible Swift Package Manager compatible

Brought to you by

Have you ever wished you could change some config parameter for your app without deploying a new version? Of course you have! Wouldn't it be great if you had whole config for your app in the cloud and change it as you see fit? Of course it would! Well, go ahead, just put some config somewhere in the cloud and MissionControl will take care of the rest for you.

Index

Features

  • Easily take advantages of using remote (cloud) config for your app
  • Simple and flexible API let's you gradually move from no config, via local config to remote config
  • Automatic caching of the latest remote settings for offline usage (fail-safe)
  • Force load remote setting when you really need the latest config (like NOW)
  • Covered with unit tests
  • Covered with docs

Usage

Initial Configuration

/// You should just launch shared instance of MissionControl on your app start.
/// Good place to do this is in your's AppDelegate's didFinishLaunchingWithOptions:

MissionControl.launch()

Phase 1 - No Config

/// If you're starting from scratch, you could just start using MissionControl right away.
///
/// For anything that you find "configurable" (colors, fonts, alignment, values etc.),
/// instead of just hard-coding it, use helper accessors with setting key and fallback value.
///
/// Here are some examples:

let ready = ConfigBool("Ready", fallback: false)
let numberOfSeconds = ConfigInt("CountdownDuration", fallback: 10)
let launchForce = ConfigDouble("LaunchForce", fallback: 0.5)
let color = ConfigString("ReadyColor", fallback: "#7ED321")

Phase 2 - Local Config

/// After some time, this adds up and you're probably ready to create some local config.
/// You should just define dictionary with setting keys and values and pass it on launch.
///
/// These settings will override whatever you put before in fallback value of accessors.
/// It doesn't need to contain all the stuff, the rest will just continue to use fallback values.

let config: [String : AnyObject] = [
	"Ready" : true,
	"LaunchForce" : 0.21
]

MissionControl.launch(localConfig: config)

Phase 3 - Remote Config

/// After some time, you decide to have more influence on these settings,
/// Yes, even if the app is already deployed. We get it!
///
/// But, you should create that backend part yourself (sorry).
/// Just make sure that you return JSON formatted key-value dictionary in response body.
/// Then, all you need to do is pass your's backend URL on launch.
///
/// After the first refresh (done automatically on launch) remote settings will be cached to disk.
/// These remote settings will override whatever you put in local config dictionary.
///
/// All helper accessors will respect these priority levels:
/// 1. Remote setting from memory (received in the most recent refresh).
/// 2. Remote setting from disk cache (if never refreshed in current app session (ex. offline)).
/// 3. Local setting from disk (defaults provided in `localConfig` on `launch`).
/// 4. Inline provided fallback value

let remoteURL = NSURL(string: "http://appculture.com/mission-control")!
MissionControl.launch(localConfig: config, remoteConfigURL: remoteURL)

Force Load Remote Setting

/// If you need, you can always call `refresh` manually to get the latest settings.
/// Good place to call this is in your AppDelegate's applicationWillEnterForeground: or applicationDidBecomeActive:

MissionControl.refresh()

/// There are also "async force remote" helper accessors which you can use
/// when it's really important to have the latest setting or abort everything.

ConfigBoolForce("Abort", fallback: true) { (forced) in
    if forced {
        self.stopCountdown()
        self.state = .Aborted
    }
}

Listen for changes

/// MissionControl can inform you whenever remote config is refreshed or failed to do so.
/// You can observe for these notifications, or become a MissionControl's delegate, whatever you prefer.

// MARK: - Notifications

let center = NSNotificationCenter.defaultCenter()
center.addObserver(self, selector: #selector(handleRefresh(_:)),
                   name: MissionControl.Notification.DidRefreshConfig, object: nil)
center.addObserver(self, selector: #selector(handleFail(_:)),
                   name: MissionControl.Notification.DidFailRefreshingConfig, object: nil)

// MARK: - MissionControlDelegate

MissionControl.delegate = self
    
func missionControlDidRefreshConfig(old old: [String : AnyObject]?, new: [String : AnyObject]) {
	/// do whatever you need to do
}
    
func missionControlDidFailRefreshingConfig(error error: ErrorType) {
	/// ignore or not, it's up to you
}

Demo

Be sure to check out our example demo project from this repo.
It's kind of a "Rocket Launcher" which doesn't really launch rockets, but it demonstrates power of using MissionControl.

Let me explain:

  1. First screen is initial "Offline" state in which you need to "Connect" to the base (remote config).
  2. When you press "Connect" button it will force load remote config asking for the "Ready" Bool flag.
  3. If remote config returns that "Ready" = true it will go to the Launch screen, otherwise Failure screen.
  4. From the Launch screen you can initiate the Countdown. Number of seconds is also provided via remote config.
  5. During the Countdown, on each second, app checks if launch should be aborted by force loading "Abort" Bool flag from remote. Yes, you can abort the launch remotely from MissionControl.
  6. After Countdown is finished, you can see some nice animation and that's all folks.

P.S. Some colors and other values were also provided via remote config.
Here's what settings are used in this demo, so you can try to abort launch from your server.
Just remember to pass your URL to MissionControl launch: method.

{
    "TopColor": "#000000",
    "BottomColor": "#4A90E2",
    "Ready": true,
    "CountdownDuration": 10,
    "Abort": false,
    "LaunchForce": 0.5,
    "OfflineColor": "#F8E71C",
    "ReadyColor": "#7ED321",
    "CountdownColor": "#F5A623",
    "LaunchedColor": "#BD10E0",
    "FailedColor": "#D0021B",
    "AbortedColor": "#D0021B"
}

So, are you ready for the "Real Time" apps?! We are.

Requirements

  • Xcode 7.3+
  • iOS 8.0+

Installation

  • Using CocoaPods:

    pod 'MissionControl'
  • Carthage:

    github "appculture/MissionControl-iOS"
    
  • Manually:

    Just drag MissionControl.swift into your project and start using it.

License

MissionControl is released under the MIT license. See LICENSE for details.

You might also like...
A simple utility allowing to detect Swift version at runtime.

SwiftVersionDetector SwiftVersionDetector allows you to detect Swift version at runtime. Note that detecting the Swift version of the machine on which

macOS utility for converting fat-frameworks to SPM-compatible XCFramework with arm64-simulator support
macOS utility for converting fat-frameworks to SPM-compatible XCFramework with arm64-simulator support

xcframework-maker macOS utility for converting fat-frameworks to SPM-compatible XCFramework with arm64-simulator support. 📝 Description make-xcframew

A utility to generate PreviewDevice presets from the available devices

SwiftUIGen A utility to generate PreviewDevice presets from the available devices Installation Manual Go to the GitHub page for the latest release Dow

Simple utility to change macOS Big Sur menu bar color by appending a solid color or gradient rectangle to a wallpaper image
Simple utility to change macOS Big Sur menu bar color by appending a solid color or gradient rectangle to a wallpaper image

Change menu bar color in macOS Big Sur Simple utility to change macOS Big Sur menu bar color by appending a solid color or gradient rectangle to a wal

Utility to run the SPI-Server tests as a benchmark

spi-benchmark This package comprises a simple tool to run the SwiftPackageIndex-Server tests in a loop, logging the run times. The purpose is to colle

A simple macOS utility that can be used to control the behaviour of Bose QC35 Headphones straight from the menu bar.

bose-macos-utility A simple macOS utility that can be used to control the behaviour of Bose QC35 Headphones straight from the menu bar. Why Have you e

A tiny macOS utility to foster sustainable OSS

SustainableOSS SustainableOSS is a status bar app for macOS that indexes the third-party dependencies your projects depend on, sorts them by usage, an

Simple utility for only executing code every so often.

Rate Limit Simple utility for only executing code every so often. This will only execute the block passed for a given name if the last time it was cal

Utility functions for validating IBOutlet and IBAction connections
Utility functions for validating IBOutlet and IBAction connections

Outlets Utility functions for validating IBOutlet and IBAction connections. About Outlets provides a set of functions which validate that IBOutlets ar

Owner
appculture
appculture
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.

Mechanica A library of Swift utils to ease your iOS, macOS, watchOS, tvOS and Linux development. Requirements Documentation Installation License Contr

Alessandro 28 Aug 28, 2022
Easy CBOR encoding and decoding for iOS, macOS, tvOS and watchOS.

CBORCoding CBORCoding is a lightweight framework containing a coder pair for encoding and decoding Codable conforming types to and from CBOR document

Joe Newton 23 Nov 8, 2022
Collection of native Swift extensions to boost your development. Support tvOS and watchOS.

SparrowKit Collection of native Swift extensions to boost your development. Support iOS, tvOS and watchOS. If you like the project, don't forget to pu

Ivan Vorobei 119 Dec 20, 2022
A utility that reminds your iPhone app's users to review the app written in pure Swift.

SwiftRater SwiftRater is a class that you can drop into any iPhone app that will help remind your users to review your app on the App Store/in your ap

Takeshi Fujiki 289 Dec 12, 2022
This is a app developed in Swift, using Object Oriented Programing, UIKit user interface programmatically, API Request and Kingfisher to load remote images

iOS NOW ⭐ This is a app developed in Swift, using Object Oriented Programing, UIKit user interface programmatically, API Request and Kingfisher to loa

William Tristão de Paula 1 Dec 7, 2021
A Powerful , Extensible CSS Parser written in pure Swift.

A Powerful , Extensible CSS Parser written in pure Swift.

null 273 Sep 9, 2022
Extensions giving Swift's Codable API type inference super powers 🦸‍♂️🦹‍♀️

Welcome to Codextended — a suite of extensions that aims to make Swift’s Codable API easier to use by giving it type inference-powered capabilities an

John Sundell 1.4k Jan 2, 2023
✨ Super sweet syntactic sugar for Swift initializers

Then ✨ Super sweet syntactic sugar for Swift initializers. At a Glance Initialize UILabel then set its properties. let label = UILabel().then { $0.t

Suyeol Jeon 4k Jan 4, 2023
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.

ZamzamKit ZamzamKit is a Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and othe

Zamzam Inc. 261 Dec 15, 2022
A simple Swift utility for producing pseudolocalized strings.

Build your App UI to adapt and respond to translations, and find localization bugs!

Reece Como 2 Sep 28, 2021