Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 344 lines (248 sloc) 8.07 kb

BubbleWrap for RubyMotion

A collection of (tested) helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.

BubbleWrap website BubbleWrap mailing list

Installation

gem install bubble-wrap

Setup

  1. Edit the Rakefile of your RubyMotion project and add the following require line.
require 'bubble-wrap'

BubbleWrap is split into multiple modules so that you can easily choose which parts are included at compile-time.

The above example requires all the wrappers/helpers. If you wish to only include the core modules use the following line of code instead:

require 'bubble-wrap/core'

If you wish to only include the HTTP wrapper:

require 'bubble-wrap/http'

Note: DON'T use app.files = in your Rakefile to set up your files once you've required BubbleWrap. Make sure to append onto the array or use +=.

  1. Now, you can use BubbleWrap extension in your app:
class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    puts "#{App.name} (#{App.documents_path})"
    true
  end
end

Note: You can also vendor this repository but the recommended way is to use the versioned gem.

Core

App

A module with useful methods related to the running application

> App.documents_path
# "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/Documents"
> App.resources_path
# "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/testSuite_spec.app"
> App.name
# "testSuite"
> App.identifier
# "io.bubblewrap.testSuite"
> App.alert("BubbleWrap is awesome!")
# creates and shows an alert message.
> App.run_after(0.5) {  p "It's #{Time.now}"   }
# Runs the block after 0.5 seconds.
> App.open_url("http://matt.aimonetti.net")
# Opens the url using the device's browser. (accepts a string url or an instance of `NSURL`.
> App::Persistence['channels'] # application specific persistence storage
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
# ['TF1', 'France 2', 'France 3']

Other available methods:

  • App.notification_center
  • App.user_cache
  • App.states
  • App.frame
  • App.delegate
  • App.current_locale

Device

A collection of useful methods about the current device:

Examples:

> Device.iphone?
# true
> Device.ipad?
# false
> Device.front_camera?
# true
> Device.rear_camera?
# true
> Device.orientation
# :portrait
> Device.simulator?
# true
> Device.retina?
# false
> Device.screen.width
# 320
> Device.screen.height
# 480
> Device.screen.width_for_orientation(:landscape_left)
# 480
> Device.screen.height_for_orientation(:landscape_left)
# 320

Gestures

Extra methods on UIView for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:

    view.whenTapped do
      UIView.animateWithDuration(1,
        animations:lambda {
          # animate
          # @view.transform = ...
        })
    end

There are similar methods for pinched, rotated, swiped, panned, and pressed (for long presses). All of the methods return the actual recognizer object, so it is possible to set the delegate if more fine-grained control is needed.

JSON

BubbleWrap::JSON wraps NSJSONSerialization available in iOS5 and offers the same API as Ruby's JSON std lib.

BW::JSON.generate({'foo => 1, 'bar' => [1,2,3], 'baz => 'awesome'})
=> "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
BW::JSON.parse "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
=> {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}

NSIndexPath

Helper methods added to give NSIndexPath a bit more of a Ruby interface.

NSNotificationCenter

Helper methods to give NSNotificationCenter a Ruby-like interface:

def viewWillAppear(animated)
  @foreground_observer = notification_center.observe UIApplicationWillEnterForegroundNotification do |notification|
    loadAndRefresh
  end

  @reload_observer = notification_center.observe ReloadNotification do |notification|
    loadAndRefresh
  end
end

def viewWillDisappear(animated)
  notification_center.unobserve @foreground_observer
  notification_center.unobserve @reload_observer
end

def reload
  notification_center.post ReloadNotification
end

NSUserDefaults

Helper methods added to the class repsonsible for user preferences used by the App::Persistence module shown below.

Persistence

Offers a way to persist application specific information using a very simple interface:

> App::Persistence['channels'] # application specific persistence storage
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
# ['TF1', 'France 2', 'France 3']

Observers

Since: > version 0.4

You can observe for object's changes and trigger blocks:

class ExampleViewController < UIViewController
  include BW::KVO

  def viewDidLoad
    @label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
    @label.text = ""
    view.addSubview @label

    observe(@label, "text") do |old_value, new_value|
      puts "Hello from viewDidLoad!"
    end
  end

  def viewDidAppear(animated)
    observe(@label, "text") do |old_value, new_value|
      puts "Hello from viewDidAppear!"
    end
  end

end

String

The Ruby String class was extended to add #camelize and #underscore methods.

> "matt_aimonetti".camelize
=> "MattAimonetti"
> "MattAimonetti".underscore
=> "matt_aimonetti"

Time

The Time Ruby class was added a class level method to convert a iso8601 formatted string into a Time instance.

> Time.iso8601("2012-05-31T19:41:33Z")
=> 2012-05-31 21:41:33 +0200

UIControl / UIButton

Helper methods to give UIButton a Ruby-like interface. Ex:

button.when(UIControlEventTouchUpInside) do
  self.view.backgroundColor = UIColor.redColor
end

UIViewController

A custom method was added to UIViewController to return the content frame of a view controller.

HTTP

BubbleWrap::HTTP wraps NSURLRequest, NSURLConnection and friends to provide Ruby developers with a more familiar and easier to use API. The API uses async calls and blocks to stay as simple as possible.

To enable it add the following require line to your Rakefile:

require 'bubble-wrap/http'

Usage example:

BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
  p response.body.to_str
end
BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
  p response.body.to_str # prints the response's body
end
data = {first_name: 'Matt', last_name: 'Aimonetti'}
BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
  if response.ok?
    json = BubbleWrap::JSON.parse(response.body.to_str)
    p json['id']
  elsif response.status_code.to_s =~ /40\d/
    App.alert("Login failed")
  else
    App.alert(response.error_message)
  end
end

Do you have a suggestion for a specific wrapper? Feel free to open an issue/ticket and tell us about what you are after. If you have a wrapper/helper you are using and are thinking that others might enjoy,

please send a pull request (with tests if possible).

BW::Dispatch

TODO: Write a gem description

Installation

Add this line to your application's Gemfile:

gem 'bw-dispatch'

And then execute:

$ bundle

Or install it yourself as:

$ gem install bw-dispatch

Usage

TODO: Write usage instructions here

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request
Something went wrong with that request. Please try again.