Stork 0.1.3

Stork 0.1.3

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Dec 2014

Maintained by Josh Holtz.



Stork 0.1.3

  • By
  • Josh Holtz

Stork iOS SDK

Deploy hybrid apps from anywhere to any device in seconds - http://www.storkhq.io/

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Prepare delivery - configure Stork (default version will be 0.0.0)
    [[Stork sharedClient] prepareDeliveryWithProjectToken:@"your-project-token" withVersion:@"your-project-version"];
    [[Stork sharedClient] prepareDeliveryWithWebView:self.webView];

    // Start Stork delivery - Stork now handles downloads and updates
    [[Stork sharedClient] deliver];
}

Overview

Stork is a platform for managing and deploying hybrid HTML 5 apps within native iOS, Android, Windows Phone, and Cordova wrappers. All you have to do is provide the projectToken and version and Stork will handle the rest. It will handle downloading and installing the newest version of your HTML5 app so that your users will always be running the latest updates without having to push changes through the App Store.

Need to communicate from HTML/JS to native iOS? No problem! Stork comes with a native bridge that allows for this communication. This however is not offically released yet, but you can use Cordova until it is.

Concepts

  • Working directory - The directory that is loaded into the UIWebView. This is the currently installed deploy that the user is interacting with.
  • Holding directory - The directory that holds the latest downloaded deploy before it is installed. The deploy stays here until it is ready to be moved into the working directory for the user to interact with. The holding directory is usually manually moved into the working directory as this will reload the webview which the user could be currently interacting with. By default, Stork moves the holding directory into the working directory when the app is started up.

Features

  • Deploy HTML5 apps into a native wrapper
  • Limit deploys to a specific native version
  • Use StorkConsoleViewController for debugging your app while running on your device - read more
  • Use StorkLoaderViewController for showing users when new content is being downloaded and installed (you know, so they aren't left with a blank screen) - read more

Installation

Examples

Simple setup with StorkLoaderViewController

This setup includes the most functionality for the least amount of work. Here is what is happening:

  1. Prepare Stork with your project token and version (configured from the Stork dashboard)
  2. Prepare with your webview that the Stork object will load up your web app into (read more about deliver)
  3. Initializing a StorkLoaderViewController with the [Stork sharedClient] singleton
  4. Setting the [Stork sharedClient] delegate as the instance of StorkLoaderViewController - this allows the StorkLoaderViewController to recieve the all information it needs to be displayed, show download progress, and hide when complete
  5. Tells Stork to start delivery (which checks for new deploys, downloads them, and loads them into the webview)
@interface ViewController ()<StorkDelegate>

@property (nonatomic, strong) StorkLoaderViewController *storkLoaderViewController;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Prepare delivery - configure Stork
    [[Stork sharedClient] prepareDeliveryWithProjectToken:@"your-project-token" withVersion:@"your-app-version"];
    [[Stork sharedClient] prepareDeliveryWithWebView:self.webView];

    // OPTIONAL - Use this fancy view controller to show loading status
    self.storkLoaderViewController = [StorkLoaderViewController addToViewController:self withStork:[Stork sharedClient]];

    // Start Stork delivery - Stork now handles downloads and updates
    [[Stork sharedClient] deliver];
}

@end

Usage

Stork

The Stork object is the backbone of this library. It handles the API communication, the downloading of the HTML web app, the loading of the UIWebView, and the state of the holding directory and working directory along with other things. Below is a breakdown of the most important aspects.

Stork sharedClient

By calling the sharedClient method on Stork, you are able to get a single instance that is accessible anywhere throughout your app. A singleton is built into Stork since most apps will really only ever have one instance of a UIWebView which only needs one instance of Stork.

It is possible however to instantiate your own (and multiple) Stork objects if you need to.

Stork *storkSingleton = [Stork sharedClient];

Stork prepareDelivery

The Stork object has a few methods that are prefixed with prepareDelivery. These methods should only get execute once and need to get called before deliver is called as they are either 1) required for deliver or 2) determine how Stork does work for you.

prepareDeliveryWithProjectToken:withVersion:

If your project token and/or version aren't defined, the Stork instance is not be able to find any deploys

prepareDeliveryWithWebView

If your webview isn't defined, the Stork instance won't be able to automically load your webview

prepareDeliveryWithOnDeliverBehavior:withOnEnterForeground:

kStorkBehaviorNone - Does nohthing
kStorkBehaviorCheckNewDeploy - Checks if a new deploy is available - request download and install manually
kStorkBehaviorDownloadNewDeploy - Checks if a new deploy is available and downloads it in background - will reload on next app restart or install manually
kStorkBehaviorReloadNewDeploy - Checks if a new deploy is available, downloads it in background, installs it, and reloads webview

Want to control Stork manually? - find more info here

// Configures this Stork instance with your project token and app version
[[Stork sharedClient] prepareDeliveryWithProjectToken:@"your-project-token" withVersion:@"your-app-version"];

// Configures this Stork instance with which webview will be loaded with the web app
[[Stork sharedClient] prepareDeliveryWithWebView:self.webView];

// Configures this Stork instance's behavior when 'delivery' is called - checks for deploy, download new deploy if available, and then reload the web view
[[Stork sharedClient] prepareDeliveryWithOnDeliverBehavior:kStorkBehaviorReloadNewDeploy withOnEnterForeground:kStorkBehaviorReloadNewDeploy];

Stork deliver

The Stork instance will start doing work once deliver is called.

