from idea to app (or “how we roll at small town heroes”)

119
FROM IDEA TO APP or how we roll at Small Town Heroes @bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

Upload: bramus-van-damme

Post on 19-Jan-2017

5.966 views

Category:

Technology


0 download

TRANSCRIPT

FROM IDEA TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

Yo!

@bramus https://www.bram.usBram(us) Van Damme

All work, no and play

#ikdoeict Small Town Heroes

I’m a former lecturer Web & Mobile, now into breaking builds at Small Town Heroes

So you have this great idea for an app

We all have great ideas!

What now?

So you have this great idea for an app

Slideshare Search: “From idea to app”

So you have this great idea for an app

• Evaluate your idea• Is it a good idea?• Will it help people?• How’s the competition doing?• Is there a market?

• Plan your app• Features• Define the MVP• Design• App Flow (Wireframes)

http://yvonnelao.com/2011/04/28/mobile-app-user-flow-chart/

Resulting Wireframes

FROM IDEA TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

FROM IDEA TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

FROM WIREFRAMES TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

FROM MVP TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15

MVP = Minimal Viable Product

So you want to build your MVP

What now?

https://adactio.com/journal/4437

If you’re looking for the more honest, truthful answer to pretty much any question on web

design and usability, here it is:

It depends.

It Depends (TM)

https://adactio.com/journal/4437

It Depends (TM)

If you’re looking for the more honest, truthful answer to pretty much any question on web

design and usability, here it is:

It depends.

XCode, Objective-C / Swift, and the App Store

So you want to build your MVP for iOS

https://developer.apple.com/programs/enroll/

Apple Developer License

https://developer.apple.com/programs/enroll/

Apple Developer License

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html

Objective-C

https://developer.apple.com/swift/

Swift

https://developer.apple.com/xcode/

XCode

Create an archive of your App to upload to Apple

XCode

https://itunesconnect.apple.com/

iTunes Connect

https://itunesconnect.apple.com/

iTunes Connect

http://appreviewtimes.com/

Average App Store Review Times

Your app in the App Store, after approval.

App Store

Even a small typo fix will take up to 7 days.

New Version?

Android SDK, Java, and the Play Store

So you want to build your MVP for Android

http://developer.android.com/distribute/googleplay/start.html

Google Play Developer License

http://developer.android.com/distribute/googleplay/start.html

Google Play Developer License

You know, like in “Programmeren 1”

Java

http://developer.android.com/tools/studio/index.html

Android Studio

https://play.google.com/apps/publish/

Google Play Developer Console

https://play.google.com/apps/publish/

Google Play Developer Console

http://androidreviewtimes.xormedia.com/

Average Play Store Review Times

Your App, in the Play Store

Play Store

Lather, Rinse, Repeat

So you want to build your MVP for Platform X

Native Apps

Write, Test, Build

What if I told you …

Hybrid Apps

Write once, run anywhere

Apache Cordova

https://cordova.apache.org/

→ If you know HTML/CSS/JavaScript, you know how to build a mobile app

HTML

You, after “Webtechnieken”

→ If you know AngularJS, you know how Ionic works

CSS

You, after “Webtechnieken”

→ If you can read, you know Ionic

JavaScript

You, after “Webscripten1”

EV-Point(3RDS)

Video not playing? https://youtu.be/4AhOKtXowgs

App development time?

(from no code to working prototype in Simulator)

App development time?

(from no code to working prototype in Simulator)

App development time?

(from no code to working prototype in Simulator)

Here’s a hint:

App development time

(in hours)

How is that possible?

Ionic Framework

http://ionicframework.com/

Ionic Framework

http://ionicframework.com/

Ionic = CSS Framework

http://ionicframework.com/docs/components/

Ionic = CSS Framework

Cross-Platform CSS, yay!

Ionic = Built on top of AngularJS

https://angularjs.org/

Ionic CLI: ionic serve

$  ionic  serve

← with livereload

→ If you know HTML/CSS/JavaScript, you know how to build a mobile app

Ionic CLI: ionic serve

Cordova Plugins

https://cordova.apache.org/plugins/

Jackpot, Right?!

Nope!

(citation needed)

Final App = Multiple Seasons of 24

App Speed?

http://appreviewtimes.com/

Average App Store Review Times

Bootstrapitis

http://www.novolume.co.uk/blog/all-websites-look-the-same/

What now?

What if I told you …

iOS: WKWebView

(Planned in Cordova 5)

Android: CrossWalk

https://crosswalk-project.org/

What if I told you …

De allesweter(Small Town Heroes)

Video not playing? https://youtu.be/gtSxQ9E9jVA

What if I told you …

Native + Web

Best of both worlds

1. Host some of your content online

Local HTML vs. Online HTML

a. Hybrid App: Point to online URL

← Online FAQ

b. Native App: Use WebViews

Host some of your views online so that you can change it anytime you want.

Memory Game = HTML

We embed this HTML game in a webview contained in the KetnetJr App

Native-Webview Communication with JockeyJS

https://github.com/tcoulter/jockeyjs

// Send an event to JavaScript, passing a payload.// payload can be an NSDictionary or NSArray, or anything that is serializable to JSON.// It can be nil.[Jockey send:@"event-name" withPayload:payload toWebView:webView];

// If you want to send an event and also execute code within the iOS app when all// JavaScript listeners have finished processing.[Jockey send:@"event-name" withPayload:payload toWebView:webView perform:^{ // Respond to callback.}];

// Listen for an event from iOS and log the payload.Jockey.on("event-name", function(payload) { console.log(payload);});

2. Build an API and feed your app with it

Feed your app the data it needs, whenever you want

ZAPP TEKENAPP

