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 World
class 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
end
end
iOS Hello World
class 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
end
end
Android Hello World
class MainActivity < Android::App::Activity
def onCreate(savedInstanceState)
super
text = Android::Widget::TextView.new(self)
text.text = 'Hello RubyMotion!'
self.contentView = text
end
end
Android Hello World
class MainActivity < Android::App::Activity
def onCreate(savedInstanceState)
super
text = Android::Widget::TextView.new(self)
text.text = 'Hello RubyMotion!'
self.contentView = text
end
end
Static compilation
Compilation
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 request
Net.get("https://httpbin.org/get?user_id=1") do |response|
if response.status == 200
response.body['args']['user_id'] # 1
end
end
Net - POST request
options = {
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
end
end
Net - Host reachability
service = Net.reachable?("www.google.fr") do |reachable|
if reachable
# …
end
end
# …
service.stop
JSON
JSON.load('{"foo":"bar"}') # => {"foo" => "bar"}
{"foo" => "bar"}.to_json # => '{"foo":"bar"}'
Digest
# quick
Digest::MD5.digest(‘hello’)
#=> '5d41402abc4b2a76b9719d911017c592'
# long
digest = Digest::MD5.new
digest.update('hello')
digest.digest #=> '5d41402abc4b2a76b9719d911017c592'
Base64
Base64.encode('xx') #=> eHg=
Base64.decode('eHg=') #=> xx
Store
Store['key'] = 42
Store[‘key'] #=> 42
Store.all #=> { 'hey' => 42 }
Store.delete('key')
Location - Monitor
service = 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
end
end
# ...
service.stop
Location - Reverse geocode
Location.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
end
end
Task - Timers
timer1 = Task.after 0.5 do
# executed after half second
end
timer2 = Task.every 2.5 do
# executed every two and half seconds
end
# ...
timer2.stop
Task - Main thread
Task.main do
# update UI stuff…
end
Task - Background thread
Task.background do
# something that takes time…
end
Task - Sequential queues
q = Task.queue
q.schedule do
# job 1
end
q.schedule do
# job 2, will be executed after job 1
end
q.schedule do
# job 3, will be executed after job 2
end
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 - Layout
view.width
view.height
view.left
view.right
view.top
view.bottom
UI - Layout
view.padding_left
view.padding_right
view.padding_top
view.padding_bottom
view.margin_left
view.margin_right
view.margin_top
view.margin_bottom
view.border_left
view.border_right
view.border_top
view.border_bottom
UI - Layout
view.flex # 0 or 1
view.direction # :inherit, :ltr, :rtl
view.flex_direction # :column, :column_reverse,
# :row, :row_reverse
view.justify_content # :flex_start, :center, flex_end,
# :space_between, :space_around
view.align_content # :auto, :flex_start, :center,
# :flex_end, :stretch
view.align_items # :auto, :flex_start, :center,
# :flex_end, :stretch
view.align_self # :auto, :flex_start, :center,
# :flex_end, :stretch
view.position_type # :relative, :absolute
view.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?

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