SkillAgentSearch skills...

BubbleWrap

Cocoa wrappers and helpers for RubyMotion (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull requests

Install / Use

/learn @rubymotion-community/BubbleWrap
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

BubbleWrap for RubyMotion

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

Code Climate Build Status Gem Version

Installation

gem install bubble-wrap

Setup

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

If you use Bundler:

gem 'bubble-wrap', '~> 1.9.7'

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

If you wish to only include the RSS Parser wrapper:

require 'bubble-wrap/rss_parser'

If you wish to only include the Reactor wrapper:

require 'bubble-wrap/reactor'

If you wish to only include the UI-related wrappers:

require 'bubble-wrap/ui'

If you wish to only include the Camera wrapper:

require 'bubble-wrap/camera'

If you wish to only include the Location wrapper:

require 'bubble-wrap/location'

If you wish to only include the Media wrapper:

require 'bubble-wrap/media'

If you wish to only include the Mail wrapper:

require 'bubble-wrap/mail'

If you wish to only include the SMS wrapper:

require 'bubble-wrap/sms'

If you wish to only include the Motion (CoreMotion) wrapper:

require 'bubble-wrap/motion'

If you wish to only include the NetworkIndicator wrapper:

require 'bubble-wrap/network-indicator'

If you want to include everything (ie kitchen sink mode) you can save time and do:

require 'bubble-wrap/all'

You can also do this directly in your Gemfile like so:

gem 'bubble-wrap', require: %w[bubble-wrap/core bubble-wrap/location, bubble-wrap/reactor]

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

Misc

UUID generator:

BubbleWrap.create_uuid
=> "68ED21DB-82E5-4A56-ABEB-73650C0DB701"

Localization (using NSBundle.mainBundle.localizedStringForKey):

BubbleWrap.localized_string(:foo, 'fallback')
=> "fallback"

Color conversion:

BubbleWrap.rgba_color(23, 45, 12, 0.4)
=> #<UIDeviceRGBColor:0x6db6ed0>
BubbleWrap.rgb_color(23, 45, 12)
=> #<UIDeviceRGBColor:0x8ca88b0>
'blue'.to_color
=> #<UICachedDeviceRGBColor:0xda535c0>
'dark_gray'.to_color
=> #<UICachedDeviceWhiteColor:0x8bb5be0>
'#FF8A19'.to_color
=> #<UIDeviceRGBColor:0x8d54110>
'#88FF8A19'.to_color # ARGB format
=> #<UIDeviceRGBColor:0xca0fe00>

Debug flag:

BubbleWrap.debug?
=> false
BubbleWrap.debug = true
=> true
BubbleWrap.debug?
=> true

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.alert("BubbleWrap is awesome!", {cancel_button_title: "I know it is!", message: "Like, seriously awesome."})
# creates and shows an alert message with optional parameters.
> App.run_after(0.5) {  p "It's #{Time.now}"   }
# Runs the block after 0.5 seconds.
> App.open_url("http://matt.aimonetti.net")
> App.open_url("tel://123456789")
# Opens the url using the device's browser. Can also open custom URL schemas (accepts a string url or an instance of `NSURL`.)
> App.can_open_url("tel://")
# Returns whether the app can open a given URL resource.
> 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']
> App.environment
# 'test'

Other available methods:

  • App.notification_center
  • App.user_cache
  • App.states
  • App.frame
  • App.delegate
  • App.shared
  • App.window
  • App.current_locale
  • App.release?
  • App.test?
  • App.development?

Device

A collection of useful methods about the current device:

Examples:

> Device.iphone?
# true
> Device.ipad?
# false
> Device.camera.front?
# true
> Device.camera.rear?
# true
> Device.orientation
# :portrait
> Device.interface_orientation
# :portrait
> Device.simulator?
# true
> Device.ios_version
# "6.0"
> 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
> Device.vendor_identifier
# <NSUUID>

Camera

Added interface for better camera access:

# Uses the front camera
BW::Device.camera.front.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the rear camera
BW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the photo library
BW::Device.camera.any.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Lets the user edit the photo (with access to the edited and original photos)
BW::Device.camera.any.picture(allows_editing: true, media_types: [:image]) do |result|
  edited_image_view = UIImageView.alloc.initWithImage(result[:edited_image])
  original_image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Capture a low quality movie with a limit of 10 seconds
BW::Device.camera.front.picture(media_types: [:movie], video_quality: :low, video_maximum_duration: 10) do |result|
  video_file_path = result[:media_url]
end

Options include:

  • :allows_editing - Boolean; whether a user can edit the photo/video before picking
  • :animated - Boolean; whether to display the camera with an animation (default true)
  • :on_dismiss - Lambda; called instead of the default dismissal logic
  • :media_types - Array; containing any of [:movie, :image]
  • :video_quality - Symbol; one of :high, :medium, low, "640x480".to_sym, iframe1280x720, or iframe960x540. Defaults to :medium
  • :video_maximum_duration - Integer; limits movie recording length. Defaults to 600.

JSON

BW::JSON wraps NSJSONSerialization available in iOS5 and offers the same API as Ruby's JSON std lib. For apps building for iOS4, we suggest a different JSON alternative, like AnyJSON.

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.

index_path = table_view.indexPathForCell(cell)
index_path + 1 # NSIndexPath for next cell in the same section
=> #<NSIndexPath:0x120db8e0>

NSNotificationCenter

Helper methods to give NSNotificationCenter a Ruby-like interface:

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

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

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

def reload
  App.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']
> App::Persistence.delete('channels')
# ['TF1', 'France 2', 'France 3']
> App::Persistence['something__new'] # something previously never stored
# nil
> App::Persistence.all
# {'all':'values', 'stored':'by', 'bubblewrap':'as a hash!'}

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

You can remove observers using unobserve method.

Since: > version 1.9.0

Optionally, multiple key paths can be passed to the observer method:

class ExampleViewController < UIViewC
View on GitHub
GitHub Stars1.2k
CategoryDevelopment
Updated22d ago
Forks206

Languages

Ruby

Security Score

80/100

Audited on Mar 9, 2026

No findings