[Srijan Wednesday Webinars] Building Full-Fledged Native Apps Using RubyMotion

Preview:

Citation preview

Building Full-Fledged Native Apps Using RubyMotion

Laurent Sansonetti - @lrz HipByte

Myself• Laurent Sansonetti

• Software hacker

• Company founder

Ruby programmer since 2002

Apple 2004-2012

2012-now

RubyMotion

Toolchain to write native mobile apps in

Ruby

Cross-platform: iOS and Android

(and OS X)

Designed for Ruby programmers

Consistent experience for cross-platform

native development

iOS Android

Language Objective-C Swift Java

Environment Xcode Android Studio

APIs iOS SDK Android SDK

iOS Android

Language Ruby

Environment Your Editor + Terminal

APIs iOS SDK Android SDK

Unified Ruby runtimes

Custom implementations of the Ruby language for

each platform

RubyMotion

iOS SDK

Objective-C

Objective-C Runtime

iOS

RubyMotion

Android SDK

Java

Dalvik / ART

JNI

Android

iOS Hello Worldclass AppDelegate def application(application, didFinishLaunchingWithOptions:options) label = UILabel.new label.text = "Hello World!" label.sizeToFit

viewController = UIViewController.new viewController.view.backgroundColor = UIColor.whiteColor label.center = viewController.view.center viewController.view.addSubview(label)

frame = UIScreen.mainScreen.applicationFrame @window = UIWindow.alloc.initWithFrame(frame) @window.rootViewController = viewController @window.makeKeyAndVisible

true endend

iOS Hello Worldclass AppDelegate def application(application, didFinishLaunchingWithOptions:options) label = UILabel.new label.text = "Hello World!" label.sizeToFit

viewController = UIViewController.new viewController.view.backgroundColor = UIColor.whiteColor label.center = viewController.view.center viewController.view.addSubview(label)

frame = UIScreen.mainScreen.applicationFrame @window = UIWindow.alloc.initWithFrame(frame) @window.rootViewController = viewController @window.makeKeyAndVisible

true endend

Android Hello Worldclass MainActivity < Android::App::Activity def onCreate(savedInstanceState) super

text = Android::Widget::TextView.new(self) text.text = 'Hello RubyMotion!' self.contentView = text endend

Android Hello Worldclass MainActivity < Android::App::Activity def onCreate(savedInstanceState) super

text = Android::Widget::TextView.new(self) text.text = 'Hello RubyMotion!' self.contentView = text endend

Static compilation

Co

mp

ilati

on

Ruby File

AST

LLVM IR

Assembly (ARM or Intel)

Runtime

Static compilation• RubyMotion apps are native binaries

• For iOS: a native executable

• For Android: a JNI native library

• The original Ruby source code is not present in the application bundle

• RubyMotion apps weight a couple MB

Command-line interface

Creating a new project$ motion create --template=ios Hello$ motion create —-template=android Hello$ motion create --template=osx Hello

Project configuration

$ vi Rakefile

Motion::Project::App.setup do |app| # Use `rake config' to see complete project settings. app.name = 'Hello'end

Running

$ rake$ rake simulator

$ rake$ rake emulator

iOS Simulator

Android Emulator

$ rake device

iOS/Android Device

Distribution

$ rake archive:distribution #=> foo.ipa

$ rake release #=> foo.apk

iOS App Store

Android Play Store

https://www.jetbrains.com/ruby/rubymotion

What’s RubyMotion?• Static (AOT) Ruby compiler

• 2 runtimes - implementations of Ruby

• Objective-C (iOS, OS X, tvOS, watchOS)

• Java (Android)

• Build system - based on Rake

• REPL

RubyMotion Starter

Fully-featured (iOS and Android)

Splash screen

rubymotion.com/download

motion-game

Create games for iOS and Android

Cross-platform Ruby API to write games

Fully-featured

Scene Graph

Sensor Events

Sprites

Animations

Physics

Particles

Parallax

Networking

UI Widgets

One code base ↓

iOS, tvOS and Android

100% cross-platform

$ gem install motion-game

Future of RubyMotion

iOS Android

Language Ruby

Environment Your Editor + Terminal

APIs iOS SDK Android SDK

iOS Android

Language Ruby

Environment Your Editor + Terminal

APIs iOS SDK Android SDK

If you make a cross-platform app in RubyMotion:

1) Use platform-specific APIs for user-interface

2) Share common code

Need to learn 2 set of APIs

Need to maintain 2 different codebases

iOS Android

Language Ruby

Environment Your Editor + Terminal

APIs iOS SDK Android SDK

iOS Android

Language Ruby

Environment Your Editor + Terminal

APIs

iOS SDK Android SDK

Ruby Framework

Flow

Cross-platform framework for RubyMotion

Rails of RubyMotion