ZAPP TEKENAPP

3. Use Feature Flags

Build it, activate it later

Example

div(ng-switch="'featureInvitefriends' | setting : false")

div(ng-switch-when="false")

.item.item-divider.item-info(ng-bind-html="'CREATE_CHANNEL.SHARE.EXPLANATION' | translate")

a.item.item-icon-left(ng-click="doShareGroup(id, title, share_url)")i.icon.icon-add| {{ 'CREATE_CHANNEL.SHARE.LABEL' | translate }}

div(ng-switch-when="true")

.item.item-divider.item-info(ng-bind-html="'CREATE_CHANNEL.INVITE.EXPLANATION' | translate")

.item.item-dividerion-item.friend(ng-repeat="friend in friends.list", ng-click="doInvite(friend)")

img(ng-src="{{ friend.thumbnailURL }}").name {{ friend.firstName }} {{ friend.lastName }}

Let your views show or not show a feature depending on a setting

Example

Let your app request the settings on load

4. Swizzling

Monkey Patch your app on the fly

Native: Method Swizzling#import #import "UIViewController+Logging.h"@implementation UIViewController (Logging) + (void)load { static dispatch_once_t once_token; dispatch_once(&once_token, ^{ SEL viewWillAppearSelector = @selector(viewDidAppear:); SEL viewWillAppearLoggerSelector = @selector(logged_viewDidAppear:); Method originalMethod = class_getInstanceMethod(self, viewWillAppearSelector); Method extendedMethod = class_getInstanceMethod(self, viewWillAppearLoggerSelector); method_exchangeImplementations(originalMethod, extendedMethod); }); } - (void) logged_viewDidAppear:(BOOL)animated { [self logged_viewDidAppear:animated]; NSLog(@"logged view did appear for %@", [self class]); }@end

http://spin.atomicobject.com/2014/12/30/method-swizzling-objective-c/

Hybrid: Load extra JS/CSSvar loadScripts = function(array, callback) {

var loader = function(src, handler) {var script = document.createElement('script');script.src = src;script.onload = script.onreadystatechange = function() {

script.onreadystatechange = script.onload = null;handler();

}var head = document.getElementsByTagName('head')[0];(head || document.body).appendChild(script);

};

(function() {if (array.length!=0) {

loader(array.shift(), arguments.callee);} else {

callback && callback();}

})();

};

http://stackoverflow.com/a/1867135/2076595

Angular/Ionic: Decorate itangular.module('ionHeaderBarTapOverride', [])

// Add our custom tapToScroll implementation on ionHeaderBar (with a higher priority).directive('ionHeaderBar', ['$ionicScrollDelegate', function($ionicScrollDelegate) {

return {restrict: 'E',priority: 100,link: function($scope, $element, $attr) {

// YOUR CODE HERE}

};}])

// Remove Ionic's tapToScroll implementation from ionHeaderBar.config(function($provide) {

$provide.decorator('ionHeaderBarDirective', ['$delegate', function($delegate) {$delegate.shift(); // It's the first one. Delete itreturn $delegate;

}]);

});

http://stackoverflow.com/a/18425418/2076595 http://stackoverflow.com/a/23209542/2076595

→ If you can read, you know Ionic

Write unit tests

(and also execute them using a pre-commit hook)

Write unit tests

(and also execute them using a pre-commit hook)

Use Git

https://git-scm.com/ | https://github.com/

Git Branching Strategy

• Develop on master• Result = “beta”or “staging” builds• → Send these to your beta testers

• Promote master to release• Result = “production” or “appstore” builds• → Send these to the App Store / Play Store / …

Branches have different BUILD_ENV’s

Continuous Integration with Circle CI

https://circleci.com/

Continuous Integration: how?

→ It’s one big hack (Combination of circle.yml, Makefile, bash scripts, build hooks, etc) but it works

# Inject settings for BUILD_ENV into config files- BUILD_ENV=$(ENVIRONMENT) grunt string-replace:settings

# Compile src into www, with staging environment- BUILD_ENV=staging grunt build

## Build Android- BUILD=$CIRCLE_BUILD_NUM BUNDLE_ID="be.smalltownheroes.vrt.allesweter.$ENVIRONMENT" BUILD_ENV=$(ENVIRONMENT) make android- ./scripts-ci/archive_apk.sh staging- ./scripts-ci/distribute_apk.sh

# Build IOS- BUILD=$CIRCLE_BUILD_NUM BUNDLE_ID="be.smalltownheroes.vrt.allesweter.$ENVIRONMENT" BUILD_ENV=$(ENVIRONMENT) make ios- ./scripts-ci/archive_ipa.sh staging- ./scripts-ci/distribute_ipa.sh staging

Continuous Integration: how?

→ It’s one big hack (Combination of circle.yml, Makefile, bash scripts, build hooks, etc) but it works

# Inject build number and bundle id into config.xmlAPP_BUILD=$(BUILD) APP_ID=$(BUNDLE_ID) node scripts-ci/update_config_xml.js

# Install Ionic Platforms and Pluginsrm -rf platformsrm -rf pluginsionic platform add android

# Inject Crashlytics./scripts-ci/crashlytics-android.sh

# Build itANDROID_NAME="$(DISPLAY_NAME)" ionic build android --device --release

Continuous Integration with Circle CI

https://circleci.com/

CI Build Artifacts

https://circleci.com/

Distributing beta builds using Fabric

https://www.fabric.io/

Distributing beta builds using Fabric

Distributing production builds using fastlane

https://fastlane.tools/

Thank you.

FROM IDEA TO APPor how we roll at Small Town Heroes

@bramus | Opleiding Elektronica-ICT, Odisee | 02/12/15