Default Behvaior
  • Will check for new deploy when an app is started up
  • Will check for a new deploy after a day when the app is brought back into the foreground
  • When a new deploy is found, it will download it in the background (into the holding directory). Once download is complete, it will automatically move it from the holding directory into the working directory and reload the UIWebView so that user can use the new web app

Note: This won't offer the best user experience since the UIWebView will automatically reload on the user. There will be other configurations later on that will make this better.

[[Stork sharedClient] deliver];

Stork delegate

Stork offers a delegate, StorkDelegate , that can be set. The delegate call - (void)stork:(Stork *)stork finishedOperation:(StorkOperation)operation withData:(NSDictionary *)data withError:(NSError *)error will get all of the different kinds of status updates and errors that can and will happen.

This allows you to handle...
  • when a new deploy is available to download - you could show your own (download and reloading screen)
  • when a new deploy has been downloaded in the background - you could ask the user if they want to refresh their webview
  • when an error occured - maybe the user doesn't have the best internet connection and should be informed
Available data
  • Download progress updated - kStorkOperationDownloadProgressUpdated
    • kStorkNotificationUserInfoProgress - Progress as a CGFLoat - 0.54
  • Did update working directory - kStorkOperationDidUpdateWorkingDirectory
    • kStorkNotificationUserInfoUrl - URL to index page as a NSString
@interface ViewController ()<StorkDelegate>

@end

@implementation ViewController

- (void)viewDidLoad
{

    // ... other setup code

    // Being a delegate but we don't really need to in this example
    [[Stork sharedClient] setDelegate:self];

    // ... other setup code

}

#pragma mark - StorkDelegate

- (void)stork:(Stork *)stork finishedOperation:(StorkOperation)operation withData:(NSDictionary *)data withError:(NSError *)error {

    switch (operation) {
        case kStorkOperationNewDeployAvailable:
            NSLog(@"New deploy available");
            break;
        case kStorkOperationNoNewDeployAvailable:
            NSLog(@"No new deploy avaiable");
            break;
        case kStorkOperationFailedCheckingNewDeployAvailable:
            NSLog(@"Failed while checking for new deploy - %@", error);
            break;
        case kStorkOperationDownloadProgressUpdated:
            NSLog(@"Download progress - %@", [data objectForKey:kStorkNotificationUserInfoProgress]);
            break;
        case kStorkOperationDownloadedNewDeploy:
            NSLog(@"Downloaded new deploy");
            break;
        case kStorkOperationFailedToDownloadNewDeploy:
            NSLog(@"Failed to download new deploy - %@", error);
            break;
        case kStorkOperationWillUpdateWorkingDirectory:
            NSLog(@"Will update working directory");
            break;
        case kStorkOperationDidUpdateWorkingDirectory:
            NSLog(@"Did update working directory - %@", [data objectForKey:kStorkNotificationUserInfoUrl]);
            break;
        case kStorkOperationFailedToUpdateWorkingDirectory:
            NSLog(@"Failed to update working directory - %@", error);
            break;
        case kStorkOperationDidReloadedWebView:
            NSLog(@"Did reload web view - %@", [data objectForKey:kStorkNotificationUserInfoUrl]);
            break;
        default:
            break;
    }

}

@end

Controlling Stork manually

Sometimes you will want to check for new deploys, download a new deploy, or update from the holding directory manually

Check for new deploy

Use this call to check for a new deploy. You may want to use this if you want to let the user to be notified of a new deploy and then let them take action on when they install the latest deploy.

[[Stork sharedClient] checkForNewDeploy:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Found new deploy
        NSDictionary *deploy = [data objectForKey:kStorkNotificationUserInfoDeploy];
    }
}];
Download newest deploy

Use this call to download from the latest checked depoy, if there is one [[Stork sharedClient] toDownloadDeploy], and download it to the holding directory.

// Returns YES if Stork can download a new deploy
BOOL hasNewDeploy = [[Stork sharedClient] downloadNewDeploy:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Downloaded successfully into holding directory
    }
}];
Update holding directory to working directory and reload webview

Use this call to move a deploy from the holding directory to the working directory and reload the web view with the newest deploy.

// Returns YES if there is a deploy in the holding directory to update with
BOOL canUpdateFromHolding = [[Stork sharedClient] updateWithHoldingDeploy:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Incase you need this - you probably don't
        NSURL *urlOfWorkingDirectory = [data objectForKey:kStorkNotificationUserInfoUrl];
    }
}];
Combined calls - check for new deploy and download
[[Stork sharedClient] checkForNewDeploy:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Found new deploy
        NSDictionary *deploy = [data objectForKey:kStorkNotificationUserInfoDeploy];
    }
} andDownload:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Downloaded successfully into holding directory
    }
}];
Combined calls - check for new deploy, download, install to working directory, and reload
[[Stork sharedClient] checkForNewDeploy:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Found new deploy
        NSDictionary *deploy = [data objectForKey:kStorkNotificationUserInfoDeploy];
    }
} andDownload:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Downloaded successfully into holding directory
    }
} andUpdateWithHolding:^(NSDictionary *data, NSError *error) {
    if (!error) {
        // Incase you need this - you probably don't
        NSURL *urlOfWorkingDirectory = [data objectForKey:kStorkNotificationUserInfoUrl];
    }
}];

StorkConsoleViewController


StorkLoaderViewController


Author(s)

Josh Holtz, [email protected], @joshdholtz

Hand-Coded in Milwaukee, WI by RokkinCat

License

Stork is available under the MIT license. See the LICENSE file for more info.