One code base ↓

iOS and Android

Set of cross-platform libraries for RubyMotion

Current libraries• Net - HTTP networking and host reachability

• JSON - JSON serialization

• Digest - Digest cryptography

• Base64 - Base64 encoding/decoding

• Store - Key-value store

• Location - Location management and (reverse) geocoding

• Task - Lightweight tasks scheduler

• UI - User-interface (big stuff!)

Net - GET requestNet.get("https://httpbin.org/get?user_id=1") do |response| if response.status == 200 response.body['args']['user_id'] # 1 end end

Net - POST requestoptions = { headers: { content_type: :json, body: { user_id: 1 } }}Net.post("https://httpbin.org/post", options) do |response| if response.status == 200 response.body['json']['user_id'] # 1 endend

Net - Host reachabilityservice = Net.reachable?("www.google.fr") do |reachable| if reachable # … endend

# …service.stop

JSONJSON.load('{"foo":"bar"}') # => {"foo" => "bar"}

{"foo" => "bar"}.to_json # => '{"foo":"bar"}'

Digest# quickDigest::MD5.digest(‘hello’) #=> '5d41402abc4b2a76b9719d911017c592'

# longdigest = Digest::MD5.newdigest.update('hello')digest.digest #=> '5d41402abc4b2a76b9719d911017c592'

Base64Base64.encode('xx') #=> eHg=

Base64.decode('eHg=') #=> xx

StoreStore['key'] = 42

Store[‘key'] #=> 42

Store.all #=> { 'hey' => 42 }

Store.delete('key')

Location - Monitorservice = Location.monitor do |location, err| if location puts location.latitude, location.longitude puts location.altitude puts location.time puts location.speed puts location.accuracy else $stderr.puts err endend

# ...service.stop

Location - Reverse geocodeLocation.geocode('apple inc') do |location, err| if location puts location.name puts location.address puts location.locality puts location.postal_code puts location.sub_area puts location.area puts location.country else $stderr.puts err endend

Task - Timerstimer1 = Task.after 0.5 do # executed after half secondend

timer2 = Task.every 2.5 do # executed every two and half secondsend

# ...timer2.stop

Task - Main threadTask.main do # update UI stuff…end

Task - Background threadTask.background do # something that takes time…end

Task - Sequential queuesq = Task.queue

q.schedule do # job 1endq.schedule do # job 2, will be executed after job 1endq.schedule do # job 3, will be executed after job 2end

q.wait # wait for all jobs to finish

UI

UI library• Set of cross-platform classes for UI components

• Cross-platform layout system

UI - Classes• UI::View

• UI::Button

• UI::TextInput

• UI::Label

• UI::Image

• UI::Table

• UI::Web

• UI::Color

• UI::Font

• UI::Alert

• UI::Screen

• UI::Navigation

• UI::Application

• …

UI - Layout• Lets you layout your user interface with a CSS

(Flexbox) Ruby API

• Very easy to use if you are a Web developer!

• Cross-platform unique implementation

• Does not use iOS’s autolayout or Android layout classes

UI - Layoutview.widthview.height

view.leftview.rightview.topview.bottom

UI - Layoutview.padding_leftview.padding_rightview.padding_topview.padding_bottom

view.margin_leftview.margin_rightview.margin_topview.margin_bottom

view.border_leftview.border_rightview.border_topview.border_bottom

UI - Layoutview.flex # 0 or 1view.direction # :inherit, :ltr, :rtlview.flex_direction # :column, :column_reverse, # :row, :row_reverseview.justify_content # :flex_start, :center, flex_end, # :space_between, :space_aroundview.align_content # :auto, :flex_start, :center, # :flex_end, :stretchview.align_items # :auto, :flex_start, :center, # :flex_end, :stretchview.align_self # :auto, :flex_start, :center, # :flex_end, :stretchview.position_type # :relative, :absoluteview.flex_wrap # :no_wrap, :wrap

Demo

Flow is completely open-source

https://github.com/HipByte/Flow

Already used in production

Actively working on it

First release later this month!

Flow will be included in RubyMotion 5.0 when

it’s fully complete

Please give it a try!

What’s RubyMotion?• Static (AOT) Ruby compiler

• 2 runtimes - implementations of Ruby

• Objective-C (iOS, OS X, tvOS, watchOS)

• Java (Android)

• Build system - based on Rake

• REPL

What’s RubyMotion?• Static (AOT) Ruby compiler

• 2 runtimes - implementations of Ruby

• Objective-C (iOS, OS X, tvOS, watchOS)

• Java (Android)

• Build system - based on Rake

• REPL

• Cross-platform framework

Recap

RubyMotion is fun!

Please download RubyMotion!

rubymotion.com/download

Thank you!

www.rubymotion.com @rubymotion info@hipbyte.com

Questions?