Showing preview only (601K chars total). Download the full file or copy to clipboard to get everything.
Repository: rubymotion/BubbleWrap
Branch: master
Commit: afdc89e7f49e
Files: 186
Total size: 553.1 KB
Directory structure:
gitextract_83mw8g5j/
├── .gitignore
├── .travis.yml
├── .yardopts
├── CHANGELOG.md
├── GEM.md
├── GETTING_STARTED.md
├── Gemfile
├── HACKING.md
├── LICENSE
├── README.md
├── Rakefile
├── bubble-wrap.gemspec
├── lib/
│ ├── bubble-wrap/
│ │ ├── all.rb
│ │ ├── camera.rb
│ │ ├── core.rb
│ │ ├── ext/
│ │ │ └── motion_project_app.rb
│ │ ├── ext.rb
│ │ ├── font.rb
│ │ ├── loader.rb
│ │ ├── location.rb
│ │ ├── mail.rb
│ │ ├── media.rb
│ │ ├── motion.rb
│ │ ├── network-indicator.rb
│ │ ├── reactor.rb
│ │ ├── requirement/
│ │ │ └── path_manipulation.rb
│ │ ├── requirement.rb
│ │ ├── rss_parser.rb
│ │ ├── sms.rb
│ │ ├── test.rb
│ │ ├── ui.rb
│ │ └── version.rb
│ └── bubble-wrap.rb
├── motion/
│ ├── core/
│ │ ├── app.rb
│ │ ├── device/
│ │ │ ├── ios/
│ │ │ │ ├── camera.rb
│ │ │ │ ├── camera_wrapper.rb
│ │ │ │ └── screen.rb
│ │ │ ├── osx/
│ │ │ │ └── screen.rb
│ │ │ └── screen.rb
│ │ ├── device.rb
│ │ ├── ios/
│ │ │ ├── app.rb
│ │ │ ├── device.rb
│ │ │ └── ns_index_path.rb
│ │ ├── json.rb
│ │ ├── kvo.rb
│ │ ├── ns_index_path.rb
│ │ ├── ns_notification_center.rb
│ │ ├── ns_url_request.rb
│ │ ├── ns_user_defaults.rb
│ │ ├── osx/
│ │ │ ├── app.rb
│ │ │ └── device.rb
│ │ ├── persistence.rb
│ │ ├── pollute.rb
│ │ ├── string.rb
│ │ └── time.rb
│ ├── core.rb
│ ├── font/
│ │ └── font.rb
│ ├── ios/
│ │ └── 8/
│ │ └── location_constants.rb
│ ├── location/
│ │ ├── location.rb
│ │ └── pollute.rb
│ ├── mail/
│ │ ├── mail.rb
│ │ └── result.rb
│ ├── media/
│ │ ├── media.rb
│ │ └── player.rb
│ ├── motion/
│ │ ├── accelerometer.rb
│ │ ├── device_motion.rb
│ │ ├── gyroscope.rb
│ │ ├── magnetometer.rb
│ │ └── motion.rb
│ ├── network-indicator/
│ │ └── network-indicator.rb
│ ├── reactor/
│ │ ├── default_deferrable.rb
│ │ ├── deferrable.rb
│ │ ├── dependent_deferrable.rb
│ │ ├── eventable.rb
│ │ ├── future.rb
│ │ ├── periodic_timer.rb
│ │ ├── queue.rb
│ │ ├── thread_aware_deferrable.rb
│ │ └── timer.rb
│ ├── reactor.rb
│ ├── rss_parser.rb
│ ├── shortcut.rb
│ ├── sms/
│ │ ├── result.rb
│ │ └── sms.rb
│ ├── test_suite_delegate.rb
│ ├── ui/
│ │ ├── pollute.rb
│ │ ├── ui_activity_view_controller_wrapper.rb
│ │ ├── ui_alert_view.rb
│ │ ├── ui_bar_button_item.rb
│ │ ├── ui_control_wrapper.rb
│ │ ├── ui_view_controller_wrapper.rb
│ │ └── ui_view_wrapper.rb
│ └── util/
│ ├── constants.rb
│ └── deprecated.rb
├── resources/
│ ├── Localizable.strings
│ └── atom.xml
├── samples/
│ ├── alert/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── alert_view_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── camera/
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── camera_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── gesture/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ ├── controllers/
│ │ │ │ └── drawing_view_controller.rb
│ │ │ ├── helpers/
│ │ │ │ └── drawing_helper.rb
│ │ │ └── views/
│ │ │ └── drawing/
│ │ │ ├── gesture_view.rb
│ │ │ └── rect_view.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── location/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ ├── controllers/
│ │ │ │ └── places_list_controller.rb
│ │ │ └── models/
│ │ │ └── places.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── media/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── play_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ └── osx/
│ ├── Gemfile
│ ├── Rakefile
│ ├── app/
│ │ ├── app_delegate.rb
│ │ └── menu.rb
│ ├── resources/
│ │ └── Credits.rtf
│ └── spec/
│ └── main_spec.rb
└── spec/
├── lib/
│ ├── bubble-wrap/
│ │ ├── ext/
│ │ │ ├── motion_project_app_spec.rb
│ │ │ └── motion_project_config_spec.rb
│ │ ├── requirement/
│ │ │ └── path_manipulation_spec.rb
│ │ └── requirement_spec.rb
│ ├── bubble-wrap_spec.rb
│ └── motion_stub.rb
└── motion/
├── core/
│ ├── app_spec.rb
│ ├── device/
│ │ ├── ios/
│ │ │ ├── camera_spec.rb
│ │ │ ├── camera_wrapper_spec.rb
│ │ │ ├── device_spec.rb
│ │ │ └── screen_spec.rb
│ │ └── osx/
│ │ └── screen_spec.rb
│ ├── device_spec.rb
│ ├── ios/
│ │ ├── app_spec.rb
│ │ └── ns_index_path_spec.rb
│ ├── json_spec.rb
│ ├── kvo_spec.rb
│ ├── ns_index_path_spec.rb
│ ├── ns_notification_center_spec.rb
│ ├── osx/
│ │ └── app_spec.rb
│ ├── persistence_spec.rb
│ ├── string_spec.rb
│ └── time_spec.rb
├── core_spec.rb
├── font/
│ └── font_spec.rb
├── location/
│ └── location_spec.rb
├── mail/
│ ├── mail_spec.rb
│ └── result_spec.rb
├── media/
│ └── player_spec.rb
├── motion/
│ └── core_motion_spec.rb
├── network-indicator/
│ └── network_indicator_spec.rb
├── reactor/
│ ├── deferrable_spec.rb
│ ├── dependent_deferrable_spec.rb
│ ├── eventable_spec.rb
│ └── thread_aware_deferrable_spec.rb
├── reactor_spec.rb
├── rss_parser_spec.rb
├── sms/
│ ├── result_spec.rb
│ └── sms_spec.rb
├── ui/
│ ├── pollute_spec.rb
│ ├── ui_activity_view_controller_wrapper_spec.rb
│ ├── ui_alert_view_spec.rb
│ ├── ui_bar_button_item_spec.rb
│ ├── ui_control_wrapper_spec.rb
│ ├── ui_view_controller_wrapper_spec.rb
│ └── ui_view_wrapper_spec.rb
└── util/
├── constants_spec.rb
└── deprecated_spec.rb
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.rake_tasks~
pkg/*
build/
.DS_Store
.repl_history
================================================
FILE: .travis.yml
================================================
language: objective-c
osx_image: xcode8
before_install:
- sudo motion update
- motion repo
script:
- bundle exec rake clean
- bundle exec rake spec
- bundle exec rake clean
- bundle exec rake spec target=10
- bundle exec rake clean
- bundle exec rake spec osx=true
================================================
FILE: .yardopts
================================================
lib/**/*.rb
motion/**/*.rb
================================================
FILE: CHANGELOG.md
================================================
## Unreleased
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.7...master)
## 1.9.7
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.6...v1.9.7)
* [iOS] Fix iOS 11 photo library crash ([#493](https://github.com/rubymotion-community/BubbleWrap/pull/493))
* [iOS] Updated Device.simulator? to work in iOS 13+ ([#499](https://github.com/rubymotion-community/BubbleWrap/pull/499))
* [iOS] Add MobileCoreServices to list of required frameworks. Fixes issue with missing KUTTypeMovie constant.
## 1.9.6
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.5...v1.9.6)
* [iOS] Add Device.force_touch? ([#478](https://github.com/rubymotion-community/BubbleWrap/pull/478))
* [iOS] Fixes for iOS 10 ([#489](https://github.com/rubymotion-community/BubbleWrap/pull/489))
## 1.9.5
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.4...v1.9.5)
* Fixed 'simulator?' so it returns the correct value, when running ios 8 or below on device. ([#481](https://github.com/rubymotion-community/BubbleWrap/pull/481))
## ~~1.9.3~~ 1.9.4
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.2...v1.9.4)
* Fixed `Device.simulator?` for iOS 9. ([#473](https://github.com/rubymotion-community/BubbleWrap/pull/473))
## 1.9.2
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.1...v1.9.2)
* Added `DependentDeferrable`. ([#469](https://github.com/rubymotion-community/BubbleWrap/pull/469))
## 1.9.1
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.0...v1.9.1)
* Fix issue in loading iOS 8 constants for CoreLocation
## 1.9.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.8.0...v1.9.0)
* Add support for `keyboardType` on first input field of `BW::UIAlertView` ([#406](https://github.com/rubymotion-community/BubbleWrap/pull/406))
* Implement #+ and #- for NSIndexPath to incr/decr row ([#420](https://github.com/rubymotion-community/BubbleWrap/pull/420))
* Extract CoreMotion classes to make it easier to use and more maintainable ([#454](https://github.com/rubymotion-community/BubbleWrap/pull/454))
* Motion extract classes ([#454](https://github.com/rubymotion-community/BubbleWrap/pull/454))
* Added RSS fields: creator, category, encoded ([#461](https://github.com/rubymotion-community/BubbleWrap/pull/461))
* KVO `observe!` and ability to pass multiple key paths to `observe` ([#460](https://github.com/rubymotion-community/BubbleWrap/pull/460))
* `App.short_version` ([#466](https://github.com/rubymotion-community/BubbleWrap/pull/466))
* Bump the required version of iOS to >= 7 ([#424](https://github.com/rubymotion-community/BubbleWrap/pull/424))
* Bump the required version of iOS to >= 7 ([#424](https://github.com/rubymotion-community/BubbleWrap/pull/424))
* Fixes to CoreLocation ([#422](https://github.com/rubymotion-community/BubbleWrap/pull/422)) & ([#432](https://github.com/rubymotion-community/BubbleWrap/pull/432))
* Adds default text option to BW::UIAlertView ([#467](https://github.com/rubymotion-community/BubbleWrap/pull/467))
* Bump the minimum required RubyMotion version to `3.12`.
## ... nothing to see here... move along.
## 1.4.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.3.0...v1.4.0)
* Added `BW::Mail` for sending emails ([#247](https://github.com/rubymotion-community/BubbleWrap/pull/247))
* Added `BW::SMS` for sending SMS/iMessages ([#287](https://github.com/rubymotion-community/BubbleWrap/pull/287))
* Added `App::Persistence.delete` ([#286](https://github.com/rubymotion-community/BubbleWrap/pull/286))
* Added `BW::HTTP::Response#error`, which is an `NSError` instance ([#284](https://github.com/rubymotion-community/BubbleWrap/pull/284))
* Added `BW::HTTP::Query#cancel` to chancel URL requests ([#278](https://github.com/rubymotion-community/BubbleWrap/pull/278))
* Added `App.info_plist` ([#273](https://github.com/rubymotion-community/BubbleWrap/pull/273/))
* Added `BW::Device.interface_orientation` ([#265](https://github.com/rubymotion-community/BubbleWrap/pull/265))
* Added `OPTIONS` request method to `BW::HTTP` ([#260](https://github.com/rubymotion-community/BubbleWrap/pull/260))
* Added `Time.iso8601_with_timezone` ([#255](https://github.com/rubymotion-community/BubbleWrap/pull/255))
* Added `:encoding` option to `BW::HTTP` ([#251](https://github.com/rubymotion-community/BubbleWrap/pull/251))
* Moved `BW::Reactor::Timer` and `BW::Reactor::PeriodicTimer` from `NSTimer` to GCD `Dispatch::Source.timer` ([#242](https://github.com/rubymotion-community/BubbleWrap/pull/242))
* Option `:common_modes` for BW::Reactor::PeriodicTimer has been deprecated, it's not needed anymore.
* Fixed App#window (and thus `BW::Camera`) to work with iOS7 modals ([#305](https://github.com/rubymotion-community/BubbleWrap/pull/305))
* Fixed patches on `String` to be on `NSString` ([#292](https://github.com/rubymotion-community/BubbleWrap/pull/292))
* Fixed `BW::HTTP` success heuristic to match RFC 2616 ([#282](https://github.com/rubymotion-community/BubbleWrap/pull/282))
* Fixed `BW::HTTP` to correctly identify `false` parameters ([#261](https://github.com/rubymotion-community/BubbleWrap/issues/261) [#262](https://github.com/rubymotion-community/BubbleWrap/pull/262))
* Fixed `BW::Reactor` to correctly handle unregistered procs ([#253](https://github.com/rubymotion-community/BubbleWrap/pull/253))
* Fixed `BW::localized_string` to mirror Cocoa API by returning the `key` if no localization exists ([#181](https://github.com/rubymotion-community/BubbleWrap/pull/181))
* Addressed a few memory related problems ([#270](https://github.com/rubymotion-community/BubbleWrap/pull/270) [#275](https://github.com/rubymotion-community/BubbleWrap/pull/275) [#276](https://github.com/rubymotion-community/BubbleWrap/pull/276))
## 1.3.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.2.0...v1.3.0)
* Added OS X support for RubyMotion 2.0 ([#233](https://github.com/rubymotion-community/BubbleWrap/pull/233)). BubbleWrap *drops support* for RubyMotion 1.x.
* Changed `BW::UIBarButtonItem` internals; `.build` is now deprecated and forwards to `.new` ([#226](https://github.com/rubymotion-community/BubbleWrap/pull/226))
* Changed `HTTP` to present credentials with an `Authorization` header *before* any requests are made, unless the `:present_credentials` option `== false` ([#199](https://github.com/rubymotion-community/BubbleWrap/pull/199))
* Fixed `HTTP` to not append a question-mark (`?`) at the end of URL requests with empty `:payload`s ([#221](https://github.com/rubymotion-community/BubbleWrap/pull/221))
* Fixed `HTTP` to correctly parameterize an array of hashes, Rails-style ([#219](https://github.com/rubymotion-community/BubbleWrap/pull/219))
## 1.2.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.5...v1.2.0)
* Added `BW::UIBarButtonItem`, a factory-esque wrapper for `UIBarButtonItem` ([#202](https://github.com/rubymotion-community/BubbleWrap/pull/202))
* Added `BW::Font`, a wrapper for creating `UIFont` objects ([#206](https://github.com/rubymotion-community/BubbleWrap/pull/206))
* Added `BW::Reactor::Eventable#off`, to remove `BW::Reactor` callbacks ([#205](https://github.com/rubymotion-community/BubbleWrap/pull/205))
* Added `BW::Constants.get`, which is a class to help wrapper creation ([#203](https://github.com/rubymotion-community/BubbleWrap/pull/203))
* Added `BW::Location.get_once` to grab only one location ([#197](https://github.com/rubymotion-community/BubbleWrap/pull/197))
* Added `App#environment`, to detect the current RubyMotion environment ([#191](https://github.com/rubymotion-community/BubbleWrap/pull/191))
* Added `:follow_urls` option to `BW::HTTP` ([#192](https://github.com/rubymotion-community/BubbleWrap/pull/192))
* Added `:common_modes` option to `BW::Reactor`to change the runloop mode (#190)
* Added `:no_redirect` option to `BW::HTTP` ([#187](https://github.com/rubymotion-community/BubbleWrap/pull/187))
* Added `:cookies` option to `BW::HTTP` ([#204](https://github.com/rubymotion-community/BubbleWrap/pull/204))
## 1.1.5
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.4...v1.1.5)
* Fix `BW::Camera` view-controller selection process to pickup a window's `presentedViewController` ([#183](https://github.com/rubymotion-community/BubbleWrap/pull/183))
* Fix strings parsed in `BW::JSON` to be mutable ([#175](https://github.com/rubymotion-community/BubbleWrap/pull/175))
* Add option for `:credential_persistence`/`NSURLCredentialPersistence` in `BW::HTTP` ([#166](https://github.com/rubymotion-community/BubbleWrap/pull/166))
* Change `Device.wide_screen?` to `Device.long_screen?` ([#159](https://github.com/rubymotion-community/BubbleWrap/pull/159))
* String escaping fixes to `BW::HTTP` ([#160](https://github.com/rubymotion-community/BubbleWrap/pull/160) [#161](https://github.com/rubymotion-community/BubbleWrap/pull/161) [#162](https://github.com/rubymotion-community/BubbleWrap/pull/162))
* Add `Device.sdk_version`
## 1.1.4
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.3...v1.1.4)
* Support RubyMotion 1.24 or above (https://github.com/rubymotion-community/BubbleWrap/pull/143)
* Fixed a problem with `when` events not properly handling multiple targets per event. Now defaults to one target per event with an option to append multiple targets.
## 1.1.3
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.2...v1.1.3)
## 1.1.2
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.1...v1.1.2)
* Fixed a problem with the load path.
* Added `format:` to the HTTP wrapper with [5 supported formats supported](https://github.com/rubymotion-community/BubbleWrap/pull/109) that sets the content type accordingly.
* Default HTTP Content-Type for `POST` like requests is back to being
form url encoded.
## 1.1.1
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.0...v1.1.1)
### Enhancements
* Added support for symbols as selectors to the KVO module.
* Improved the RSSParser by providing a delegate to handle errors.
### Bug Fixes
* Fixed a bug with the way JSON payloads were handled in the HTTP
wrapper.
* Fixed a bug with the way the headers and content types were handled in
the HTTP wrapper.
## 1.1.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.0.0...v1.1.0)
* Added `BubbleWrap::Reactor`, a simplified implementation of the Event Machine API on top of GCD.
* Added upload support to the HTTP wrapper.
* Added `BubbleWrap.create_uuid` to generate a uuid string.
* Added a program progress proc option to the HTTP wrapper.
* Added a RSS parser.
* Added a camera wrapper.
* Split the various wrappers in self contained and requirable libraries.
* Added a wrapper around the location/gps APIs.
* Added a merge method to the persistence layer so multiple values can
be saved at once.
* Added a way to create `UIColor` instances using a hex string: `'#FF8A19'.to_color` or color keyword: `'blue'.to_color`, `'dark_gray'.to_color`.
## 1.0.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.4.0...v1.0.0)
* Improved the integration with RubyMotion build system.
* Improved test suite.
* Added better documentation, including on how to work on the internals.
* Added a KVO DSL to observe objects.
* Renamed `Device.screen.widthForOrientation` to Device.screen.width_for_orientation` and `Device.screen.heightForOrientation` to `Device.screen.height_for_orientation`.
* The `HTTP` wrapper now encodes arrays in params in a way that's compatible with Rails.
## 0.4.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.3.1...v0.4.0)
* Refactored the code and test suite to be more modular and to handle
dependencies. One can now require only a subset of BW such as `require 'bubble-wrap/core'` or 'bubble-wrap/http'
## 0.3.1
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.3.0...v0.3.1)
* Added App.run_after(delay){ }
* HTTP responses return true to ok? when the status code is 20x.
## 0.3.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.2.1...v0.3.0)
* Major refactoring preparing for 1.0
## 0.2.1
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.2.0...v0.2.1)
* Minor fix in the way the dependencies are set (had to monkey patch
RubyMotion)
## 0.2.0
[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.1.2...v0.2.0)
* Added network activity notification to the HTTP wrapper.
* fixed a bug in the `NSNotificationCenter` wrapper.
## 0.1.2
Start packaging this lib as a gem.
================================================
FILE: GEM.md
================================================
# Creating a RubyMotion gem with BubbleWrap
Let's say we want to develop a simple library gem that lists the
people in a user's addressbook.
Let's start by initializing an empty gem directory:
```
$ gem install bundler
$ bundle gem bw-addressbook
```
Add BubbleWrap and Rake to your gem's dependencies in `bw-addressbook.gemspec`:
```ruby
Gem::Specification.new do |gem|
gem.add_dependency 'bubble-wrap'
gem.add_development_dependency 'rake'
end
```
Then run `bundler`:
```
$ bundle
Fetching gem metadata from https://rubygems.org/..
Using rake (0.9.2.2)
Installing bubble-wrap (0.4.0)
Using bw-addressbook (0.0.1) from source at /Users/jnh/Dev/tmp/bw-addressbook
Using bundler (1.1.4)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
```
Modify your `lib/bw-addressbook.rb` to include:
```ruby
require 'bw-addressbook/version'
BW.require 'motion/address_book.rb'
```
Edit your project's `Rakefile` to include:
```ruby
#!/usr/bin/env rake
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'
require "bundler/gem_tasks"
Bundler.setup
Bundler.require
require 'bubble-wrap/test'
```
At this point we should have a working RubyMotion environment able to
compile our code as we write it.
Let's start by creating a spec for our address book gem in `spec/address_book_spec.rb`:
```ruby
describe AddressBook do
describe '.list' do
it 'returns an Enumerable' do
AddressBook.list.is_a?(Enumerable).should == true
end
end
end
```
Now if you run `rake spec` you can watch the spec fail:
```
2012-06-07 11:19:35.506 Untitled[14987:f803] *** Terminating app due to uncaught exception 'NameError', reason: 'uninitialized constant AddressBook (NameError)'
*** First throw call stack:
(0x8f6022 0x286cd6 0x140054 0x291f 0x2645 0x1)
terminate called throwing an exception
```
Let's go and define ourselves an `AddressBook` class in `motion/address_book.rb`:
```ruby
class AddressBook
end
```
You'll now get a spec failure:
```
NoMethodError: undefined method `list' for AddressBook:Class
spec.rb:156:in `block in run_spec_block': .list - returns an Enumerable
4:in `execute_block'
spec.rb:156:in `run_spec_block'
spec.rb:171:in `run'
```
Well, we'd better go and define it then, eh?
```
class AddressBook
def self.list
[]
end
end
```
I'm going to leave it here for now, but you're welcome to take a look at the
fully working demonstration project on [Github](http://github.com/jamesotron/bw-addressbook-demo).
================================================
FILE: GETTING_STARTED.md
================================================
# Getting Started with BubbleWrap
A short guide to starting a RubyMotion application using the bubble wrappers.
## A quick note about RubyMotion
[RubyMotion](http://www.rubymotion.com/) is a commercial product available from
[HipByte SPRL](http://www.hipbyte.com/). RubyMotion needs a recent (10.6 or newer)
version of Mac OS X and Apple's Xcode tools installed. If you don't have a working
RubyMotion install take a look at the [getting started guide](http://www.rubymotion.com/developer-center/guides/getting-started/).
## Create a new RubyMotion project
RubyMotion ships with the `motion` command-line tool to handle creating projects,
updating and creating support tickets.
```
$ motion create bw-demo
Create bw-demo
Create bw-demo/.gitignore
Create bw-demo/Rakefile
Create bw-demo/app
Create bw-demo/app/app_delegate.rb
Create bw-demo/resources
Create bw-demo/spec
Create bw-demo/spec/main_spec.rb
```
This gives us an empty project (and one failing spec). That's fine for now.
## Set up Bundler
[Bundler](http://www.gembundler.com/) is a project to manage your project's
RubyGem dependencies. You can get by without it if you want to, but it will
save time and hassle as the number of BubbleWrap gems grows over time.
```
$ gem install bundler
```
Create a new file called `Gemfile` in your project directory and add the
following:
```ruby
source :rubygems
gem 'bubble-wrap', '~> 1.0.0'
gem 'rake'
```
Then run `bundle` from the command-line in the same directory and Bundler
should install BubbleWrap and Rake for you.
## Adding BubbleWrap
Now that we have BubbleWrap installed we need to configure the project to use
it - the easiest way is to add Bundler to our build-environment and tell it
to take care of everything for us.
Edit your project's `Rakefile` and add the following just under `require 'motion/project'`:
```ruby
require 'bundler'
Bundler.setup
Bundler.require
```
Now when you build your project by running `rake` you will see the BubbleWrap files
being compiled into your project.
## Customising BubbleWrap requires
By default BubbleWrap will include all the bubble wrappers into your project, but often
you won't need them all - perhaps you only want to use BubbleWrap's `http` wrappers?
You can change your bubble-wrap line in your `Gemfile` as follows:
```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/http'
```
If you just want core, the change is similarly easy:
```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/core'
```
Also, if you don't want any of BubbleWrap loaded by default, and you just want to use
it's ability to add projects to your build system you can change it to:
```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/loader'
```
And modify your `Rakefile` to include one or more `BW.require` lines:
```ruby
BW.require '/path/to/some/files/**/*.rb'
```
For more information in using `BW.require` take a look at
[the bubblewrap hacking guide](HACKING.md).
## Go forth and conquer!
The developers wish to thank you for using BubbleWrap.
Please feel free to open issues or pull requests on
[GitHub](https://www.github.com/mattetti/BubbleWrap), join our
[mailing list](https://groups.google.com/forum/#!forum/bubblewrap)
or join us on `#bubblewrap` on `irc.freenode.net`.
================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'
# Specify your gem's dependencies in bubble-wrap.gemspec
gemspec
================================================
FILE: HACKING.md
================================================
# Hacking on BubbleWrap
## A library in two parts
RubyMotion forces a certain background-radiation of schizophrenia
due to the fact that it's build tools run using the system ruby
via Rake. BubbleWrap manipulates the build environment in order
to make it possible to include itself (and other code) into the
build process from outside the project hierarchy.
### Part the first: `lib/`
This is where [RubyGems](http://rubygems.org) goes looking for
code when you call
```ruby
require 'bubble-wrap'
```
When `bubble-wrap` is required it immediately requires `bubble-wrap/loader`
which sets up the infrastructure needed to manipulate the `Rakefile` build process.
Once that is done we can freely call
```ruby
BubbleWrap.require 'motion/core/**/*.rb'
```
`BubbleWrap.require` (or simply `BW.require`) is used to include
library code into the Rake build process used by RubyMotion.
`BW.require` is similar to ruby's standard `require` method with
two major changes:
- it can take a file pattern as used by [`Dir.glob`](http://ruby-doc.org/core-1.9.3/Dir.html#method-c-glob).
- it can be passed a block to manipulate dependencies.
If a block is passed to `BW.require` it is evaluated in the context
of `BW::Requirement` and thus has access to all it's class methods.
The most common use cases are setting file dependencies:
```ruby
BW.require('motion/core/**/*.rb') do
file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
end
```
and specifying frameworks that need to be included at build time:
```ruby
BW.require('motion/**/*.rb') do
file('motion/address_book.rb').uses_framework 'Addressbook'
end
```
### Part the second: `motion/`
Inside the `motion` directory you'll see the actual implementation code
which is compiled into RubyMotion projects that are using BubbleWrap.
- `motion/core` contains "core" extension, things that the developers
reasonably think should be included in every BubbleWrap using project.
Careful consideration should be taken when making changes to the
contents and test coverage (in `spec/core`) must be updated to match.
This can be included in your project by requiring `bubble-wrap` or
`bubble-wrap/core` in your project `Rakefile`.
- `motion/http` contains the "http" extension. This can be included
by requiring `bubble-wrap/http` in your project `Rakefile`.
- `motion/test_suite_delegate` contains a simple `AppDelegate` which
can be used to enable the `rake spec` to run when developing a
BubbleWrap gem. Using `require 'bubble-wrap/test'` will include
it in the build process and also configure the app delegate to point
to `TestSuiteDelegate`. See the [BubbleWrap gem guide](gem.html) for
more information.
#### Your project here
If you think that your project would be of interest to the large number
of RubyMotion users that use BubbleWrap in their daily development then
feel free to fork [the repository on GitHub](https://github.com/mattetti/BubbleWrap)
and send us a pull request.
You should place your implementation files in a subdirectory of `motion`
(eg `motion/my_awesome_project`), your tests in a subdirectory of `spec`
(eg `spec/my_awesome_project`) and you can create a require file in
`lib/bubble-wrap` for example `lib/bubble-wrap/my_awesome_project.rb`:
```ruby
require 'bubble-wrap/loader'
BW.require 'motion/my_awesome_project.rb'
```
People will then be able to use it by adding:
```ruby
require 'bubble-wrap/my_awesome_project'
```
to their project's `Rakefile`
## Go forth and conquer!
The developers wish to thank you so much for taking the time
to improve BubbleWrap and by extension the RubyMotion
ecosystem. You're awesome!
================================================
FILE: LICENSE
================================================
LICENCE
MIT: http://mattaimonetti.mit-license.org
------------------------------------------------
The MIT License (MIT)
Copyright © 2012 Matt Aimonetti <matt.aimonetti@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# BubbleWrap for RubyMotion
A collection of (tested) helpers and wrappers used to wrap Cocoa Touch and AppKit code and provide more Ruby like APIs.
[](https://codeclimate.com/github/rubymotion/BubbleWrap)
[](https://travis-ci.org/rubymotion/BubbleWrap)
[](http://badge.fury.io/rb/bubble-wrap)
## Installation
```ruby
gem install bubble-wrap
```
## Setup
1. Edit the `Rakefile` of your RubyMotion project and add the following require line:
```ruby
require 'bubble-wrap'
```
If you use Bundler:
```ruby
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:
```ruby
require 'bubble-wrap/rss_parser'
```
If you wish to only include the `Reactor` wrapper:
```ruby
require 'bubble-wrap/reactor'
```
If you wish to only include the UI-related wrappers:
```ruby
require 'bubble-wrap/ui'
```
If you wish to only include the `Camera` wrapper:
```ruby
require 'bubble-wrap/camera'
```
If you wish to only include the `Location` wrapper:
```ruby
require 'bubble-wrap/location'
```
If you wish to only include the `Media` wrapper:
```ruby
require 'bubble-wrap/media'
```
If you wish to only include the `Mail` wrapper:
```ruby
require 'bubble-wrap/mail'
```
If you wish to only include the `SMS` wrapper:
```ruby
require 'bubble-wrap/sms'
```
If you wish to only include the `Motion` (CoreMotion) wrapper:
```ruby
require 'bubble-wrap/motion'
```
If you wish to only include the `NetworkIndicator` wrapper:
```ruby
require 'bubble-wrap/network-indicator'
```
If you want to include everything (ie kitchen sink mode) you can save time and do:
```ruby
require 'bubble-wrap/all'
```
You can also do this directly in your `Gemfile` like so:
```ruby
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 `+=`.
2. Now, you can use BubbleWrap extension in your app:
```ruby
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:
```ruby
BubbleWrap.create_uuid
=> "68ED21DB-82E5-4A56-ABEB-73650C0DB701"
```
Localization (using `NSBundle.mainBundle.localizedStringForKey`):
```ruby
BubbleWrap.localized_string(:foo, 'fallback')
=> "fallback"
```
Color conversion:
```ruby
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:
```ruby
BubbleWrap.debug?
=> false
BubbleWrap.debug = true
=> true
BubbleWrap.debug?
=> true
```
### App
A module with useful methods related to the running application
```ruby
> 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:
```ruby
> 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:
```ruby
# 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](https://github.com/mattt/AnyJSON).
```ruby
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.
```ruby
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:
```ruby
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:
``` ruby
> 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:
``` ruby
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:
``` ruby
class ExampleViewController < UIViewController
include BW::KVO
def viewDidLoad
@label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
@label.text = ""
view.addSubview @label
observe(@label, [:text, :textColor]) do |old_value, new_value, key_path|
puts "Hello from viewDidLoad for #{key_path}!"
end
end
end
```
Also you can use `observe!` method to register observer that will immediately
return initial value. Note that in this case only new value will be passed to
the block.
### String
The Ruby `String` class was extended to add `#camelize` and
`#underscore` methods.
```ruby
> "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.
```ruby
> Time.iso8601("2012-05-31T19:41:33Z")
=> 2012-05-31 21:41:33 +0200
```
## Location
Interface for Ruby-like GPS and compass access (the CoreLocation framework):
```ruby
> BW::Location.enabled? # Whether location services are enabled on the device
=> true
> BW::Location.authorized? # If your app is authorized to use location services
=> false
```
```ruby
BW::Location.get(purpose: 'We need to use your GPS because...') do |result|
p "From Lat #{result[:from].latitude}, Long #{result[:from].longitude}"
p "To Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
end
```
*Note: `result[:from]` will return `nil` the first time location services are started.*
The `:previous` key in the `BW::Location.get()` result hash will always return an array of zero or more additional `CLLocation` objects aside from the locations returned from the `:to` and `:from` hash keys. While in most scenarios this array will be empty, per [Apple's Documentation](https://developer.apple.com/library/IOs/documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/index.html#//apple_ref/occ/intfm/CLLocationManagerDelegate/locationManager:didUpdateLocations:) if there are deferred updates or multiple locations that arrived before they could be delivered, multiple locations will be returned in an order of oldest to newest.
```ruby
BW::Location.get_compass do |result|
p result[:magnetic_heading] # Heading towards magnetic north
p result[:true_heading] # Heading towards true north
p result[:accuracy] # Potential error between magnetic and true heading
p result[:timestamp] # Timestamp of the heading calculation
end
```
`BW::Location.get_significant` is also available, for monitoring significant location changes.
`BW::Location` also supports `get_once`-style methods, which will return the first result before ending the search:
```ruby
BW::Location.get_once(desired_accuracy: :three_kilometers, ...) do |result|
if result.is_a?(CLLocation)
p result.coordinate.latitude
p result.coordinate.longitude
else
p "ERROR: #{result[:error]}"
end
end
BW::Location.get_compass_once do |heading|
p result[:magnetic_heading]
p result[:true_heading]
p result[:accuracy]
p result[:timestamp]
end
```
### iOS 8 Location Requirements
iOS 8 introduced stricter location services requirements. Although BubbleWrap will handle most of this for you automatically, you are required to add a few key/value pairs to the `Info.plist`. Add these two lines to your `Rakefile` (with your descriptions, obviously):
```ruby
app.info_plist['NSLocationAlwaysUsageDescription'] = 'Description'
app.info_plist['NSLocationWhenInUseUsageDescription'] = 'Description'
```
*Note: you need both keys to use `get_once`, so it's probably best to just include both no matter what.* See [Apple's documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW18) on iOS 8 location services requirements for more information.
## Motion
Interface for the accelerometer, gyroscope, and magnetometer sensors (the
CoreMotion framework). You can access each sensor individually, or you can get
data from all of them at once using the `BW::Motion.device` interface, which
delegates to `CMMotionManager#deviceMotion`.
Each sensor has an `every` and `once` method. `every` expects a time interval,
and you will need to retain the object it returns and call `#stop` on it when
you are done with the data.
The `every` and `once` methods can accept a `:queue` option. The default value
is a queue that runs on the main loop, so that UI updates can be processed in
the block. This is useful, but not recommended by Apple, since the events can
come in at a high rate. If you want to use a background queue, you can either
specify an NSOperationQueue object, or you can use one of these symbols:
- `:main` - `NSOperationQueue.mainQueue`, this is the default value.
- `:background` - BubbleWrap will create a new `NSOperationQueue`.
- `:current` - BubbleWrap will use `NSOperationQueue.currentQueue`.
If you pass a string instead, a new queue will be created and its `name`
property will be set to that string.
The `CMDeviceMotion` interface (`BW::Motion.device`) accepts a `:reference`
option, which specifies the `CMAttitudeReferenceFrame`. The default value is
the same as the one that `CMMotionManager` uses, which is returned by the
`CMMotionManager#attitudeReferenceFrame` method. This option should be passed
to the `repeat`, `every` or `once` methods.
###### Accelerometer
```ruby
BW::Motion.accelerometer.available?
BW::Motion.accelerometer.data # returns CMAccelerometerData object or nil
# ask the CMMotionManager to update every 5 seconds
BW::Motion.accelerometer.every(5) do |result|
# result contains the following data (from CMAccelerometerData#acceleration):
p result[:data] # the CMAccelerometerData object
p result[:acceleration] # the CMAcceleration struct
p result[:x] # acceleration in the x direction
p result[:y] # " y direction
p result[:z] # " z direction
end
# every, start, and repeat all need to be stopped later.
BW::Motion.accelerometer.stop
# repeat, but don't set the interval
BW::Motion.accelerometer.repeat do |result|
end
# you can specify a :queue where the operations will be executed. See above for details
BW::Motion.accelerometer.every(5, queue: :background) { |result| ... }
BW::Motion.accelerometer.every(5, queue: :main) { |result| ... }
BW::Motion.accelerometer.every(5, queue: :current) { |result| ... }
BW::Motion.accelerometer.every(5, queue: 'my queue') { |result| ... }
BW::Motion.accelerometer.once do |result|
# ...
end
```
###### Gyroscope
```ruby
BW::Motion.gyroscope.available?
BW::Motion.gyroscope.data # returns CMGyroData object or nil
# ask the CMMotionManager to update every second.
BW::Motion.gyroscope.every(1) do |result|
# result contains the following data (from CMGyroData#rotationRate):
p result[:data] # the CMGyroData object
p result[:rotation] # the CMRotationRate struct
p result[:x] # rotation in the x direction
p result[:y] # " y direction
p result[:z] # " z direction
end
BW::Motion.gyroscope.stop
BW::Motion.gyroscope.once do |result|
# ...
end
```
###### Magnetometer
```ruby
BW::Motion.magnetometer.available?
BW::Motion.magnetometer.data # returns CMMagnetometerData object or nil
# ask the CMMotionManager to update every second
BW::Motion.magnetometer.every(1) do |result|
# result contains the following data (from CMMagnetometerData#magneticField):
p result[:data] # the CMMagnetometerData object
p result[:field] # the CMMagneticField struct
p result[:x] # magnetic field in the x direction
p result[:y] # " y direction
p result[:z] # " z direction
end
BW::Motion.magnetometer.stop
BW::Motion.magnetometer.once do |result|
# ...
end
```
###### Device Motion
This is an amalgam of all the motion sensor data.
```ruby
BW::Motion.device.available?
BW::Motion.device.data # returns CMDeviceMotion object or nil
BW::Motion.device.every(1) do |result|
# result contains the following data:
p result[:data] # the CMDeviceMotion object
# orientation data, from CMDeviceMotion#attitude
p result[:attitude] # the CMAttitude struct
p result[:roll]
p result[:pitch]
p result[:yaw]
# rotation data, from CMDeviceMotion#rotationRate
p result[:rotation] # the CMRotationRate struct
p result[:rotation_x]
p result[:rotation_y]
p result[:rotation_z]
# gravity+acceleration vector, from CMDeviceMotion#gravity
p result[:gravity] # the CMAcceleration struct
p result[:gravity_x]
p result[:gravity_y]
p result[:gravity_z]
# just the acceleration vector, from CMDeviceMotion#userAcceleration
p result[:acceleration] # the CMAcceleration struct
p result[:acceleration_x]
p result[:acceleration_y]
p result[:acceleration_z]
# the magnetic data, from CMDeviceMotion#magneticField
p result[:magnetic] # the CMCalibratedMagneticField struct
p result[:magnetic_field] # the CMMagneticField struct from the CMCalibratedMagneticField
p result[:magnetic_x]
p result[:magnetic_y]
p result[:magnetic_z]
p result[:magnetic_accuracy] # this will be a symbol, :low, :medium, :high, or nil if the magnetic data is uncalibrated
# less useful data from CMAttitude, unless you're into the whole linear algebra thing:
p result[:matrix] # CMAttitude#rotationMatrix
p result[:quarternion] # CMAttitude#quarternion
end
# the reference frame should be one of the CMAttitudeReferenceFrame constants...
ref = CMAttitudeReferenceFrameXArbitraryZVertical
# ... or one of these symbols: :arbitrary_z, :corrected_z, :magnetic_north, :true_north
ref = :corrected_z
BW::Motion.device.every(1, queue: :background, reference: ref) { |result| ... }
BW::Motion.device.once do |result|
# ...
end
```
## Media
Added wrapper for playing remote and local media. Available are `modal` and custom presentation styles:
```ruby
# Plays in your custom frame
local_file = NSURL.fileURLWithPath(File.join(NSBundle.mainBundle.resourcePath, 'test.mp3'))
BW::Media.play(local_file) do |media_player|
media_player.view.frame = [[10, 100], [100, 100]]
self.view.addSubview media_player.view
end
# Plays in an independent modal controller
BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
```
## Mail
Wrapper for showing an in-app mail composer view.
You should always determine if the device your app is running on is configured to send mail before displaying a mail composer window. `BW::Mail.can_send_mail?` will return `true` or `false`.
```ruby
# Opens as a modal in the current UIViewController
BW::Mail.compose(
delegate: self, # optional, defaults to rootViewController
to: [ "tom@example.com" ],
cc: [ "itchy@example.com", "scratchy@example.com" ],
bcc: [ "jerry@example.com" ],
html: false,
subject: "My Subject",
message: "This is my message. It isn't very long.",
animated: false
) do |result, error|
result.sent? # => boolean
result.canceled? # => boolean
result.saved? # => boolean
result.failed? # => boolean
error # => NSError
end
```
## SMS
Wrapper for showing an in-app message (SMS) composer view.
You should always determine if the device your app is running on can send SMS messages before displaying a SMS composer window. `BW::SMS.can_send_sms?` will return `true` or `false`.
```ruby
# Opens as a modal in the current UIViewController
BW::SMS.compose (
{
delegate: self, # optional, will use root view controller by default
to: [ "1(234)567-8910" ],
message: "This is my message. It isn't very long.",
animated: false
}) {|result, error|
result.sent? # => boolean
result.canceled? # => boolean
result.failed? # => boolean
error # => NSError
}
```
## NetworkIndicator
Wrapper for showing and hiding the network indicator (the status bar spinner).
```ruby
BW::NetworkIndicator.show # starts the spinner
BW::NetworkIndicator.hide # stops it
# the nice thing is if you call 'show' multiple times, the 'hide' method will
# not have any effect until you've called it the same number of times.
BW::NetworkIndicator.show
# ...somewhere else
BW::NetworkIndicator.show
# ...down the line
BW::NetworkIndicator.hide
# indicator is still visible
BW::NetworkIndicator.hide
# NOW the indicator is hidden!
# If you *really* want to hide the indicator immediately, you can call `reset!`
# but this is in no way encouraged.
BW::NetworkIndicator.reset!
# and for completeness, a check to see if the indicator is visible
BW::NetworkIndicator.visible?
```
## UI
### Gestures
Extra methods on `UIView` for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:
```ruby
view.when_tapped 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.
In order to prevent retain cycles due to strong references within the passed block, use the use_weak_callbacks flag so the blocks do not retain a strong reference to self:
```ruby
BubbleWrap.use_weak_callbacks = true
```
### UIViewController
A custom method was added to `UIViewController` to return the content
frame of a view controller.
### UIControl / UIButton
Helper methods to give `UIButton` a Ruby-like interface. Ex:
```ruby
button.when(UIControlEventTouchUpInside) do
self.view.backgroundColor = UIColor.redColor
end
```
The `#when` method also accepts bitwise combinations of events:
```ruby
button.when(UIControlEventTouchUpInside | UIControlEventTouchUpOutside) do
self.view.backgroundColor = UIColor.redColor
end
```
You can use symbols for events (but won't work with the bitwise operator):
```ruby
button.when(:touch_up_inside) do
self.view.backgroundColor = UIColor.redColor
end
button.when(:value_changed) do
self.view.backgroundColor = UIColor.blueColor
end
```
Set the use_weak_callbacks flag so the blocks do not retain a strong reference to self:
```ruby
BubbleWrap.use_weak_callbacks = true
```
### UIBarButtonItem
`BW::UIBarButtonItem` is a subclass of `UIBarButtonItem` with an natural Ruby syntax.
#### Constructors
Instead specifying a target-action pair, each constructor method accepts an optional block. When the button is tapped, the block is executed.
```ruby
BW::UIBarButtonItem.system(:save) do
# ...
end
title = "Friends"
BW::UIBarButtonItem.styled(:plain, title) do
# ...
end
image = UIImage.alloc.init
BW::UIBarButtonItem.styled(:bordered, image) do
# ...
end
image = UIImage.alloc.init
landscape = UIImage.alloc.init
BW::UIBarButtonItem.styled(:bordered, image, landscape) do
# ...
end
view = UIView.alloc.init
BW::UIBarButtonItem.custom(view) do
# ...
end
# NOTE: The block is attached to the view as a single tap gesture recognizer.
```
The `.new` constructor provides a flexible, builder-style syntax.
```ruby
options = { :system => :save }
BW::UIBarButtonItem.new(options) do
# ...
end
options = { :styled => :plain, :title => "Friends" }
BW::UIBarButtonItem.new(options) do
# ...
end
options = { :styled => :bordered, :image => UIImage.alloc.init }
BW::UIBarButtonItem.new(options) do
# ...
end
options = {
:styled => :bordered,
:image => UIImage.alloc.init,
:landscape => UIImage.alloc.init
}
BW::UIBarButtonItem.new(options) do
# ...
end
options = { :custom => UIView.alloc.init }
BW::UIBarButtonItem.new(options) do
# ...
end
# NOTE: The block is attached to the view as a single tap gesture recognizer.
```
#### Button types
The `.styled` button types are:
```ruby
:plain
:bordered
:done
```
And the `.system` button types are:
```ruby
:done
:cancel
:edit
:save
:add
:flexible_space
:fixed_space
:compose
:reply
:action
:organize
:bookmarks
:search
:refresh
:stop
:camera
:trash
:play
:pause
:rewind
:fast_forward
:undo
:redo
:page_curl
```
### UIActivityViewController
`BW::UIActivityViewController` is a subclass of `UIActivityViewController` with an natural Ruby syntax.
You can initiate a `UIActivityViewController` with or without a completion handler block. For more information on `UIActivityViewController`s, see [Apple's documentation](https://developer.apple.com/library/ios/documentation/uikit/reference/UIActivityViewController_Class/Reference/Reference.html).
```ruby
# Without a completion handler
BW::UIActivityViewController.new(
items: "Some Text", # or ["Some Text", NSURL.URLWithString('http://www.rubymotion.com')] or a UIImage
animated: true, # Defaults to true
excluded: :add_to_reading_list # One item or an array
)
# With completion handler
BW::UIActivityViewController.new(
items: "Some Text",
animated: true,
excluded: [:add_to_reading_list, :print, :air_drop]
) do |activity_type, completed|
puts "completed with activity: #{activity_type} - finished?: #{completed}"
end
```
Built in activities that can be passed to the `excluded` option are defined as `UIActivity` class `UIActivityType` constants:
```ruby
:post_to_facebook
:post_to_twitter
:post_to_weibo
:message
:mail
:print
:copy_to_pasteboard
:assign_to_contact
:save_to_camera_roll
:add_to_reading_list
:post_to_flickr
:post_to_vimeo
:post_to_tencent_weibo
:air_drop
```
## RSS Parser
**Since: > version 1.0.0**
The RSS Parser provides an easy interface to consume RSS feeds in an
asynchronous (non blocking) way.
```ruby
feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
feed_parser.parse do |item|
# called asynchronously as items get parsed
p item.title
end
```
The yielded RSS item is of type `RSSParser::RSSItem` and has the
following attributes:
* title
* description
* link
* guid
* pubDate
* enclosure
The item can be converted into a hash by calling `to_hash` on it.
### Delegate
**Since: > version 1.0.0**
You can also designate a delegate to the parser and implement change
state callbacks:
```ruby
feed_parser = BW::RSSParser.new("http://feeds.feedburner.com/sdrbpodcast")
feed_parser.delegate = self
feed_parser.parse do |item|
p item.title
end
# Delegate method
def when_parser_initializes
p "The parser is ready!"
end
def when_parser_parses
p "The parser started parsing the document"
end
def when_parser_is_done
p "The feed is entirely parsed, congratulations!"
end
def when_parser_errors
p "The parser encountered an error"
ns_error = feed_parser.parserError
p ns_error.localizedDescription
end
```
These delegate methods are optional, however, you might find the
`when_parser_is_done` callback useful if you collected all the items and
want to process all at once for instance.
### Parsing a remote content or actual data
You have the choice to initialize a parser instance with a string
representing an URL, an instance of `NSURL` or my specifying that the
passed param is some data to parse directly.
```ruby
# string representing an url:
feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
# a NSURL instance:
url = NSURL.alloc.initWithString("http://matt.aimonetti.net/atom.xml")
feed_parser = BW::RSSParser.new(url)
# Some data
feed = File.read('atom.xml')
feed_parser = BW::RSSParser.new(feed, true)
```
## Reactor
**Since: > version 1.0.0**
`BW::Reactor` is a simplified, mostly complete implementation of
the [Event Machine](http://rubyeventmachine.com/) API. In fact
`BW::Reactor` is aliased to `EM` in the runtime environment.
### Deferables
BubbleWrap provides both a `Deferrable` mixin and a `DefaultDeferrable`
class, which simply mixes in deferrable behaviour if you don't want to
implement your own.
A deferrable is an object with four states: unknown, successful, failure
and timeout. When you initially create a deferrable it is in an unknown
state, however you can assign callbacks to be run when the object
changes to either successful or failure state.
Using `delegate`, `errback_delegate` and `callback_delegate` you can link
deferrables together.
By default, callbacks will be made on the thread that the deferrable
succeeds/fails on. For multithreaded environments, it can be useful to use
EM::ThreadAwareDeferrable so that callbacks will be made on the threads they
are declared on.
#### Success
```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x6d859a0>
> d.callback { |what| puts "Great #{what}!" }
=> [#<Proc:0x6d8a1e0>]
> d.succeed "justice"
Great justice!
=> nil
```
#### Failure
```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> d.errback { |what| puts "Great #{what}!" }
=> [#<Proc:0x8bf3ef0>]
> d.fail "sadness"
Great sadness!
=> nil
```
#### Delegate
```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> delegate = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf5910>
> d.delegate delegate
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> delegate.callback { |*args| puts args }
=> [#<Proc:0x8bf3ef0>]
> d.succeed :passed
=> nil
=> [:passed]
```
#### DependentDeferrable
`DependentDeferrable` depends on children deferrables. A `DependentDeferrable`
succeeds only when every child succeeds and fails immediately when any child
fails
```ruby
> d1 = EM::DefaultDeferrable.new
=> #<BubbleWrap::Reactor::DefaultDeferrable:0x10c713750>
> d2 = EM::DefaultDeferrable.new
=> #<BubbleWrap::Reactor::DefaultDeferrable:0x10370bb10>
> d = EM::DependentDeferrable.on(d1, d2)
=> #<BubbleWrap::Reactor::DependentDeferrable:0x106c17b80>
> d.callback {|a, b| puts "a: #{a} b: #{b}"}
=> [#<Proc:0x103075210>]
> d1.succeed 'one', 'one more'
> d2.succeed :two
a: ["one", "one more"] b: [:two]
```
#### ThreadAwareDeferrable
```ruby
> d = EM::ThreadAwareDeferrable.new
=> #<BW::Reactor::ThreadAwareDeferrable:0x8bf3ee0>
> queue = Dispatch::Queue.new(:deferrable.to_s)
> queue.async do
> d.callback do |*args|
> Dispatch::Queue.current == queue
> => true # this is normally false
> end
> end
> d.succeed true
```
#### Timeout
```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf5910>
> d.errback { puts "Great scott!" }
=> [#<Proc:0x8bf6350>]
> d.timeout 2
=> #<BW::Reactor::Timer:0x6d920a0 @timer=#<__NSCFTimer:0x6d91990>>
# wait...
> Great scott!
```
### Timers
*All timers can be cancelled using `EM.cancel_timer`.*
#### One-shot timers
```ruby
> EM.add_timer 1.0 do
> puts "Great scott!"
> end
=> 146335904
> Great scott!
```
#### Periodic timers
```ruby
> count = 0
=> 0
> timer = EM.add_periodic_timer 1.0 do
> count = count + 1
> puts "Great scott!"
> (count < 10) || EM.cancel_timer(timer)
> end
=> 146046832
> Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
```
### Scheduling operations
You can use `EM.schedule` to schedule blocks to be executed
asynchronously. BubbleWrap deviates from the EventMachine
API here in that it also provides `EM.schedule_on_main` which
makes sure that the task is run asynchronously, but on the
application's main thread - this is necessary if you are
updating the user interface.
```ruby
> EM.schedule { puts Thread.current.object_id }
146027920
=> nil
> EM.schedule_on_main { puts Thread.current.object_id }
112222480
=> nil
```
### Deferrable operations
You can also use `EM.defer` in much the same way as `EM.schedule`
with one important difference, you can pass in a second `proc`
which will be called when the first has completed, and be passed
it's result as an argument. Just like `EM.schedule`, `EM.defer`
also has an `EM.defer_on_main` version.
```ruby
> operation = proc { 88 }
=> #<Proc:0x6d763c0>
> callback = proc { |speed| puts speed >= 88 ? "Time travel!" : "Conventional travel!" }
=> #<Proc:0x8bd3910>
> EM.defer(operation, callback)
=> nil
Time travel!
```
### Events
Although not part of the EventMachine API, BubbleWrap provides
an `Eventable` mixin for use instrumenting objects with simple
event triggering behaviour. `BW::Reactor` uses this
behind the scenes in several places, and as it's a very handy
idiom it is available as a public API.
```ruby
> o = Class.new { include EM::Eventable }.new
=> #<#<Class:0xab63f00>:0xab64430>
> o.on(:november_5_1955) { puts "Ow!" }
=> [#<Proc:0xad9bf00>]
> flux = proc{ puts "Flux capacitor!" }
=> #<Proc:0xab630f0>
> o.on(:november_5_1955, &flux)
=> [#<Proc:0xad9bf00>, #<Proc:0xab630f0>]
> o.trigger(:november_5_1955)
Ow!
Flux capacitor!
=> [nil, nil]
> o.off(:november_5_1955, &flux)
=> #<Proc:0xab630f0>
> o.trigger(:november_5_1955)
Ow!
=> [nil]
> o.on(:november_5_1955) { puts "Ow!" }
> o.on(:november_5_1955) { puts "Another Ow!" }
> o.off(:november_5_1955)
=> nil
```
# Contributing
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 you need help writing the tests,
send the pull request anyways and we'll try to help you out with that.
1. Create an issue in GitHub to make sure your PR will be accepted
2. Fork the BubbleWrap repository
3. Create your feature branch (`git checkout -b my-new-feature`)
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Write tests for your changes and ensure they pass locally (`bundle exec rake spec && bundle exec rake spec osx=true`)
6. Push to the branch (`git push origin my-new-feature`)
7. Create new Pull Request
================================================
FILE: Rakefile
================================================
$:.unshift("/Library/RubyMotion/lib")
$:.unshift("~/.rubymotion/rubymotion-templates")
require 'motion/project/template/gem/gem_tasks'
if ENV['osx']
require 'motion/project/template/osx'
else
require 'motion/project/template/ios'
end
Bundler.setup
Bundler.require
require 'bubble-wrap/all'
require 'bubble-wrap/test'
module Motion
module Project
class Config
def spec_files=(spec_files)
@spec_files = spec_files
end
end
end
end
Motion::Project::App.setup do |app|
app.name = 'testSuite'
app.identifier = 'io.bubblewrap.testSuite'
app.specs_dir = './spec/motion'
app.spec_files
if Motion::Project::App.osx?
app.spec_files -= Dir.glob("./spec/motion/**/ios/**.rb")
["font", "motion", "location", "media", "ui", "mail", "sms", "network-indicator"].each do |package|
app.spec_files -= Dir.glob("./spec/motion/#{package}/**/*.rb")
end
else
app.info_plist['NSLocationAlwaysUsageDescription'] = 'Description'
app.info_plist['NSLocationWhenInUseUsageDescription'] = 'Description'
app.spec_files -= Dir.glob("./spec/motion/**/osx/**.rb")
end
app.version = '1.2.3'
app.short_version = '3.2.1'
end
namespace :spec do
task :lib do
sh "bacon #{Dir.glob("spec/lib/**/*_spec.rb").join(' ')}"
end
task :motion => 'spec'
task :all => [:lib, :motion]
end
================================================
FILE: bubble-wrap.gemspec
================================================
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/bubble-wrap/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ['Matt Aimonetti', 'Francis Chong', 'James Harton', 'Clay Allsopp', 'Dylan Markow', 'Jan Weinkauff', 'Marin Usalj']
gem.email = ['mattaimonetti@gmail.com', 'francis@ignition.hk', 'james@sociable.co.nz', 'clay.allsopp@gmail.com', 'dylan@dylanmarkow.com', 'jan@dreimannzelt.de', 'marin2211@gmail.com']
gem.description = 'RubyMotion wrappers and helpers (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
gem.summary = 'RubyMotion wrappers and helpers (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
gem.homepage = 'https://github.com/rubymotion-community/BubbleWrap'
gem.license = 'MIT'
gem.files = `git ls-files`.split($\)
gem.test_files = gem.files.grep(%r{^(test|spec|lib_spec|features)/})
gem.name = 'bubble-wrap'
gem.require_paths = ['lib']
gem.version = BubbleWrap::VERSION
gem.extra_rdoc_files = gem.files.grep(%r{motion})
gem.add_development_dependency 'mocha', '~> 0.11'
gem.add_development_dependency 'mocha-on-bacon', '~> 0.2'
gem.add_development_dependency 'bacon', '~> 1.2'
gem.add_development_dependency 'rake', '~> 10.0'
gem.add_development_dependency 'webstub', '~> 1.1'
end
================================================
FILE: lib/bubble-wrap/all.rb
================================================
require File.expand_path('../loader', __FILE__)
[
'core',
'font',
'location',
'mail',
'media',
'motion',
'network-indicator',
'reactor',
'rss_parser',
'sms',
'ui',
].each { |sub|
require File.expand_path("../#{sub}", __FILE__)
}
================================================
FILE: lib/bubble-wrap/camera.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("camera") do
BubbleWrap.require('motion/util/constants.rb')
BubbleWrap.require('motion/core/device.rb')
BubbleWrap.require('motion/core/device/*.rb')
BubbleWrap.require('motion/core/device/ios/*.rb') do
file('motion/core/device/ios/camera_wrapper.rb').depends_on 'motion/core/device/ios/camera.rb'
file('motion/core/device/ios/camera.rb').depends_on ['motion/core/ios/device.rb', 'motion/util/constants.rb']
file('motion/core/device/ios/camera.rb').uses_framework 'MobileCoreServices'
file('motion/core/device/ios/screen.rb').depends_on 'motion/core/ios/device.rb'
end
end
================================================
FILE: lib/bubble-wrap/core.rb
================================================
require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)
require 'bubble-wrap/loader'
BubbleWrap.require('motion/core.rb')
BubbleWrap.require('motion/core/*.rb') do
file('motion/core/pollute.rb').depends_on 'motion/core/ns_index_path.rb'
end
BubbleWrap.require('motion/core/device/*.rb')
BubbleWrap.require_ios do
BubbleWrap.require('motion/core/ios/**/*.rb')
BubbleWrap.require('motion/core/device/ios/**/*.rb')
require 'bubble-wrap/camera'
require 'bubble-wrap/ui'
end
BubbleWrap.require_osx do
BubbleWrap.require('motion/core/osx/**/*.rb')
BubbleWrap.require('motion/core/device/osx/**/*.rb')
end
================================================
FILE: lib/bubble-wrap/ext/motion_project_app.rb
================================================
module BubbleWrap
module Ext
module BuildTask
def self.extended(base)
base.instance_eval do
def setup_with_bubblewrap(*args, &block)
bw_config = proc do |app|
::BubbleWrap.before_config(app)
block.call(app) unless block.nil?
end
setup_without_bubblewrap *args, &bw_config
end
alias :setup_without_bubblewrap :setup
alias :setup :setup_with_bubblewrap
end
end
end
module Config
def config_with_bubblewrap
config_without_bubblewrap.tap do |c|
::BubbleWrap.after_config(c)
end
end
def self.extended(base)
singleton_class = class << base; self; end
singleton_class.send :alias_method, :config_without_bubblewrap, :config
singleton_class.send :alias_method, :config, :config_with_bubblewrap
end
end
module Platforms
def osx?
self.respond_to?(:template) && self.template == :osx
end
end
end
end
Motion::Project::App.extend(BubbleWrap::Ext::BuildTask)
Motion::Project::App.extend(BubbleWrap::Ext::Platforms)
Motion::Project::App.extend(BubbleWrap::Ext::Config)
================================================
FILE: lib/bubble-wrap/ext.rb
================================================
require 'bubble-wrap/ext/motion_project_app'
================================================
FILE: lib/bubble-wrap/font.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("font") do
BubbleWrap.require('motion/font/font.rb')
end
================================================
FILE: lib/bubble-wrap/loader.rb
================================================
unless defined?(Motion::Project::Config)
raise 'This file must be required within a RubyMotion project Rakefile.'
end
unless defined?(BubbleWrap::LOADER_PRESENT)
require 'bubble-wrap/version' unless defined?(VERSION)
if Gem::Version.new(Motion::Version) < Gem::Version.new(BubbleWrap::MIN_MOTION_VERSION)
raise "BubbleWrap #{BubbleWrap::VERSION} requires at least RubyMotion #{BubbleWrap::MIN_MOTION_VERSION}"
end
require 'bubble-wrap/ext'
require 'bubble-wrap/requirement'
module BubbleWrap
LOADER_PRESENT = true
module_function
def root
File.expand_path('../../../', __FILE__)
end
def require(file_spec, &block)
Requirement.scan(caller.first, file_spec, &block)
end
def require_ios(requirement = nil, &callback)
if !Motion::Project::App.osx?
callback.call
else
puts "bubble-wrap/#{requirement} requires iOS to use." if requirement
end
end
def require_osx(requirement = nil, &callback)
if Motion::Project::App.osx?
callback.call
else
puts "bubble-wrap/#{requirement} requires OS X to use." if requirement
end
end
def before_config(app)
app.files = ::BubbleWrap::Requirement.files(app.files)
app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
app.frameworks = ::BubbleWrap::Requirement.frameworks(app.frameworks)
end
def after_config(config)
return unless ::BubbleWrap::Requirement.frameworks.include?("CoreLocation")
BubbleWrap.require_ios do
ios8_files = 'motion/ios/8/location_constants.rb'
if config.send(:deployment_target).to_f >= 8.0
::BubbleWrap.require(ios8_files)
before_config(config)
else
config.files = config.files.reject {|s|
s.include?(ios8_files)
}
end
end
end
end
BW = BubbleWrap unless defined?(BW)
BW.require 'motion/shortcut.rb'
BW.require 'lib/bubble-wrap/version.rb'
BW.require 'motion/util/deprecated.rb'
end
================================================
FILE: lib/bubble-wrap/location.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("location") do
BubbleWrap.require('motion/util/constants.rb')
BubbleWrap.require('motion/core/string.rb')
BubbleWrap.require('motion/location/**/*.rb') do
file('motion/location/pollute.rb').depends_on 'motion/location/location.rb'
file('motion/location/location.rb').depends_on 'motion/util/constants.rb'
file('motion/location/location.rb').uses_framework('CoreLocation')
end
end
================================================
FILE: lib/bubble-wrap/mail.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("mail") do
BubbleWrap.require('motion/core/app.rb')
BubbleWrap.require('motion/mail/**/*.rb') do
file('motion/mail/mail.rb').depends_on('motion/mail/result.rb')
file('motion/mail/mail.rb').uses_framework('MessageUI')
end
end
================================================
FILE: lib/bubble-wrap/media.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("media") do
BubbleWrap.require('motion/core/app.rb')
BubbleWrap.require('motion/core/ios/app.rb')
BubbleWrap.require('motion/core/ios/device.rb')
BubbleWrap.require('motion/core/string.rb')
BubbleWrap.require('motion/core/ns_notification_center.rb')
BubbleWrap.require('motion/media/**/*.rb') do
file('motion/media/media.rb').depends_on('motion/media/player.rb')
file('motion/media/player.rb').depends_on 'motion/core/string.rb'
file('motion/media/player.rb').uses_framework('MediaPlayer')
end
end
================================================
FILE: lib/bubble-wrap/motion.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios('motion') do
BubbleWrap.require('motion/util/constants.rb')
BubbleWrap.require('motion/core/string.rb')
BubbleWrap.require('motion/motion/**/*.rb') do
file('motion/motion/motion.rb').depends_on 'motion/util/constants.rb'
file('motion/motion/accelerometer.rb').depends_on('motion/motion/motion.rb')
file('motion/motion/device_motion.rb').depends_on('motion/motion/motion.rb')
file('motion/motion/gyroscope.rb').depends_on('motion/motion/motion.rb')
file('motion/motion/magnetometer.rb').depends_on('motion/motion/motion.rb')
file('motion/motion/motion.rb').uses_framework('CoreMotion')
end
end
================================================
FILE: lib/bubble-wrap/network-indicator.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("network-indicator") do
BubbleWrap.require('motion/core/app.rb')
BubbleWrap.require('motion/network-indicator/**/*.rb')
end
================================================
FILE: lib/bubble-wrap/reactor.rb
================================================
require 'bubble-wrap/loader'
BW.require 'motion/reactor.rb'
BW.require 'motion/reactor/**/*.rb' do
file('motion/reactor.rb').depends_on Dir.glob('motion/reactor/**/*.rb')
file('motion/reactor/timer.rb').depends_on 'motion/reactor/eventable.rb'
file('motion/reactor/periodic_timer.rb').depends_on 'motion/reactor/eventable.rb'
file('motion/reactor/deferrable.rb').depends_on ['motion/reactor/timer.rb', 'motion/reactor/future.rb']
file('motion/reactor/default_deferrable.rb').depends_on 'motion/reactor/deferrable.rb'
end
================================================
FILE: lib/bubble-wrap/requirement/path_manipulation.rb
================================================
module BubbleWrap
class Requirement
module PathManipulation
def convert_caller_to_root_path(path)
path = convert_caller_to_path path
path = convert_to_absolute_path path
strip_up_to_last_lib path
end
def convert_caller_to_path(string)
chunks = string.split(':')
if chunks.size >= 3
string = chunks[0..-3].join(':')
string = File.dirname(string)
end
string
end
def convert_to_absolute_path(path)
File.expand_path(path)
end
def strip_up_to_last_lib(path)
if path =~ /\/lib$/
path = path.gsub(/\/lib$/, "")
else
path = path.split('lib')
path = if path.size > 1
path[0..-2].join('lib')
else
path[0]
end
path = path[0..-2] if path[-1] == '/'
end
path
end
def convert_to_relative(path,root)
path = path.gsub(root,'')
path = path[1..-1] if path[0] == '/'
path
end
end
end
end
================================================
FILE: lib/bubble-wrap/requirement.rb
================================================
require 'bubble-wrap/requirement/path_manipulation'
module BubbleWrap
class Requirement
extend PathManipulation
include PathManipulation
attr_accessor :file, :root
attr_writer :file_dependencies
def initialize(file,root)
self.file = file
self.root = root
end
def relative
convert_to_relative(file, root)
end
def depends_on(file_or_paths)
paths = file_or_paths.respond_to?(:each) ? file_or_paths : [ file_or_paths ]
self.file_dependencies += paths.map do |f|
f = self.class.file(f) unless f.is_a? Requirement
f unless f.file == file
end.compact
self.file_dependencies.uniq!(&:to_s)
end
def uses_framework(framework_name)
self.frameworks << framework_name
end
def dependencies
return {} if file_dependencies.empty?
{ file => file_dependencies.map(&:to_s) }
end
def to_s
file
end
def file_dependencies
@file_dependencies ||= []
end
def frameworks
@frameworks ||= []
end
class << self
attr_accessor :paths
def scan(caller_location, file_spec, &block)
root = convert_caller_to_root_path caller_location
self.paths ||= {}
Dir.glob(File.expand_path(file_spec, root)).each do |file|
p = new(file,root)
self.paths[p.relative] = p
p.depends_on('motion/shortcut.rb') unless p.relative == 'motion/shortcut.rb'
end
self.class_eval(&block) if block
end
def file(relative)
paths.fetch(relative)
end
def files(app_files=nil)
files = paths.values.map(&:to_s)
files += app_files if app_files
files.uniq
end
def clear!
paths.select! { |k,v| v.relative == 'motion/shortcut.rb' }
end
def files_dependencies
deps = {}
paths.each_value do |file|
deps.merge! file.dependencies
end
deps
end
def frameworks(app_frameworks=nil)
frameworks = ['Foundation', 'CoreGraphics'] +
paths.values.map(&:frameworks)
frameworks += app_frameworks if app_frameworks
frameworks.flatten.compact.sort.uniq
end
end
end
end
================================================
FILE: lib/bubble-wrap/rss_parser.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require('motion/rss_parser.rb')
================================================
FILE: lib/bubble-wrap/sms.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("sms") do
BubbleWrap.require('motion/core/app.rb')
BubbleWrap.require('motion/sms/**/*.rb') do
file('motion/sms/sms.rb').depends_on('motion/sms/result.rb')
file('motion/sms/sms.rb').uses_framework('MessageUI')
end
end
================================================
FILE: lib/bubble-wrap/test.rb
================================================
require 'webstub'
require 'bubble-wrap/loader'
BW.require 'motion/util/*.rb'
BW.require 'motion/test_suite_delegate.rb'
Motion::Project::App.setup do |app|
app.development do
if Motion::Project::App.osx?
app.delegate_class = 'TestSuiteOSXDelegate'
else
app.delegate_class = 'TestSuiteDelegate'
end
end
end
================================================
FILE: lib/bubble-wrap/ui.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("ui") do
BubbleWrap.require('motion/util/constants.rb')
BubbleWrap.require('motion/ui/**/*.rb') do
file('motion/ui/pollute.rb').depends_on %w(
motion/ui/ui_control_wrapper.rb
motion/ui/ui_view_wrapper.rb
motion/ui/ui_view_controller_wrapper.rb
)
end
end
================================================
FILE: lib/bubble-wrap/version.rb
================================================
module BubbleWrap
VERSION = '1.9.7' unless defined?(BubbleWrap::VERSION)
MIN_MOTION_VERSION = '3.12'
end
================================================
FILE: lib/bubble-wrap.rb
================================================
require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)
require File.expand_path('../bubble-wrap/core', __FILE__)
================================================
FILE: motion/core/app.rb
================================================
# Provides a module to store global states
#
module BubbleWrap
module App
include BubbleWrap::Deprecated
module_function
# Returns the application's document directory path where users might be able to upload content.
# @return [String] the path to the document directory
def documents_path
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
end
# Returns the application resource path where resource located
# @return [String] the application main bundle resource path
def resources_path
NSBundle.mainBundle.resourcePath
end
# Returns the default notification center
# @return [NSNotificationCenter] the default notification center
def notification_center
NSNotificationCenter.defaultCenter
end
def user_cache
NSUserDefaults.standardUserDefaults
end
deprecated :user_cache, "2.0.0"
# Executes a block after a certain delay
# Usage example:
# App.run_after(0.5) { p "It's #{Time.now}" }
def run_after(delay,&block)
NSTimer.scheduledTimerWithTimeInterval( delay,
target: block,
selector: "call:",
userInfo: nil,
repeats: false)
end
@states = {}
def states
@states
end
def info_plist
NSBundle.mainBundle.infoDictionary
end
def name
info_plist['CFBundleDisplayName']
end
def identifier
NSBundle.mainBundle.bundleIdentifier
end
def version
info_plist['CFBundleVersion']
end
def short_version
info_plist['CFBundleShortVersionString']
end
# @return [NSLocale] locale of user settings
def current_locale
languages = NSLocale.preferredLanguages
if languages.count > 0
return NSLocale.alloc.initWithLocaleIdentifier(languages.first)
else
return NSLocale.currentLocale
end
end
# the current application environment : development, test, release
def environment
RUBYMOTION_ENV
end
def development?
environment == 'development'
end
def test?
environment == 'test'
end
def release?
environment == 'release'
end
def osx?
Kernel.const_defined?(:NSApplication)
end
def ios?
Kernel.const_defined?(:UIApplication)
end
end
end
::App = BubbleWrap::App unless defined?(::App)
================================================
FILE: motion/core/device/ios/camera.rb
================================================
# Provides a nice DSL for interacting with the standard
# UIImagePickerController
#
module BubbleWrap
module Device
class Camera
module Error
SOURCE_TYPE_NOT_AVAILABLE=0
INVALID_MEDIA_TYPE=1
MEDIA_TYPE_NOT_AVAILABLE=2
INVALID_CAMERA_LOCATION=3
CANCELED=1000
end
Constants.register UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera,
UIImagePickerControllerSourceTypeSavedPhotosAlbum
Constants.register UIImagePickerControllerQualityTypeHigh,
UIImagePickerControllerQualityTypeMedium,
UIImagePickerControllerQualityTypeLow,
UIImagePickerControllerQualityType640x480,
UIImagePickerControllerQualityTypeIFrame1280x720,
UIImagePickerControllerQualityTypeIFrame960x540
MEDIA_TYPE_HASH = {movie: KUTTypeMovie, image: KUTTypeImage}
CAMERA_LOCATIONS = [:front, :rear, :none]
# The camera location; if :none, then we can't use source_type: :camera
# in #picture
# [:front, :rear, :none]
attr_accessor :location
def self.front
return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
@front ||= Camera.new(:front)
end
def self.rear
return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
@rear ||= Camera.new(:rear)
end
def self.available?
UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera)
end
# For uploading photos from the library.
class << self
def any
@any ||= Camera.new
end
alias_method "photo_library", "any"
end
def popover_from(view)
@popover_in_view = view
self
end
def initialize(location = :none)
self.location = location
end
def location=(location)
if not CAMERA_LOCATIONS.member? location
raise Error::INVALID_CAMERA_LOCATION, "#{location} is not a valid camera location"
end
@location = location
end
def flash?
return false if self.location == :none
UIImagePickerController.isFlashAvailableForCameraDevice(camera_device)
end
# @param [Hash] options to open the UIImagePickerController with
# the form {
# source_type: :photo_library, :camera, or :saved_photos_album; default :photo_library
# media_types: [] containing :image and/or :movie; default [:image]
# allows_editing: true/false; default false
# animated: true/false; default true
# on_dismiss: lambda; default nil
# }
#
# @param [UIViewController] view controller from which to present the image picker;
# if nil, uses the keyWindow's rootViewController.
#
# @block for callback. takes one argument.
# - On error or cancelled, is called with a hash {error: BW::Camera::Error::<Type>}
# - On success, is called with a hash with a possible set of keys
# [:media_type, :original_image, :edited_image, :crop_rect, :media_url,
# :reference_url, :media_metadata]
#
# Example
# BW::Camera.picture(source_type: :photo_library, media_types: [:image]) do |result|
# image_view = UIImageView.alloc.initWithImage(result[:original_image])
# end
def picture(options = {}, presenting_controller = nil, &block)
@callback = block
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
@options = {
allows_editing: false,
animated: true,
on_dismiss: false,
media_types: [:image],
dismiss_completed: nil,
video_quality: :medium,
video_maximum_duration: 600
}.merge(options)
# If we're using Camera.any, by default use photo library
if !@options.has_key?(:source_type) and self.location == :none
@options[:source_type] = :photo_library
# If we're using a real Camera, by default use the camera.
elsif !@options.has_key?(:source_type)
@options[:source_type] = :camera
end
source_type_readable = options[:source_type]
source_type = Constants.get("UIImagePickerControllerSourceType", @options[:source_type])
if not Camera.source_type_available?(source_type)
error(Error::SOURCE_TYPE_NOT_AVAILABLE) and return
end
media_types = @options[:media_types].collect { |mt| symbol_to_media_type(mt) }
if media_types.member? nil
error(Error::INVALID_MEDIA_TYPE) and return
end
media_types.each { |media_type|
if not Camera.media_type_available?(media_type, for_source_type: source_type)
error(Error::MEDIA_TYPE_NOT_AVAILABLE) and return
end
}
self.picker.delegate = self
self.picker.sourceType = source_type
self.picker.mediaTypes = media_types
self.picker.allowsEditing = @options[:allows_editing]
self.picker.videoQuality = Constants.get("UIImagePickerControllerQualityType", @options[:video_quality])
self.picker.videoMaximumDuration = @options[:video_maximum_duration]
if source_type_readable == :camera && ![:front, :rear].member?(self.location)
raise Error::INVALID_CAMERA_LOCATION, "Can't use camera location #{self.location} with source type :camera"
end
if source_type_readable == :camera
self.picker.cameraDevice = camera_device
end
presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
presenting_controller ||= App.window.rootViewController
# use popover for iPad (ignore on iPhone)
if Device.ipad? and source_type==UIImagePickerControllerSourceTypePhotoLibrary and @popover_in_view
@popover = UIPopoverController.alloc.initWithContentViewController(picker)
@popover.presentPopoverFromRect(@popover_in_view.bounds, inView:@popover_in_view, permittedArrowDirections:UIPopoverArrowDirectionAny, animated:@options[:animated])
else
presenting_controller.presentViewController(self.picker, animated:@options[:animated], completion: lambda {})
end
end
# iPad popover is dismissed
def popoverControllerDidDismissPopover(popoverController)
@popover = nil
end
##########
# UIImagePickerControllerDelegate Methods
def imagePickerControllerDidCancel(picker)
error(Error::CANCELED)
dismiss
end
# Takes the default didFinishPickingMediaWithInfo hash,
# transforms the keys to be nicer symbols of :this_form
# instead of UIImagePickerControllerThisForm, and then sends it
# to the callback
def imagePickerController(picker, didFinishPickingMediaWithInfo: info)
callback_info = {}
info.keys.each { |k|
nice_key = k.gsub("UIImagePickerController", "").underscore.to_sym
val = info[k]
callback_info[nice_key] = val
}
if media_type = callback_info[:media_type]
callback_info[:media_type] = media_type_to_symbol(media_type)
end
@callback.call(callback_info)
dismiss
# iPad popover? close it
if @popover
@popover.dismissPopoverAnimated(@options[:animated])
@popover = nil
end
end
##########
# Short Helper Methods
def picker
@picker_klass ||= UIImagePickerController
@picker ||= @picker_klass.alloc.init
end
def dismiss
if @options[:on_dismiss]
@options[:on_dismiss].call(self.picker)
return
end
self.picker.dismissViewControllerAnimated(@options[:animated], completion: @options[:dismiss_completed])
end
# @param [UIImagePickerControllerSourceType] source_type to check
def self.source_type_available?(source_type)
UIImagePickerController.isSourceTypeAvailable(source_type)
end
# @param [String] (either KUTTypeMovie or KUTTypeImage)
# @param [UIImagePickerControllerSourceType]
def self.media_type_available?(media_type, for_source_type: source_type)
UIImagePickerController.availableMediaTypesForSourceType(source_type).member? media_type
end
private
def camera_device
Constants.get("UIImagePickerControllerCameraDevice", self.location)
end
# ex media_type_to_symbol(KUTTypeMovie) => :movie
def media_type_to_symbol(media_type)
MEDIA_TYPE_HASH.invert[media_type]
end
# ex symbol_to_media_type(:movie) => :KUTTypeMovie
def symbol_to_media_type(symbol)
MEDIA_TYPE_HASH[symbol]
end
def error(type)
@callback.call({ error: type })
end
end
end
end
::Camera = BubbleWrap::Device::Camera unless defined?(::Camera)
================================================
FILE: motion/core/device/ios/camera_wrapper.rb
================================================
module BubbleWrap
module Device
module CameraWrapper
module_function
# The front-facing camera used to capture media
# @return [Device::Camera, NilClass] a Camera will be returned if there is a front camera, nil otherwise
def front
@front ||= BubbleWrap::Device::Camera.front
end
# Verifies that the device running has a front facing camera.
# @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
def front?
!!front
end
# The rear-facing camera used to capture media
# @return [Device::Camera, NilClass] a Camera will be returned if there is a rear camera, nil otherwise
def rear
@rear ||= BubbleWrap::Device::Camera.rear
end
# Verifies that the device running has a rear facing camera.
# @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
def rear?
!!rear
end
# A Device::Camera used to capture media; by default it will use the :photo_library source type
# See Device::Camera docs for more source type options.
# @return [Device::Camera] a Camera will always be returned.
def any
@any ||= BubbleWrap::Device::Camera.any
end
# alias for any
def photo_library
any
end
# Should always return true, since picking images from *some* source is always possible
# @return [TrueClass]
def any?
!!any
end
# Verifies that the device running has a physical camera.
# @return [TrueClass, FalseClass] true will be returned if the device has a physical camera, false otherwise.
def available?
BubbleWrap::Device::Camera.available?
end
end
end
end
================================================
FILE: motion/core/device/ios/screen.rb
================================================
module BubbleWrap
module Device
module Screen
module_function
# Certifies that the device running the app has a Retina display
# @return [TrueClass, FalseClass] true will be returned if the device has a Retina display, false otherwise.
def retina?(screen=UIScreen.mainScreen)
if screen.respondsToSelector('displayLinkWithTarget:selector:') && screen.scale == 2.0
true
else
false
end
end
# Figure out the current physical orientation of the device
# @return [:portrait, :portrait_upside_down, :landscape_left, :landscape_right, :face_up, :face_down, :unknown]
def orientation(device_orientation=UIDevice.currentDevice.orientation, fallback=true)
case device_orientation
when UIDeviceOrientationPortrait then :portrait
when UIDeviceOrientationPortraitUpsideDown then :portrait_upside_down
when UIDeviceOrientationLandscapeLeft then :landscape_left
when UIDeviceOrientationLandscapeRight then :landscape_right
when UIDeviceOrientationFaceUp then :face_up
when UIDeviceOrientationFaceDown then :face_down
else
# In some cases, the accelerometer can't get an accurate read of orientation so we fall back on the orientation of
# the status bar.
if fallback && (device_orientation != UIApplication.sharedApplication.statusBarOrientation)
orientation(UIApplication.sharedApplication.statusBarOrientation)
else
:unknown
end
end
end
# Figure out the current orientation of the interface
# @return [:portrait, :portrait_upside_down, :landscape_left, :landscape_right]
def interface_orientation(device_orientation=UIDevice.currentDevice.orientation, fallback=true)
case device_orientation
when UIInterfaceOrientationPortrait then :portrait
when UIInterfaceOrientationPortraitUpsideDown then :portrait_upside_down
when UIInterfaceOrientationLandscapeLeft then :landscape_left
when UIInterfaceOrientationLandscapeRight then :landscape_right
else
# In some cases, the accelerometer can't get an accurate read of orientation so we fall back on the orientation of
# the status bar.
if fallback && (device_orientation != UIApplication.sharedApplication.statusBarOrientation)
orientation(UIApplication.sharedApplication.statusBarOrientation)
else
:unknown
end
end
end
# The width of the device's screen.
# The real resolution is dependant on the scale
# factor (see `retina?`) but the coordinate system
# is in non-retina pixels. You can get pixel
# accuracy by using half-coordinates.
# This is a Float
def width
UIScreen.mainScreen.bounds.size.width
end
# The height of the device's screen.
# The real resolution is dependant on the scale
# factor (see `retina?`) but the coordinate system
# is in non-retina pixels. You can get pixel
# accuracy by using half-coordinates.
# This is a Float
def height
UIScreen.mainScreen.bounds.size.height
end
# The same as `.width` and `.height` but
# compensating for screen rotation (which
# can do your head in).
def width_for_orientation(o=orientation)
return height if (o == :landscape_left) || (o == :landscape_right)
width
end
# The same as `.width` and `.height` but
# compensating for screen rotation (which
# can do your head in).
def height_for_orientation(o=orientation)
return width if (o == :landscape_left) || (o == :landscape_right)
height
end
end
end
end
================================================
FILE: motion/core/device/osx/screen.rb
================================================
module BubbleWrap
module Device
module Screen
module_function
# Certifies that the device running the app has a Retina display
# @return [TrueClass, FalseClass] true will be returned if the device has a Retina display, false otherwise.
def retina?(screen=NSScreen.mainScreen)
if screen.respondsToSelector('backingScaleFactor') && screen.backingScaleFactor == 2.0
true
else
false
end
end
end
end
end
================================================
FILE: motion/core/device/screen.rb
================================================
module BubbleWrap
module Device
module Screen
end
end
end
================================================
FILE: motion/core/device.rb
================================================
module BubbleWrap
module Device
module_function
# Shameless shorthand for accessing BubbleWrap::Screen
def screen
BubbleWrap::Device::Screen
end
# Delegates to BubbleWrap::Screen.retina?
def retina?
screen.retina?
end
end
end
::Device = BubbleWrap::Device unless defined?(::Device)
================================================
FILE: motion/core/ios/app.rb
================================================
module BubbleWrap
module App
module_function
# Opens an url (string or instance of `NSURL`)
# in the device's web browser or in the correspondent app for custom schemas
# Usage Example:
# App.open_url("http://matt.aimonetti.net")
# App.open_url("fb://profile")
def open_url(url)
unless url.is_a?(NSURL)
url = NSURL.URLWithString(url)
end
UIApplication.sharedApplication.openURL(url)
end
# Returns whether an app can open a given URL resource (string or instance of `NSURL`)
# Useful to check if certain apps are installed before calling to their custom schemas.
# Usage Example:
# App.open_url("fb://profile") if App.can_open_url("fb://")
def can_open_url(url)
unless url.is_a?(NSURL)
url = NSURL.URLWithString(url)
end
UIApplication.sharedApplication.canOpenURL(url)
end
# Displays a UIAlertView.
#
# title - The title as a String.
# args - The title of the cancel button as a String, or a Hash of options.
# (Default: { cancel_button_title: 'OK' })
# cancel_button_title - The title of the cancel button as a String.
# message - The main message as a String.
# block - Yields the alert object if a block is given, and does so before the alert is shown.
#
# Returns an instance of BW::UIAlertView
def alert(title, *args, &block)
options = { cancel_button_title: 'OK' }
options.merge!(args.pop) if args.last.is_a?(Hash)
if args.size > 0 && args.first.is_a?(String)
options[:cancel_button_title] = args.shift
end
options[:title] = title
options[:buttons] = options[:cancel_button_title]
options[:cancel_button_index] = 0 # FIXME: alerts don't have "Cancel" buttons
alert = UIAlertView.default(options)
yield(alert) if block_given?
alert.show
alert
end
# Return application frame
def frame
UIScreen.mainScreen.applicationFrame
end
# Main Screen bounds. Useful when starting the app
def bounds
UIScreen.mainScreen.bounds
end
# Application Delegate
def delegate
UIApplication.sharedApplication.delegate
end
# the Application object.
def shared
UIApplication.sharedApplication
end
def windows
UIApplication.sharedApplication.windows
end
# the Application Window
def window
normal_windows = App.windows.select { |w|
w.windowLevel == UIWindowLevelNormal
}
key_window = normal_windows.select {|w|
w == UIApplication.sharedApplication.keyWindow
}.first
key_window || normal_windows.first
end
end
end
================================================
FILE: motion/core/ios/device.rb
================================================
module BubbleWrap
module Device
module_function
# Verifies that the device running the app is an iPhone.
# @return [TrueClass, FalseClass] true will be returned if the device is an iPhone, false otherwise.
def iphone?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
idiom == UIUserInterfaceIdiomPhone
end
# Verifies that the device running the app is an iPad.
# @return [TrueClass, FalseClass] true will be returned if the device is an iPad, false otherwise.
def ipad?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
idiom == UIUserInterfaceIdiomPad
end
# Verifies that the device having a long screen (4 inch iPhone/iPod)
# @return [TrueClass, FalseClass] true will be returned if the device is an iPhone/iPod with 4 inche screen, false otherwise.
def long_screen?(idiom=UIDevice.currentDevice.userInterfaceIdiom, screen_height=UIScreen.mainScreen.bounds.size.height)
iphone?(idiom) && screen_height == 568.0
end
# Use this to make a DSL-style call for picking images
# @example Device.camera.front
# @return [Device::Camera::CameraWrapper]
def camera
BubbleWrap::Device::CameraWrapper
end
# Verifies that the device running has a front facing camera.
# @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
def front_camera?(picker=UIImagePickerController)
p "This method (front_camera?) is DEPRECATED. Transition to using Device.camera.front?"
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
end
# Verifies that the device running has a rear facing camera.
# @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
def rear_camera?(picker=UIImagePickerController)
p "This method (rear_camera?) is DEPRECATED. Transition to using Device.camera.rear?"
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
end
# Return whether app is being run in simulator
# @return [TrueClass, FalseClass] true will be returned if simulator, false otherwise.
def simulator?
@simulator_state ||= begin
if ios_version.to_i >= 9
NSBundle.mainBundle.bundlePath !~ /^(\/private)?\/var/
else
!(UIDevice.currentDevice.model =~ /simulator/i).nil?
end
end
end
def force_touch?
if defined?(UIForceTouchCapabilityAvailable) && defined?(UIScreen.mainScreen.traitCollection) && defined?(UIScreen.mainScreen.traitCollection.forceTouchCapability)
UIScreen.mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable
else
false
end
end
# Returns the IOS SDK version currently running (i.e. "5.1" or "6.0" etc)
# @return [String] the IOS SDK version currently running
def ios_version
UIDevice.currentDevice.systemVersion
end
# Returns an identifier unique to the vendor across the vendors app.
# @return [NSUUID]
def vendor_identifier
UIDevice.currentDevice.identifierForVendor
end
# Delegates to BubbleWrap::Screen.orientation
def orientation
screen.orientation
end
# Delegates to BubbleWrap::Screen.interface_orientation
def interface_orientation
screen.interface_orientation
end
end
end
================================================
FILE: motion/core/ios/ns_index_path.rb
================================================
module NSIndexPathWrap
def +(aNumber)
self.class.indexPathForRow(row+aNumber, inSection:section)
end
def -(aNumber)
self.class.indexPathForRow(row-aNumber, inSection:section)
end
end
================================================
FILE: motion/core/json.rb
================================================
module BubbleWrap
# Handles JSON encoding and decoding in a similar way Ruby 1.9 does.
module JSON
class ParserError < StandardError; end
# Parses a string or data object and converts it in data structure.
#
# @param [String, NSData] str_data the string or data to serialize.
# @raise [ParserError] If the parsing of the passed string/data isn't valid.
# @return [Hash, Array, NilClass] the converted data structure, nil if the incoming string isn't valid.
#
# TODO: support options like the C Ruby module does
def self.parse(str_data, &block)
return nil unless str_data
data = str_data.respond_to?('dataUsingEncoding:') ? str_data.dataUsingEncoding(NSUTF8StringEncoding) : str_data
opts = NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments
error = Pointer.new(:id)
obj = NSJSONSerialization.JSONObjectWithData(data, options:opts, error:error)
raise ParserError, error[0].description if error[0]
if block_given?
yield obj
else
obj
end
end
def self.generate(obj)
NSJSONSerialization.dataWithJSONObject(obj, options:0, error:nil).to_str
end
end
end
================================================
FILE: motion/core/kvo.rb
================================================
# Usage example:
#
# class ExampleViewController < UIViewController
# include BubbleWrap::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 "Changed #{old_value} to #{new_value}"
# end
# end
#
# end
#
# @see https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177i
module BubbleWrap
module KVO
class Registry
COLLECTION_OPERATIONS = [ NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement ]
OPTION_MAP = {
new: NSKeyValueChangeNewKey,
old: NSKeyValueChangeOldKey
}
attr_reader :callbacks, :keys
def initialize(value_keys = [:old, :new])
@keys = value_keys.inject([]) do |acc, key|
value_change_key = OPTION_MAP[key]
if value_change_key.nil?
raise RuntimeError, "Unknown value change key #{key}. Possible keys: #{OPTION_MAP.keys}"
end
acc << value_change_key
end
@callbacks = Hash.new do |hash, key|
hash[key] = Hash.new do |subhash, subkey|
subhash[subkey] = Array.new
end
end
end
def add(target, key_path, &block)
return if target.nil? || key_path.nil? || block.nil?
block.weak! if BubbleWrap.use_weak_callbacks?
callbacks[target][key_path.to_s] << block
end
def remove(target, key_path)
return if target.nil? || key_path.nil?
key_path = key_path.to_s
callbacks[target].delete(key_path)
# If there no key_paths left for target, remove the target key
if callbacks[target].empty?
callbacks.delete(target)
end
end
def registered?(target, key_path)
callbacks[target].has_key? key_path.to_s
end
def remove_all
callbacks.clear
end
def each_key_path
callbacks.each do |target, key_paths|
key_paths.each_key do |key_path|
yield target, key_path
end
end
end
private
def observeValueForKeyPath(key_path, ofObject: target, change: change, context: context)
key_paths = callbacks[target] || {}
blocks = key_paths[key_path] || []
args = change.values_at(*keys)
args << key_path
blocks.each do |block|
block.call(*args)
end
end
end
DEFAULT_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
IMMIDEATE_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
def observe(target = self, key_paths, &block)
key_paths = [key_paths].flatten
key_paths.each do |key_path|
if not observers_registry.registered?(target, key_path)
target.addObserver(observers_registry, forKeyPath:key_path, options:DEFAULT_OPTIONS, context:nil)
end
# Add block even if observer is registed, so multiplie blocks can be invoked.
observers_registry.add(target, key_path, &block)
end
end
def observe!(target = self, key_paths, &block)
key_paths = [key_paths].flatten
key_paths.each do |key_path|
registered = immediate_observers_registry.registered?(target, key_path)
immediate_observers_registry.add(target, key_path, &block)
# We need to first register the block, and then call addObserver, because
# observeValueForKeyPath will fire immedeately.
if not registered
target.addObserver(immediate_observers_registry, forKeyPath:key_path, options: IMMIDEATE_OPTIONS, context:nil)
end
end
end
def unobserve(target = self, key_paths)
remove_from_registry_if_exists(target, key_paths, observers_registry)
end
def unobserve!(target = self, key_paths)
remove_from_registry_if_exists(target, key_paths, immediate_observers_registry)
end
def unobserve_all
observers_registry.each_key_path do |target, key_path|
target.removeObserver(observers_registry, forKeyPath:key_path)
end
immediate_observers_registry.each_key_path do |target, key_path|
target.removeObserver(immediate_observers_registry, forKeyPath:key_path)
end
observers_registry.remove_all
immediate_observers_registry.remove_all
end
private
def observers_registry
@observers_registry ||= Registry.new
end
def immediate_observers_registry
@immediate_observers_registry ||= Registry.new([:new])
end
def remove_from_registry_if_exists(target, key_paths, registry)
key_paths = [key_paths].flatten
key_paths.each do |key_path|
if registry.registered?(target, key_path)
target.removeObserver(registry, forKeyPath:key_path)
registry.remove(target, key_path)
end
end
end
end
end
================================================
FILE: motion/core/ns_index_path.rb
================================================
module NSIndexPathWrap
# Gives access to an index at a given position.
# @param [Integer] position to use to fetch the index
# @return [Integer] the index for the given position
def [](position)
raise ArgumentError unless position.is_a?(Integer)
indexAtPosition(position)
end
# Provides an iterator taking a block following the common Ruby idiom.
# @param [Block]
# @return [NSIndexPath] the iterated object itself
def each
i = 0
until i == self.length
yield self.indexAtPosition(i)
i += 1
end
self
end
end
================================================
FILE: motion/core/ns_notification_center.rb
================================================
class NSNotificationCenter
def observers
@observers ||= []
end
def observe(name, object=nil, &proc)
proc.weak! if proc && BubbleWrap.use_weak_callbacks?
observer = self.addObserverForName(name, object:object, queue:NSOperationQueue.mainQueue, usingBlock:proc)
observers << observer
observer
end
def unobserve(observer)
return unless observers.include?(observer)
removeObserver(observer)
observers.delete(observer)
end
def post(name, object=nil, info=nil)
self.postNotificationName(name, object: object, userInfo: info)
end
end
================================================
FILE: motion/core/ns_url_request.rb
================================================
class NSURLRequest
# Provides a to_s method so we can use inspect in instances and get
# valuable information.
def to_s
"#<#{self.class}:#{self.object_id} - url: #{self.URL.description},
headers: #{self.allHTTPHeaderFields.inspect},
cache policy: #{self.cachePolicy}, Pipelining: #{self.HTTPShouldUsePipelining}, main doc url: #{mainDocumentURL},\
timeout: #{self.timeoutInterval}, network service type: #{self.networkServiceType} >"
end
end
================================================
FILE: motion/core/ns_user_defaults.rb
================================================
# Reopens the NSUserDefaults class to add Array like accessors
# @see https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html
class NSUserDefaults
# Retrieves the object for the passed key
def [](key)
self.objectForKey(key.to_s)
end
# Sets the value for a given key and save it right away.
def []=(key, val)
self.setObject(val, forKey: key.to_s)
self.synchronize
end
end
================================================
FILE: motion/core/osx/app.rb
================================================
module BubbleWrap
module App
module_function
# Opens an url (string or instance of `NSURL`)
# in the default web browser
# Usage Example:
# App.open_url("http://www.rubymotion.com")
def open_url(url)
url = NSURL.URLWithString(url) unless url.is_a?(NSURL)
NSWorkspace.sharedWorkspace.openURL(url)
end
# Application Delegate
def delegate
shared.delegate
end
# the Application object.
def shared
NSApplication.sharedApplication
end
end
end
================================================
FILE: motion/core/osx/device.rb
================================================
module BubbleWrap
module Device
module_function
end
end
================================================
FILE: motion/core/persistence.rb
================================================
# Persistence module built on top of NSUserDefaults
module BubbleWrap
module Persistence
module_function
def app_key
@app_key ||= BubbleWrap::App.identifier
end
def []=(key, value)
storage.setObject(value, forKey: storage_key(key))
storage.synchronize
end
def [](key)
value = storage.objectForKey storage_key(key)
# RubyMotion currently has a bug where the strings returned from
# standardUserDefaults are missing some methods (e.g. to_data).
# And because the returned object is slightly different than a normal
# String, we can't just use `value.is_a?(String)`
value.class.to_s == 'String' ? value.dup : value
end
def merge(values)
values.each do |key, value|
storage.setObject(value, forKey: storage_key(key))
end
storage.synchronize
end
def delete(key)
value = storage.objectForKey storage_key(key)
storage.removeObjectForKey(storage_key(key))
storage.synchronize
value
end
def storage
NSUserDefaults.standardUserDefaults
end
def storage_key(key)
"#{app_key}_#{key}"
end
def all
hash = storage.dictionaryRepresentation.select{|k,v| k.start_with?(app_key) }
new_hash = {}
hash.each do |k,v|
new_hash[k.sub("#{app_key}_", '')] = v
end
new_hash
end
end
end
::Persistence = BubbleWrap::Persistence unless defined?(::Persistence)
================================================
FILE: motion/core/pollute.rb
================================================
[
[NSIndexPath, NSIndexPathWrap]
].each do |base, wrapper|
base.send(:include, wrapper)
end
================================================
FILE: motion/core/string.rb
================================================
module BubbleWrap
# This module contains simplified version of the `camelize` and
# `underscore` methods from ActiveSupport, since these are such
# common operations when dealing with the Cocoa API.
module String
# Convert 'snake_case' into 'CamelCase'
def camelize(uppercase_first_letter = true)
string = self.dup
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
new_word = $2.downcase
new_word[0] = new_word[0].upcase
new_word = "/#{new_word}" if $1 == '/'
new_word
end
if uppercase_first_letter && uppercase_first_letter != :lower
string[0] = string[0].upcase
else
string[0] = string[0].downcase
end
string.gsub!('/', '::')
string
end
# Convert 'CamelCase' into 'snake_case'
def underscore
word = self.dup
word.gsub!(/::/, '/')
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!("-", "_")
word.downcase!
word
end
def to_url_encoded(encoding = nil, legacy = false)
if legacy
stringByAddingPercentEscapesUsingEncoding(encoding || NSUTF8StringEncoding)
else
encoding ||= KCFStringEncodingUTF8
encoding = CFStringConvertNSStringEncodingToEncoding(encoding) unless CFStringIsEncodingAvailable(encoding)
CFURLCreateStringByAddingPercentEscapes(nil, self, nil, "!*'();:@&=+$,/?%#[]", encoding)
end
end
def to_url_decoded(encoding = nil, legacy = false)
if legacy
stringByReplacingPercentEscapesUsingEncoding(encoding || NSUTF8StringEncoding)
else
if encoding
encoding = CFStringConvertNSStringEncodingToEncoding(encoding) unless CFStringIsEncodingAvailable(encoding)
CFURLCreateStringByReplacingPercentEscapesUsingEncoding(nil, self, nil, encoding)
else
CFURLCreateStringByReplacingPercentEscapes(nil, self, nil)
end
end
end
def to_encoded_data(encoding = NSUTF8StringEncoding)
dataUsingEncoding encoding
end
def to_color
# First check if it is a color keyword
keyword_selector = "#{self.camelize(:lower)}Color"
color_klass = App.osx? ? NSColor : UIColor
return color_klass.send(keyword_selector) if color_klass.respond_to? keyword_selector
# Next attempt to convert from hex
hex_color = self.gsub("#", "")
case hex_color.size
when 3
colors = hex_color.scan(%r{[0-9A-Fa-f]}).map!{ |el| (el * 2).to_i(16) }
when 6
colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map!{ |el| el.to_i(16) }
when 8
colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map!{ |el| el.to_i(16) }
else
raise ArgumentError
end
if colors.size == 3
BubbleWrap.rgb_color(colors[0], colors[1], colors[2])
elsif colors.size == 4
BubbleWrap.rgba_color(colors[1], colors[2], colors[3], colors[0])
else
raise ArgumentError
end
end
end
end
NSString.send(:include, BubbleWrap::String)
================================================
FILE: motion/core/time.rb
================================================
class Time
def self.iso8601(time)
if time.include?(".")
# Fractional Seconds
if time.include?('Z')
iso8601_with_fractional_seconds(time)
else
iso8601_with_fractional_seconds_and_timesone(time)
end
else
# Non Fractional Seconds
if time.include?('Z')
iso8601_zulu(time)
else
iso8601_with_timezone(time)
end
end
end
def self.iso8601_zulu(time)
cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss'Z'").
dateFromString(time)
end
def self.iso8601_with_timezone(time)
cached_date_formatter("yyyy-MM-dd'T'HH:mm:ssZZZZZ").
dateFromString(time)
end
def self.iso8601_with_fractional_seconds(time)
cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").
dateFromString(time)
end
def self.iso8601_with_fractional_seconds_and_timesone(time)
cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ").
dateFromString(time)
end
private
def self.cached_date_formatter(dateFormat)
Thread.current[:date_formatters] ||= {}
Thread.current[:date_formatters][dateFormat] ||=
NSDateFormatter.alloc.init.tap do |formatter|
formatter.dateFormat = dateFormat
formatter.timeZone = NSTimeZone.timeZoneWithAbbreviation "UTC"
end
end
end
================================================
FILE: motion/core.rb
================================================
module BubbleWrap
module_function
# @return [UIcolor]
def rgb_color(r,g,b)
rgba_color(r,g,b,1)
end
# @return [UIcolor]
def rgba_color(r,g,b,a)
r,g,b = [r,g,b].map { |i| i / 255.0}
if a > 1.0
a = a / 255.0
end
if App.osx?
NSColor.colorWithDeviceRed(r, green: g, blue: b, alpha: a)
else
UIColor.colorWithRed(r, green: g, blue:b, alpha:a)
end
end
def localized_string(key, value=nil)
NSBundle.mainBundle.localizedStringForKey(key, value:value, table:nil)
end
# I had issues with #p on the device, this is a temporary workaround
def p(arg)
NSLog arg.inspect
end
def create_uuid
uuid = CFUUIDCreate(nil)
CFUUIDCreateString(nil, uuid)
end
end
================================================
FILE: motion/font/font.rb
================================================
module BubbleWrap
module Font
module_function
def bold(size = nil)
Font.new(:bold, size)
end
def system(size = nil)
Font.new(:system, size)
end
def italic(size = nil)
Font.new(:italic, size)
end
# Example
# Font.new(<# UIFont >)
# Font.new("Helvetica")
# Font.new("Helvetica", 12)
# Font.new("Helvetica", size: 12)
# Font.new(name: "Helvetica", size: 12)
def new(params = {}, *args)
if params.is_a?(UIFont)
return params
end
_font = nil
if params.is_a?(NSString)
params = {name: params}
end
if args && !args.empty?
case args[0]
when NSDictionary
params.merge!(args[0])
else
params.merge!({size: args[0]})
end
end
params[:size] ||= UIFont.systemFontSize
case params[:name].to_sym
when :system
_font = UIFont.systemFontOfSize(params[:size].to_f)
when :bold
_font = UIFont.boldSystemFontOfSize(params[:size].to_f)
when :italic
_font = UIFont.italicSystemFontOfSize(params[:size].to_f)
else
begin
_font = UIFont.fontWithName(params[:name], size: params[:size])
rescue
end
end
if !_font
raise "Invalid font for parameters: #{params.inspect} args #{args.inspect}"
end
_font
end
class << self
alias_method :named, :new
end
# I.e. for UINavigationBar#titleTextAttributes
def attributes(params = {})
_attributes = {}
_attributes[UITextAttributeFont] = Font.new(params[:font]) if params[:font]
_attributes[UITextAttributeTextColor] = params[:color].to_color if params[:color]
_attributes[UITextAttributeTextShadowColor] = params[:shadow_color].to_color if params[:shadow_color]
_attributes[UITextAttributeTextShadowOffset] = begin
x = params[:shadow_offset][:x]
y = params[:shadow_offset][:y]
offset = UIOffsetMake(x,y)
NSValue.valueWithUIOffset(offset)
end if params[:shadow_offset]
_attributes
end
end
end
================================================
FILE: motion/ios/8/location_constants.rb
================================================
module BW
# New additions to CLAuthorizationStatus in ios8
# see: https://developer.apple.com/library/prerelease/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/c/tdef/CLAuthorizationStatus
Constants.register(
KCLAuthorizationStatusAuthorized,
KCLAuthorizationStatusAuthorizedWhenInUse,
KCLAuthorizationStatusAuthorizedAlways
)
module Location
module_function
def authorized?
[
BW::Constants.get("KCLAuthorizationStatus", :authorized),
BW::Constants.get("KCLAuthorizationStatus", :authorized_always),
BW::Constants.get("KCLAuthorizationStatus", :authorized_when_in_use)
].include?(CLLocationManager.authorizationStatus)
end
end
end
================================================
FILE: motion/location/location.rb
================================================
# Provides a nice DSL for interacting with the standard
# CLLocationManager
#
module BubbleWrap
module CLLocationWrap
def latitude
self.coordinate.latitude
end
def longitude
self.coordinate.longitude
end
end
module Location
module Error
DISABLED=0
PERMISSION_DENIED=1
NETWORK_FAILURE=2
LOCATION_UNKNOWN=3
end
Constants.register KCLLocationAccuracyBestForNavigation, KCLLocationAccuracyBest,
KCLLocationAccuracyNearestTenMeters, KCLLocationAccuracyHundredMeters,
KCLLocationAccuracyKilometer, KCLLocationAccuracyThreeKilometers
module_function
# Start getting locations
# @param [Hash] options = {
# authorization_type: :always/:when_in_use to trigger the type of authorization you want
# default == uses :always
# significant: true/false; whether to listen for significant location changes or
# all location changes (see Apple docs for info); default == false
# distance_filter: minimum change in distance to be updated about, in meters;
# default == uses KCLDistanceFilterNone,
# desired_accuracy: minimum accuracy for updates to arrive;
# any of :best_for_navigation, :best, :nearest_ten_meters,
# :hundred_meters, :kilometer, or :three_kilometers; default == :best
# purpose: string to display when the system asks user for location,
# retries: if location cant be found. how many errors do we retry; default == 5
# calibration: if the OS should display the heading calibration to the user; default == false
# }
# @block for callback. takes one argument, `result`.
# - On error or cancelled, is called with a hash {error: BW::Location::Error::<Type>}
# - On success, is called with a hash {to: #<CLLocation>, from: #<CLLocation>, previous: [#<CLLocation>,...]}
# -- :previous will return an Array of CLLocation objects, ordered from oldest to newest, excluding the
# locations :to and :from, returning an empty Array if no additional locations were provided
#
# Example
# BW::Location.get(distance_filter: 10, desired_accuracy: :nearest_ten_meters) do |result|
# result[:to].class == CLLocation
# result[:from].class == CLLocation
# result[:previous].class == NSArray<CLLocation>
# p "Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
# end
def get(options = {}, &block)
@callback = block
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
@options = {
authorization_type: :always,
significant: false,
distance_filter: KCLDistanceFilterNone,
desired_accuracy: KCLLocationAccuracyBest,
retries: 5,
once: false,
calibration: false
}.merge(options)
@options[:significant] = false if @options[:significant].nil?
@retries = 0
@from_location = nil
if not enabled?
error(Error::DISABLED) and return
end
self.location_manager
if self.location_manager.respondsToSelector('requestAlwaysAuthorization')
@options[:authorization_type] == :always ? self.location_manager.requestAlwaysAuthorization : self.location_manager.requestWhenInUseAuthorization
end
self.location_manager.distanceFilter = @options[:distance_filter]
self.location_manager.desiredAccuracy = Constants.get("KCLLocationAccuracy", @options[:desired_accuracy])
self.location_manager.purpose = @options[:purpose] if @options[:purpose]
@initialized = true
start
end
def get_significant(options = {}, &block)
get(options.merge(significant: true), &block)
end
# Get the first returned location based on your options
# @param [Hash] options = {
# significant: true/false; whether to listen for significant location changes or
# all location changes (see Apple docs for info); default == false
# distance_filter: minimum change in distance to be updated about, in meters;
# default == uses KCLDistanceFilterNone,
# desired_accuracy: minimum accuracy for updates to arrive;
# any of :best_for_navigation, :best, :nearest_ten_meters,
# :hundred_meters, :kilometer, or :three_kilometers; default == :best
# purpose: string to display when the system asks user for location,
# retries: if location cant be found. how many errors do we retry; default == 5
# }
# @block for callback. takes one argument, `result`.
# - On error or cancelled, is called with a hash {error: BW::Location::Error::<Type>}
# - On success, it returns a CLLocation
#
#
# Example
# BW::Location.get_once(desired_accuracy: :three_kilometers, purpose: 'We need to use your GPS to show you how fun RM is') do |result|
# if result.is_a?(CLLocation)
# p "Lat #{result.latitude}, Long #{result.longitude}"
# else
# p "ERROR: #{result[:error]"
# end
# end
def get_once(options = {}, &block)
get(options.merge(once: true), &block)
end
def get_compass(options = {}, &block)
get(options.merge(compass: true), &block)
end
def get_compass_once(options = {}, &block)
get_compass(options.merge(once: true), &block)
end
# Start getting locations
def start
return unless initialized?
if @options[:significant]
self.location_manager.startMonitoringSignificantLocationChanges
elsif @options[:compass]
self.location_manager.startUpdatingHeading
else
self.location_manager.startUpdatingLocation
end
end
# Stop getting locations
def stop
return unless @options
if @options[:significant]
self.location_manager.stopMonitoringSignificantLocationChanges
elsif @options[:compass]
self.location_manager.stopUpdatingHeading
else
self.location_manager.stopUpdatingLocation
end
end
def location_manager
@location_manager ||= CLLocationManager.alloc.init
@location_manager.delegate ||= self
@location_manager
end
# returns true/false whether services, or limited services, are enabled for the _device_
def enabled?
CLLocationManager.locationServicesEnabled
end
# returns true/false if CLLocationManager has been initialized with the provided or default options
def initialized?
@initialized ||= false
end
# returns true/false whether services are enabled for the _app_
def authorized?
[
BW::Constants.get("KCLAuthorizationStatus", :authorized)
].include?(CLLocationManager.authorizationStatus)
end
def error(type)
@callback && @callback.call({ error: type })
@callback = nil
self.location_manager.stopUpdatingLocation
end
##########
# CLLocationManagerDelegate Methods
def locationManager(manager, didUpdateLocations:locations)
if @options[:once]
@callback && @callback.call(locations.last)
@callback = proc { |result| }
stop
else
size = locations.count
result = {to: locations.last,
from: ( (size > 1) ? locations.last(2).first : @from_location ),
previous: ( (size > 2) ? locations.first(size - 2) : [] )
}
@from_location = result[:to]
@callback && @callback.call(result)
end
end
def locationManager(manager, didUpdateHeading:newHeading)
heading = {
magnetic_heading: newHeading.magneticHeading,
true_heading: newHeading.trueHeading,
accuracy: newHeading.headingAccuracy,
timestamp: newHeading.timestamp,
}
if @options[:once]
@callback && @callback.call(heading)
@callback = proc { |result| }
stop
else
@callback && @callback.call(heading)
end
end
def locationManager(manager, didFailWithError:error)
if error.domain == KCLErrorDomain
case error.code
when KCLErrorDenied
error(Error::PERMISSION_DENIED)
when KCLErrorLocationUnknown
# Docs specify that this is a temporary error,
# so we stop/start updating to try again.
@retries += 1
if @retries > @options[:retries]
error(Error::LOCATION_UNKNOWN)
else
stop
start
end
when KCLErrorNetwork
error(Error::NETWORK_FAILURE)
end
end
end
def locationManager(manager, didChangeAuthorizationStatus:status)
case status
when KCLAuthorizationStatusRestricted
error(Error::PERMISSION_DENIED)
when KCLAuthorizationStatusDenied
error(Error::PERMISSION_DENIED)
end
end
def locationManagerShouldDisplayHeadingCalibration(manager)
@options[:calibration] ? @options[:calibration] : false
end
end
end
::Location = BubbleWrap::Location unless defined?(::Location)
================================================
FILE: motion/location/pollute.rb
================================================
[
[CLLocation, BubbleWrap::CLLocationWrap],
].each do |base, wrapper|
base.send(:include, wrapper)
end
================================================
FILE: motion/mail/mail.rb
================================================
module BubbleWrap
module Mail
module_function
# Base method to create your in-app mail
# ---------------------------------------
# EX
# BW::Mail.compose(
# delegate: self, # optional, will use root view controller by default
# to: [ "tom@example.com" ],
# cc: [ "itchy@example.com", "scratchy@example.com" ],
# bcc: [ "jerry@example.com" ],
# html: false,
# subject: "My Subject",
# message: "This is my message. It isn't very long.",
# animated: false
# ) do |result, error|
# result.sent? # => boolean
# result.canceled? # => boolean
# result.saved? # => boolean
# result.failed? # => boolean
# error # => NSError
# end
def compose(options = {}, &callback)
options = {
delegate: App.window.rootViewController,
animated: true,
html: false,
to: [],
cc: [],
bcc: [],
subject: 'Contact'
}.merge(options)
@delegate = options[:delegate]
@mailer_is_animated = options[:animated]
@callback = callback
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
@mail_controller = create_mail_controller(options)
@delegate.presentViewController(@mail_controller, animated: @mailer_is_animated, completion: options[:completion])
end
def create_mail_controller(options = {})
unless can_send_mail?
controller = UIAlertController.alertControllerWithTitle("Email", message:"Cannot compose an email. Please run on device.", preferredStyle:UIAlertControllerStyleAlert)
controller.addAction(UIAlertAction.actionWithTitle:"OK",style:UIAlertActionStyleDefault, handler:@callback)
return controller
end
mail_controller = MFMailComposeViewController.alloc.init
mail_controller.mailComposeDelegate = self
mail_controller.setToRecipients(Array(options[:to]))
mail_controller.setCcRecipients(Array(options[:cc]))
mail_controller.setBccRecipients(Array(options[:bcc]))
mail_controller.setSubject(options[:subject])
mail_controller.setMessageBody(options[:message], isHTML: !!options[:html])
mail_controller
end
def can_send_mail?
!!MFMailComposeViewController.canSendMail
end
# Event when the MFMailComposeViewController is closed
# -------------------------------------------------------------
# the callback is fired if it was present in the constructor
def mailComposeController(controller, didFinishWithResult: result, error: error)
@delegate.dismissModalViewControllerAnimated(@mailer_is_animated)
@callback.call Result.new(result, error) if @callback
end
end
end
================================================
FILE: motion/mail/result.rb
================================================
module BubbleWrap
module Mail
class Result
attr_accessor :result, :error
def initialize(result, error)
self.result = result
self.error = error
end
def sent?
self.result == MFMailComposeResultSent
end
def canceled?
self.result == MFMailComposeResultCancelled
end
def saved?
self.result == MFMailComposeResultSaved
end
def failed?
self.result == MFMailComposeResultFailed || self.error
end
end
end
end
================================================
FILE: motion/media/media.rb
================================================
module BubbleWrap
module Media
module_function
def play_modal(*args, &block)
Media::Player.new.retain.send(:play_modal, *args, &block)
end
def play(*args, &block)
Media::Player.new.retain.send(:play, *args, &block)
end
end
end
::Media = BubbleWrap::Media unless defined?(::Media)
================================================
FILE: motion/media/player.rb
================================================
module BubbleWrap
module Media
module Error
class InvalidPlayerType < StandardError; end
class NilPlayerCallback < StandardError; end
end
class Player
attr_reader :media_player
############
# Playing Media
# Plays media in the system-default modal controller
# Takes same parameters as #play
# NOTE: If you don't supply a :controller option,
# the rootViewController will be used.
def play_modal(content_url, options = {})
play(content_url, options.merge(modal: true))
end
# @param [String, NSURL] content_url is either a local or remote string
# for the location of the media you're playing.
# NOTE: if you're playing a remote file, your server needs to support
# range requests for that URL.
#
# @param [Hash] options to open the MPMoviePlayerController with
# the form {
# ### These are properties of MPMoviePlayerController
# allows_air_play: true/false; default false,
# control_style: [MPMovieControlStyle]; default MPMovieControlStyleDefault,
# end_playback_time: [Integer] end time (in seconds) for media; default is -1,
# initial_playback_time: [Integer] start time (in seconds) for media; default is -1,
# movie_source_type: [MPMovieSourceType] a "hint" so the player knows how to load the data type;
# either MPMovieSourceTypeFile or MPMovieSourceTypeStreaming; default is MPMovieSourceTypeUnknown
# which may delay playback,
# repeat_mode: [MPMovieRepeatMode] how the player repeats at the end of playback; defautl is
# MPMovieRepeatModeNone
# scaling_mode: [MPMovieScalingMode] scaling mode for movies; default is MPMovieScalingModeAspectFit
# should_autoplay: true/false; default true,
# use_application_audio_session: true/false; default true.
#
# ### These are properties of just the ::Player
# delay_play: true/false, default false. If false then you have to manually call
# @media_player.play in your code
# modal: true/false; default false,
# controller: [UIViewController] used to present the player modally;
# default uses root view controller of window
# }
#
# @block for when setup is done; use this block to present
# @media_player.view if options[:modal] == false
#
# EX
# From a local URL:
# file = File.join(App.resources_path, 'test.mp3')
# BW::Media::Player.play(NSURL.fileURLWithPath(file)) do |media_player|
# media_player.view.frame = some_view.bounds
# self.view.addSubview media_player.view
# end
#
# From a remote URL:
# BW::Media::Player.play("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3") do |media_player|
# media_player.view.frame = some_view.bounds
# self.view.addSubview media_player.view
# end
def play(content_url, options = {}, &block)
options = {
delay_play: false
}.merge(options)
display_modal = !!options[:modal]
klass = display_modal ? MPMoviePlayerViewController : MPMoviePlayerController
content_url = content_url.is_a?(NSURL) ? content_url : NSURL.URLWithString(content_url)
@media_player = klass.alloc.init
self.media_player.prepareToPlay if not display_modal
set_player_options(options)
self.media_player.setContentURL(content_url)
NSNotificationCenter.defaultCenter.observe MPMoviePlayerPlaybackDidFinishNotification do |notification|
h = notification.userInfo
error = h["error"]
if error
p "BW::Media::Player error: #{error.userInfo.inspect}"
p "Code: #{error.code}, Domain: #{error.domain}"
end
end
if display_modal
@presenting_controller = options[:controller]
@presenting_controller ||= App.window.rootViewController
if Device.ios_version < "7.0"
@presenting_controller.presentMoviePlayerViewControllerAnimated(@media_player)
else
@presenting_controller.presentViewController(@media_player, animated:true, completion:nil)
end
else
if block.nil?
raise Error::NilPlayerCallback, "no block callback given in #play; you need\
to supply one if options[:modal] == false"
end
block.call(@media_player)
end
if not display_modal and not options[:delay_play]
@media_player.play
end
end
# Stops playback for a Media::Player
def stop
if @media_player.is_a? MPMoviePlayerViewController
if Device.ios_version < "7.0"
@presenting_controller.dismissMoviePlayerViewControllerAnimated
else
@presenting_controller.dismissViewControllerAnimated(true, completion:nil)
end
@presenting_controller = nil
else
@media_player.stop
end
@media_player = nil
end
def media_player
if @media_player.is_a? MPMoviePlayerViewController
return @media_player.moviePlayer
end
@media_player
end
private
# RubyMotion has a problem calling some objective-c methods at runtime, so we can't
# do any cool `camelize` tricks.
def set_player_options(options)
self.media_player.allowsAirPlay = options[:allows_air_play] if options.has_key? :allows_air_play
self.media_player.controlStyle = options[:control_style] if options.has_key? :control_style
self.media_player.endPlaybackTime = options[:end_playback_time] if options.has_key? :end_playback_time
self.media_player.initialPlaybackTime = options[:initial_playback_time] if options.has_key? :initial_playback_time
self.media_player.movieSourceType = options[:movie_source_type] if options.has_key? :movie_source_type
self.media_player.repeatMode = options[:repeat_mode] if options.has_key? :repeat_mode
self.media_player.scalingMode = options[:scaling_mode] if options.has_key? :scaling_mode
self.media_player.shouldAutoplay = options[:should_autoplay] if options.has_key? :should_autoplay
self.media_player.useApplicationAudioSession = options[:use_application_audio_session] if options.has_key? :use_application_audio_session
end
end
end
end
================================================
FILE: motion/motion/accelerometer.rb
================================================
module BubbleWrap
module Motion
class Accelerometer < GenericMotionInterface
def start(options={}, &handler)
if options.key?(:interval)
@manager.accelerometerUpdateInterval = options[:interval]
end
if handler
queue = convert_queue(options[:queue])
@manager.startAccelerometerUpdatesToQueue(queue, withHandler: internal_handler(handler))
else
@manager.startAccelerometerUpdates
end
return self
end
private def handle_result(result_data, error, handler)
if result_data
result = {
data: result_data,
acceleration: result_data.acceleration,
x: result_data.acceleration.x,
y: result_data.acceleration.y,
z: result_data.acceleration.z,
}
else
result = nil
end
handler.call(result, error)
end
def available?
@manager.accelerometerAvailable?
end
def active?
@manager.accelerometerActive?
end
def data
@manager.accelerometerData
end
def stop
@manager.stopAccelerometerUpdates
end
end
end
end
================================================
FILE: motion/motion/device_motion.rb
================================================
module BubbleWrap
module Motion
class DeviceMotion < GenericMotionInterface
def start(options={}, &handler)
if options.key?(:interval)
@manager.deviceMotionUpdateInterval = options[:interval]
end
if options.key?(:reference)
reference_frame = convert_reference_frame(options[:reference])
else
reference_frame = nil
end
if handler
queue = convert_queue(options[:queue])
if reference_frame
@manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame, toQueue: queue, withHandler: internal_handler(handler))
else
@manager.startDeviceMotionUpdatesToQueue(queue, withHandler: internal_handler(handler))
end
else
if reference_frame
@manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame)
else
@manager.startDeviceMotionUpdates
end
end
return self
end
private def handle_result(result_data, error, handler)
if result_data
result = {
data: result_data,
attitude: result_data.attitude,
rotation: result_data.rotationRate,
gravity: result_data.gravity,
acceleration: result_data.userAcceleration,
magnetic: result_data.magneticField,
}
if result_data.attitude
result.merge!({
roll: result_data.attitude.roll,
pitch: result_data.attitude.pitch,
yaw: result_data.attitude.yaw,
matrix: result_data.attitude.rotationMatrix,
quaternion: result_data.attitude.quaternion,
})
end
if result_data.rotationRate
result.merge!({
rotation_x: result_data.rotationRate.x,
rotation_y: result_data.rotationRate.y,
rotation_z: result_data.rotationRate.z,
})
end
if result_data.gravity
result.merge!({
gravity_x: result_data.gravity.x,
gravity_y: result_data.gravity.y,
gravity_z: result_data.gravity.z,
})
end
if result_data.userAcceleration
result.merge!({
acceleration_x: result_data.userAcceleration.x,
acceleration_y: result_data.userAcceleration.y,
acceleration_z: result_data.userAcceleration.z,
})
end
if result_data.magneticField
case result_data.magneticField.accuracy
when CMMagneticFieldCalibrationAccuracyLow
accuracy = :low
when CMMagneticFieldCalibrationAccuracyMedium
accuracy = :medium
when CMMagneticFieldCalibrationAccuracyHigh
accuracy = :high
end
result.merge!({
field: result_data.magneticField.field,
magnetic_x: result_data.magneticField.field.x,
magnetic_y: result_data.magneticField.field.y,
magnetic_z: result_data.magneticField.field.z,
magnetic_accuracy: accuracy,
})
end
else
result = nil
end
handler.call(result, error)
end
def convert_reference_frame(reference_frame)
case reference_frame
when :arbitrary_z
CMAttitudeReferenceFrameXArbitraryZVertical
when :corrected_z
CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
when :magnetic_north
CMAttitudeReferenceFrameXMagneticNorthZVertical
when :true_north
CMAttitudeReferenceFrameXTrueNorthZVertical
else
reference_frame
end
end
def available?
@manager.deviceMotionAvailable?
end
def active?
@manager.deviceMotionActive?
end
def data
@manager.deviceMotion
end
def stop
@manager.stopDeviceMotionUpdates
end
end
end
end
================================================
FILE: motion/motion/gyroscope.rb
================================================
module BubbleWrap
module Motion
class Gyroscope < GenericMotionInterface
def start(options={}, &handler)
if options.key?(:interval)
@manager.gyroUpdateInterval = options[:interval]
end
if handler
queue = convert_queue(options[:queue])
@manager.startGyroUpdatesToQueue(queue, withHandler: internal_handler(handler))
else
@manager.startGyroUpdates
end
return self
end
private def handle_result(result_data, error, handler)
if result_data
result = {
data: result_data,
rotation: result_data.rotationRate,
x: result_data.rotationRate.x,
y: result_data.rotationRate.y,
z: result_data.rotationRate.z,
}
else
result = nil
end
handler.call(result, error)
end
def available?
@manager.gyroAvailable?
end
def active?
@manager.gyroActive?
end
def data
@manager.gyroData
end
def stop
@manager.stopGyroUpdates
end
end
end
end
================================================
FILE: motion/motion/magnetometer.rb
================================================
module BubbleWrap
module Motion
class Magnetometer < GenericMotionInterface
def start(options={}, &handler)
if options.key?(:interval)
@manager.magnetometerUpdateInterval = options[:interval]
end
if handler
queue = convert_queue(options[:queue])
@manager.startMagnetometerUpdatesToQueue(queue, withHandler: internal_handler(handler))
else
@manager.startMagnetometerUpdates
end
return self
end
private def handle_result(result_data, error, handler)
if result_data
result = {
data: result_data,
field: result_data.magneticField,
x: result_data.magneticField.x,
y: result_data.magneticField.y,
z: result_data.magneticField.z,
}
else
result = nil
end
handler.call(result, error)
end
def available?
@manager.magnetometerAvailable?
end
def active?
@manager.magnetometerActive?
end
def data
@manager.magnetometerData
end
def stop
@manager.stopMagnetometerUpdates
end
end
end
end
================================================
FILE: motion/motion/motion.rb
================================================
# Provides a nice DSL for interacting with the standard CMMotionManager from
# CoreMotion
module BubbleWrap
# These module methods provide the main interface. It uses a shared manager
# (per Apple's recommendation), and they all have a common set of supported
# methods:
# available?
# active?
# repeat(opts)
# once(opts)
# every(time_interval, opts)
#
# @example
# if BW::Motion.accelerometer.available?
# BW::Motion.accelerometer.every(5) do |result|
# # see the README for the keys that are available in result.
# end
# end
#
# If you insist on using your own manager, or you want more than one
# BW::Motion::Whatever running at the same time, you'll need to instantiate
# them yourself.
#
# @example
# mgr = CMMotionManager.alloc.init
# accel = BW::Motion::Accelerometer.new(mgr)
# accel.once do |result_data|
# end
# # => BW::Motion::accelerometer.once do |result_data| ... end
module Motion
module_function
def manager
@manager ||= CMMotionManager.alloc.init
end
def accelerometer
@accelerometer ||= Accelerometer.new(self.manager)
end
def gyroscope
@gyroscope ||= Gyroscope.new(self.manager)
end
def magnetometer
@magnetometer ||= Magnetometer.new(self.manager)
end
def device
@device ||= DeviceMotion.new(self.manager)
end
end
module Motion
module Error
end
class GenericMotionInterface
def initialize(manager)
@manager = manager
end
def repeat(options={}, &blk)
raise "A block is required" unless blk
blk.weak! if BubbleWrap.use_weak_callbacks?
self.start(options, &blk)
return self
end
def every(time=nil, options={}, &blk)
raise "A block is required" unless blk
blk.weak! if BubbleWrap.use_weak_callbacks?
if time.is_a?(NSDictionary)
options = time
elsif time
options = options.merge(interval: time)
end
self.start(options, &blk)
return self
end
def once(options={}, &blk)
raise "A block is required" unless blk
blk.weak! if BubbleWrap.use_weak_callbacks?
@called_once = false
every(options) do |result, error|
unless @called_once
@called_once = true
blk.call(result, error)
end
self.stop
end
return self
end
private def convert_queue(queue_name)
case queue_name
when :main, nil
return NSOperationQueue.mainQueue
when :background
queue = NSOperationQueue.new
queue.name = 'com.bubble-wrap.core-motion.background-queue'
return queue
when :current
return NSOperationQueue.currentQueue
when String
queue = NSOperationQueue.new
queue.name = queue_name
return queue
else
queue_name
end
end
private def internal_handler(handler)
retval = -> (result_data, error) do
handle_result(result_data, error, handler)
end
retval.weak! if BubbleWrap.use_weak_callbacks?
retval
end
end
end
end
================================================
FILE: motion/network-indicator/network-indicator.rb
================================================
module BubbleWrap
module NetworkIndicator
DELAY = 0.2
module_function
def counter
@counter ||= 0
end
def show
if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
@counter = self.counter + 1
self.update_spinner
else
Dispatch::Queue.main.async do
self.show
end
end
end
def hide
if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
@counter = [self.counter - 1, 0].max
if self.counter == 0
if @hide_indicator_timer
@hide_indicator_timer.invalidate
end
@hide_indicator_timer = NSTimer.timerWithTimeInterval(DELAY - 0.01, target: self, selector: :update_spinner_timer, userInfo: nil, repeats: false)
NSRunLoop.mainRunLoop.addTimer(@hide_indicator_timer, forMode:NSRunLoopCommonModes)
end
else
Dispatch::Queue.main.async do
self.hide
end
end
end
def update_spinner_timer
update_spinner
end
def update_spinner
if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
if @hide_indicator_timer
@hide_indicator_timer.invalidate
@hide_indicator_timer = nil
end
UIApplication.sharedApplication.networkActivityIndicatorVisible = (@counter > 0)
else
Dispatch::Queue.main.async do
self.update_spinner
end
end
end
def visible?
UIApplication.sharedApplication.networkActivityIndicatorVisible?
end
def reset!
@counter = 0
self.update_spinner
end
end
end
================================================
FILE: motion/reactor/default_deferrable.rb
================================================
module BubbleWrap
module Reactor
# A basic class which includes Deferrable when all
# you need is a deferrable without any added behaviour.
class DefaultDeferrable
include ::BubbleWrap::Reactor::Deferrable
end
end
end
================================================
FILE: motion/reactor/deferrable.rb
================================================
module BubbleWrap
module Reactor
# Provides a mixin for deferrable jobs.
module Deferrable
# def self.included(base)
# base.extend ::BubbleWrap::Reactor::Future
# end
# Specify a block to be executed if and when the Deferrable object
# receives a status of :succeeded. See set_deferred_status for more
# information.
# Calling this method on a Deferrable object whose status is not yet
# known will cause the callback block to be stored on an internal
# list. If you call this method on a Deferrable whose status is
# :succeeded, the block will be executed immediately, receiving
# the parameters given to the prior set_deferred_status call.
def callback(&blk)
return unless blk
@deferred_status ||= :unknown
if @deferred_status == :succeeded
execute_block(&blk)
elsif @deferred_status != :failed
@callbacks ||= []
@callbacks.unshift blk
end
end
# Cancels an outstanding timeout if any. Undoes the action of timeout.
def cancel_timeout
@deferred_timeout ||= nil
if @deferred_timeout
@deferred_timeout.cancel
@deferred_timeout = nil
end
end
# Specify a block to be executed if and when the Deferrable object
# receives a status of :failed. See set_deferred_status for more
# information.
def errback(&blk)
return unless blk
@deferred_status ||= :unknown
if @deferred_status == :failed
execute_block(&blk)
blk.call(*@deferred_args)
elsif @deferred_status != :succeeded
@errbacks ||= []
@errbacks.unshift blk
end
end
def execute_block(&blk)
return unless blk
blk.call(*@deferred_args)
end
def delegate(delegate)
callback_delegate(delegate)
errback_delegate(delegate)
self
end
def errback_delegate(delegate)
errback do |*args|
delegate.fail *args
end
self
end
def callback_delegate(delegate)
callback do |*args|
delegate.succeed *args
end
self
end
# Sugar for set_deferred_status(:failed, …)
def fail(*args)
set_deferred_status :failed, *args
end
alias set_deferred_failure fail
# Sets the “disposition” (status) of the Deferrable object. See also
# the large set of sugarings for this method. Note that if you call
# this method without arguments, no arguments will be passed to the
# callback/errback. If the user has coded these with arguments,
# then the user code will throw an argument exception. Implementors
# of deferrable classes must document the arguments they will supply
# to user callbacks.
# OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
# on the INSIDE of a callback. This is very useful when a
# previously-registered callback wants to change the parameters that
# will be passed to subsequently-registered ones.
# You may give either :succeeded or :failed as the status argument.
# If you pass :succeeded, then all of the blocks passed to the object
# using the callback method (if any) will be executed BEFORE the
# set_deferred_status method returns. All of the blocks passed to the
# object using errback will be discarded.
# If you pass :failed, then all of the blocks passed to the object
# using the errback method (if any) will be executed BEFORE the
# set_deferred_status method returns. All of the blocks passed to the
# object using # callback will be discarded.
# If you pass any arguments to set_deferred_status in addition to the
# status argument, they will be passed as arguments to any callbacks
# or errbacks that are executed. It’s your responsibility to ensure
# that the argument lists specified in your callbacks and errbacks match
# the arguments given in calls to set_deferred_status, otherwise Ruby
# will raise an ArgumentError.
def set_deferred_status(status, *args)
cancel_timeout
@errbacks ||= nil
@callbacks ||= nil
@deferred_status = status
@deferred_args = args
case @deferred_status
when :succeeded
if @callbacks
while cb = @callbacks.pop
execute_block(&cb)
end
end
@errbacks.clear if @errbacks
when :failed
if @errbacks
while eb = @errbacks.pop
execute_block(&eb)
end
end
@callbacks.clear if @callbacks
end
end
# Sugar for set_deferred_status(:succeeded, …)
def succeed(*args)
set_deferred_status :succeeded, *args
end
alias set_deferred_success succeed
# Setting a timeout on a Deferrable causes it to go into the failed
# state after the Timeout expires (passing no arguments to the object’s
# errbacks). Setting the status at any time prior to a call to the
# expiration of the timeout will cause the timer to be cancelled.
def timeout(seconds)
cancel_timeout
me = self
@deferred_timeout = Timer.new(seconds) {me.fail}
end
def deferred_status
@deferred_status ||= :unknown
end
def deferred_args
@deferred_args
end
end
end
end
================================================
FILE: motion/reactor/dependent_deferrable.rb
================================================
module BubbleWrap
module Reactor
class DependentDeferrable < DefaultDeferrable
# args are Deferrable(s) which the returned Deferrable depends on.
# returns a Deferrable that depends on args.
# which:
# succeeds only when every Deferrable in args succeeds
# fails immediately when any Deferrable in args fails
# Have to be careful that #deferred_args for DependentDeferrable is a list of #deferred_args from its children Deferrable(s).
def self.on(*args)
deferrable = self.new
@children_deferrables = args
@children_deferrables.each do |e|
e.callback do |result|
if @children_deferrables.all? {|a| a.deferred_status == :succeeded}
deferrable.succeed(*@children_deferrables.map(&:deferred_args))
end
end
e.errback do |result|
deferrable.fail(*e.deferred_args)
end
end
deferrable
end
end
end
end
================================================
FILE: motion/reactor/eventable.rb
================================================
module BubbleWrap
module Reactor
# A simple mixin that adds events to your object.
module Eventable
# When `event` is triggered the block will execute
# and be passed the arguments that are passed to
# `trigger`.
def on(event, method = nil, &blk)
events = _events_for_key(event)
method_or_block = method ? method : blk
events.push method_or_block
end
# When `event` is triggered, do not call the given
# block any more
def off(event, method = nil, &blk)
events = _events_for_key(event)
if method
events.delete_if { |m| m.receiver == method.receiver and m.name == method.name }
elsif blk
events.delete_if { |b| b == blk }
else
__events__[event] = Array.new
end
blk
end
# Trigger an event
def trigger(event, *args)
blks = _events_for_key(event).clone
blks.map do |blk|
blk.call(*args)
end
end
private
def __events__
@__events__ ||= Hash.new
end
def _events_for_key(event)
__events__[event] ||= Array.new
end
end
end
end
================================================
FILE: motion/reactor/future.rb
================================================
module BubbleWrap
module Reactor
module Future
# A future is a sugaring of a typical deferrable usage.
def future arg, cb=nil, eb=nil, &blk
arg = arg.call if arg.respond_to?(:call)
if arg.respond_to?(:set_deferred_status)
if cb || eb
arg.callback(&cb) if cb
arg.errback(&eb) if eb
else
arg.callback(&blk) if blk
end
end
arg
end
end
end
end
================================================
FILE: motion/reactor/periodic_timer.rb
================================================
module BubbleWrap
module Reactor
# Creates a repeating timer.
class PeriodicTimer
include Eventable
attr_accessor :interval
# Create a new timer that fires after a given number of seconds
def initialize(interval, *args, &blk)
callback = args.first.respond_to?(:call) ? args.first : blk
raise ArgumentError, "No callback or block supplied to periodic timer" unless callback
callback.weak! if callback && BubbleWrap.use_weak_callbacks?
options = args.last.is_a?(Hash) ? args.last : {}
if options[:common_modes]
NSLog "[DEPRECATED - Option :common_modes] a Run Loop Mode is no longer needed."
end
self.interval = interval
leeway = interval
queue = Dispatch::Queue.current
@timer = Dispatch::Source.timer(leeway, interval, 0.0, queue) do
callback.call
trigger(:fired)
end
end
# Cancel the timer
def cancel
@timer.cancel!
trigger(:cancelled)
end
end
end
end
================================================
FILE: motion/reactor/queue.rb
================================================
module BubbleWrap
module Reactor
# A GCD scheduled, linear queue.
#
# This class provides a simple “Queue” like abstraction on top of the
# GCD scheduler.
#
# Useful as an API sugar for stateful protocols
#
# q = BubbleWrap::Reactor::Queue.new
# q.push('one', 'two', 'three')
# 3.times do
# q.pop{ |msg| puts(msg) }
# end
class Queue
# Create a new queue
def initialize
@items = []
end
# Is the queue empty?
def empty?
@items.empty?
end
# The size of the queue
def size
@items.size
end
# Push items onto the work queue. The items will not appear in the queue
# immediately, but will be scheduled for addition.
def push(*items)
::BubbleWrap::Reactor.schedule do
@items.push(*items)
@popq.shift.call @items.shift until @items.empty? || @popq.empty?
end
end
# Pop items off the queue, running the block on the work queue. The pop
# will not happen immediately, but at some point in the future, either
# in the next tick, if the queue has data, or when the queue is populated.
def pop(*args, &blk)
cb = proc do
blk.call(*args)
end
::BubbleWrap::Reactor.schedule do
if @items.empty?
@popq << cb
else
cb.call @items.shift
end
end
nil # Always returns nil
end
end
end
end
================================================
FILE: motion/reactor/thread_aware_deferrable.rb
================================================
module BubbleWrap
module Reactor
class ThreadAwareDeferrable < DefaultDeferrable
include ::BubbleWrap::Reactor::Deferrable
# need to store the the queue in callback / errback
def callback(&blk)
return unless blk
cache_block_queue(&blk)
super(&blk)
end
def errback(&blk)
return unless blk
cache_block_queue(&blk)
super(&blk)
end
def execute_block(&blk)
return unless blk
queue = @queue_cache.delete(blk.object_id)
return unless queue
queue.async do
blk.call(*@deferred_args)
end
end
def cache_block_queue(&blk)
return unless blk
@queue_cache ||= {}
@queue_cache[blk.object_id] = Dispatch::Queue.current
end
end
end
end
================================================
FILE: motion/reactor/timer.rb
================================================
module BubbleWrap
module Reactor
# Creates a one-time timer.
class Timer
include Eventable
# Create a new timer that fires after a given number of seconds
def initialize(leeway, callback=nil, &blk)
queue = Dispatch::Queue.current
@timer = Dispatch::Source.timer(leeway, Dispatch::TIME_FOREVER, 0.0, queue) do |src|
begin
(callback || blk).call
trigger(:fired)
ensure
src.cancel!
end
end
end
# Cancel the timer
def cancel
@timer.cancel! if @timer
trigger(:cancelled)
true
end
end
end
end
================================================
FILE: motion/reactor.rb
================================================
module BubbleWrap
module Reactor
module_function
# Always returns true - for compatibility with EM
def reactor_running?
true
end
alias reactor_thread? reactor_running?
# Call `callback` or the passed block in `interval` seconds.
# Returns a timer signature that can be passed into
# `cancel_timer`
def add_timer(interval, callback=nil, &blk)
@timers ||= {}
timer = Timer.new(interval,callback,&blk)
timer.on(:fired) do
@timers.delete(timer.object_id)
end
timer.on(:cancelled) do
@timers.delete(timer.object_id)
end
@timers[timer.object_id] = timer
timer.object_id
end
# Cancel a timer by passing in either a Timer object or
# a timer id (as returned by `add_timer` and
# `add_periodic_timer`).
def cancel_timer(timer)
return timer.cancel if timer.respond_to?(:cancel)
@timers ||= {}
return @timers[timer].cancel if @timers[timer]
false
end
# Call `callback` or the passed block every `interval` seconds.
# Returns a timer signature that can be passed into
# `cancel_timer`
# Optionally supply a callback as a second argument instead of a block
# (as per EventMachine API)
# Optionally supply :common_modes => true in args to schedule the timer
# for the runloop "common modes" (NSRunLoopCommonModes) instead of
# the default runloop mode.
def add_periodic_timer(interval, *args, &blk)
@timers ||= {}
timer = PeriodicTimer.new(interval,*args,&blk)
timer.on(:cancelled) do
@timers.delete(timer)
end
@timers[timer.object_id] = timer
timer.object_id
end
# Defer is for integrating blocking operations into the reactor's control
# flow.
# Call defer with one or two blocks, the second block is optional.
# operation = proc do
# # perform a long running operation here
# "result"
# end
# callback = proc do |result|
# # do something with the result here, such as trigger a UI change
# end
# BubbleWrap::Reactor.defer(operation,callback)
# The action of `defer` is to take the block specified in the first
# parameter (the "operation") and schedule it for asynchronous execution
# on a GCD concurrency queue. When the operation completes the result (if any)
# is passed into the callback (if present).
def defer(op=nil,cb=nil,&blk)
schedule do
result = (op||blk).call
schedule(result, &cb) if cb
end
end
# A version of `defer` which schedules both the operator
# and callback operations on the application's main thread.
def defer_on_main(op=nil,cb=nil,&blk)
schedule_on_main do
result = (op||blk).call
schedule_on_main(result, &cb) if cb
end
end
# Schedule a block for execution on the reactor queue.
def schedule(*args, &blk)
@queue ||= ::Dispatch::Queue.concurrent("#{NSBundle.mainBundle.bundleIdentifier}.reactor")
blk.weak! if blk && BubbleWrap.use_weak_callbacks?
cb = proc do
blk.call(*args)
end
@queue.async &cb
nil
end
# Schedule a block for execution on your application's main thread.
# This is useful as UI updates need to be executed from the main
# thread.
def schedule_on_main(*args, &blk)
blk.weak! if blk && BubbleWrap.use_weak_callbacks?
cb = proc do
blk.call(*args)
end
::Dispatch::Queue.main.async &cb
end
end
end
::EM = ::BubbleWrap::Reactor unless defined?(::EM) # Yes I dare!
================================================
FILE: motion/rss_parser.rb
================================================
# Asynchronous and non blocking RSS Parser based on NSXMLParser.
# The parser will progressively parse a feed and yield each item to the provided block.
#
# The parser can also trigger delegate methods, you can define the following delegate method on the receiving object:
# def when_parser_initializes; end
# def when_parser_parses; end
# def when_parser_is_done; end
# def when_parser_errors; end
#
# @see https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html
#
# @usage example:
# feed = RSSParser.new(URL)
# feed.delegate = self
# feed.parse do |item|
# print item.link
# end
# def when_parser_is_done
# App.alert('parsing complete')
# end
#
module BubbleWrap
class RSSParser
attr_accessor :parser, :source, :doc, :debug, :delegate, :parser_error
attr_reader :state
# RSSItem is a simple class that holds all of RSS items.
# Extend this class to display/process the item differently.
class RSSItem
attr_accessor :title, :description, :link, :guid, :pubDate, :creator, :category, :encoded, :enclosure
def initialize
@title, @description, @link, @pubDate, @guid, @creator, @category, @encoded = '', '', '', '', ''
end
def to_hash
{
:title => title,
:description => description,
:link => link,
:pubDate => pubDate,
:guid => guid,
:enclosure => enclosure,
:category => category,
:encoded => encoded,
}
end
end
def initialize(input, data=false)
if data
data_to_parse = input.respond_to?(:to_data) ? input.to_data : input
@source = data_to_parse
@source_type = :data
else
url = input.is_a?(NSURL) ? input : NSURL.alloc.initWithString(input)
@source = url
@source_type = :url
end
self
end
def state=(new_state)
@state = new_state
callback_meth = "when_parser_#{new_state}"
if self.delegate && self.delegate.respond_to?(callback_meth)
self.delegate.send(callback_meth)
end
end
# Starts the parsing and send each parsed item through its block.
#
# Usage:
# feed.parse do |item|
# puts item.link
# end
def parse(&block)
@block = block
if @source_type == :url
@parser = NSXMLParser.alloc.initWithContentsOfURL(@source)
else
@parser = NSXMLParser.alloc.initWithData(@source)
end
@parser.shouldProcessNamespaces = true
@parser.delegate ||= self
self.state = :initializes
@parser.parse
end
# Delegate getting called when parsing starts
def parserDidStartDocument(parser)
puts "starting parsing.." if debug
self.state = :parses
end
# Delegate being called when an element starts being processed
def parser(parser, didStartElement:element, namespaceURI:uri, qualifiedName:name, attributes:attrs)
if element == 'item'
@current_item = RSSItem.new
elsif element == 'enclosure'
@current_item.enclosure = attrs
end
@current_element = element
end
# as the parser finds characters, this method is being called
def parser(parser, foundCharacters:string)
if @current_element && @current_item && @current_item.respond_to?(@current_element)
el = @current_item.send(@current_element)
el << string if el.respond_to?(:<<)
end
end
# method called when an element is done being parsed
def parser(parser, didEndElement:element, namespaceURI:uri, qualifiedName:name)
if element == 'item'
@block.call(@current_item) if @block
else
@current_element = nil
end
end
# method called when the parser encounters an error
# error can be retrieved with parserError
def parser(parser, parseErrorOccurred:parse_error)
puts "parseErrorOccurred" if debug
@parser_error = parse_error
self.state = :errors
end
# delegate getting called when the parsing is done
# If a block was set, it will be called on each parsed items
def parserDidEndDocument(parser)
puts "done parsing" if debug
self.state = :is_done unless self.state == :errors
end
def parserError
@parser_error || @parser.parserError
end
# TODO: implement
# parser:validationErrorOccurred:
# parser:foundCDATA:
end
end
================================================
FILE: motion/shortcut.rb
================================================
# Make sure that
# Both BubbleWrap and BW are defined. This file is depended on by everything
# else in BubbleWrap, so don't stuff anything in here unless you know why
# you're doing it.
module BubbleWrap
SETTINGS = {}
def self.debug=(val)
BubbleWrap::SETTINGS[:debug] = val
end
def self.debug?
BubbleWrap::SETTINGS[:debug]
end
def self.use_weak_callbacks=(val)
BubbleWrap::SETTINGS[:use_weak_callbacks] = val
end
def self.use_weak_callbacks?
BubbleWrap::SETTINGS[:use_weak_callbacks]
end
def version
BubbleWrap::VERSION
end
end
BW = BubbleWrap unless defined?(BW)
================================================
FILE: motion/sms/result.rb
================================================
module BubbleWrap
module SMS
class Result
attr_accessor :result
def initialize(result)
self.result = result
end
def sent?
self.result == MessageComposeResultSent
end
def canceled?
self.result == MessageComposeResultCancelled
end
def failed?
self.result == MessageComposeResultFailed
end
end
end
end
================================================
FILE: motion/sms/sms.rb
================================================
module BubbleWrap
module SMS
module_function
# Base method to create your in-app mail
# ---------------------------------------
# EX
# BW::SMS.compose (
# {
# delegate: self, # optional, will use root view controller by default
# to: [ "1(234)567-8910" ],
# message: "This is my message. It isn't very long.",
# animated: false
# }) {|result, error|
# result.sent? # => boolean
# result.canceled? # => boolean
# result.failed? # => boolean
# error # => NSError
# }
def compose(options = {}, &callback)
@delegate = options[:delegate] || App.window.rootViewController
@callback = callback
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
@message_controller = create_message_controller(options)
@message_is_animated = options[:animated] == false ? false : true
@delegate.presentModalViewController(@message_controller, animated: @message_is_animated)
end
def create_message_controller(options = {})
message_controller = MFMessageComposeViewController.alloc.init
message_controller.messageComposeDelegate = self
message_controller.body = options[:message]
message_controller.recipients = Array(options[:to])
message_controller
end
def can_send_sms?
!!MFMessageComposeViewController.canSendText
end
# Event when the MFMessageComposeViewController is closed
# -------------------------------------------------------------
# the callback is fired if it was present in the constructor
def messageComposeViewController(controller, didFinishWithResult: result)
@delegate.dismissModalViewControllerAnimated(@message_is_animated)
@callback.call Result.new(result) if @callback
end
end
end
================================================
FILE: motion/test_suite_delegate.rb
================================================
class TestSuiteDelegate
attr_accessor :window
def application(application, didFinishLaunchingWithOptions:launchOptions)
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
@window.rootViewController = UIViewController.alloc.init
@window.makeKeyAndVisible
true
end
end
class TestSuiteOSXDelegate
def applicationDidFinishLaunching(notification)
buildMenu
buildWindow
end
def buildWindow
@mainWindow = NSWindow.alloc.initWithContentRect([[240, 180], [480, 360]],
styleMask: NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
backing: NSBackingStoreBuffered,
defer: false)
@mainWindow.title = "BubbleWrap Tests"
end
def buildMenu
@mainMenu = NSMenu.new
appName = "BubbleWrap Tests"
addMenu(appName) do
addItemWithTitle("About #{appName}", action: 'orderFrontStandardAboutPanel:', keyEquivalent: '')
addItem(NSMenuItem.separatorItem)
addItemWithTitle('Preferences', action: 'openPreferences:', keyEquivalent: ',')
addItem(NSMenuItem.separatorItem)
servicesItem = addItemWithTitle('Services', action: nil, keyEquivalent: '')
NSApp.servicesMenu = servicesItem.submenu = NSMenu.new
addItem(NSMenuItem.separatorItem)
addItemWithTitle("Hide #{appName}", action: 'hide:', keyEquivalent: 'h')
item = addItemWithTitle('Hide Others', action: 'hideOtherApplications:', keyEquivalent: 'H')
item.keyEquivalentModifierMask = NSCommandKeyMask|NSAlternateKeyMask
addItemWithTitle('Show All', action: 'unhideAllApplications:', keyEquivalent: '')
addItem(NSMenuItem.separatorItem)
addItemWithTitle("Quit #{appName}", action: 'terminate:', keyEquivalent: 'q')
end
NSApp.helpMenu = addMenu('Help') do
addItemWithTitle("#{appName} Help", action: 'showHelp:', keyEquivalent: '?')
end.menu
NSApp.mainMenu = @mainMenu
end
private
def addMenu(title, &b)
item = createMenu(title, &b)
@mainMenu.addItem item
item
end
def createMenu(title, &b)
menu = NSMenu.alloc.initWithTitle(title)
menu.instance_eval(&b) if b
item = NSMenuItem.alloc.initWithTitle(title, action: nil, keyEquivalent: '')
item.submenu = menu
item
end
end
================================================
FILE: motion/ui/pollute.rb
================================================
# Please, no more! It'll hurt BubbleWrap's compatibility with other libraries.
[
[UIControl, BW::UIControlWrapper],
[UIView, BW::UIViewWrapper],
[UIViewController, BW::UIViewControllerWrapper],
].each do |base, wrapper|
base.send(:include, wrapper)
end
================================================
FILE: motion/ui/ui_activity_view_controller_wrapper.rb
================================================
module BW
class UIActivityViewController < ::UIActivityViewController
class << self
def new(options = {}, presenting_controller = nil, &block)
options = {
activities: nil,
animated: true
}.merge(options)
if options[:item] || options[:items]
items = Array(options[:item] || options[:items])
else
raise ArgumentError, "You must specify at least one item - #{options.inspect}"
end
vc = alloc.initWithActivityItems(items, applicationActivities:options[:activities])
vc.excludedActivityTypes = BW::Constants.get("UIActivityType", Array(options[:excluded])) if options[:excluded]
unless block.nil?
block.weak! if BubbleWrap.use_weak_callbacks?
vc.setCompletionHandler block
end
presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
presenting_controller ||= App.window.rootViewController
presenting_controller.presentViewController(vc, animated:options[:animated], completion: lambda {})
vc
end
end
end
# UIActivityTypes
Constants.register(
UIActivityTypePostToFacebook,
UIActivityTypePostToTwitter,
UIActivityTypePostToWeibo,
UIActivityTypeMessage,
UIActivityTypeMail,
UIActivityTypePrint,
UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList,
UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo,
UIActivityTypeAirDrop
)
end
================================================
FILE: motion/ui/ui_alert_view.rb
================================================
module BW
class UIAlertView < ::UIAlertView
@callbacks = [
:will_present,
:did_present,
:on_system_cancel,
:enable_first_other_button?,
:on_click,
:will_dismiss,
:did_dismiss
]
KEYBOARD_TYPES = {
default: UIKeyboardTypeDefault,
ascii: UIKeyboardTypeASCIICapable,
numbers_punctuation: UIKeyboardTypeNumbersAndPunctuation,
url: UIKeyboardTypeURL,
number_pad: UIKeyboardTypeNumberPad,
phone_pad: UIKeyboardTypePhonePad,
name_phone_pad: UIKeyboardTypeNamePhonePad,
email_address: UIKeyboardTypeEmailAddress,
email: UIKeyboardTypeEmailAddress, # Duplicate to help developers
decimal_pad: UIKeyboardTypeDecimalPad,
twitter: UIKeyboardTypeTwitter,
web_search: UIKeyboardTypeWebSearch,
alphabet: UIKeyboardTypeASCIICapable
}
class << self
attr_reader :callbacks
def new(options = {}, &block)
view = alloc.initWithTitle(options[:title],
message: options[:message],
delegate: nil,
cancelButtonTitle: nil,
otherButtonTitles: nil
)
Array(options[:buttons]).each { |title| view.addButtonWithTitle(title) }
view.style = options[:style]
view.delegate = view
view.cancel_button_index = options[:cancel_button_index]
view.instance_variable_set(:@handlers, {})
block.weak! if block && BubbleWrap.use_weak_callbacks?
options[:on_click] ||= block
callbacks.each do |callback|
view.send(callback, &options[callback]) if options[callback]
end
view
end
def default(options = {}, &block)
options = {buttons: "OK"}.merge!(options)
options[:style] = :default
new(options, &block)
end
def plain_text_input(options = {}, &block)
options = {buttons: ["Cancel", "OK"],
cancel_button_index: 0}.merge!(options)
options[:style] = :plain_text_input
new(options, &block).tap do |view|
view.textFieldAtIndex(0).tap do |tf|
tf.text = options[:text] if options[:text]
tf.placeholder = options[:placeholder] if options[:placeholder]
tf.keyboardType = (KEYBOARD_TYPES[options[:keyboard_type]] || options[:keyboard_type]) if options[:keyboard_type]
end
end
end
def secure_text_input(options = {}, &block)
options = {buttons: ["Cancel", "OK"],
cancel_button_index: 0}.merge!(options)
options[:style] = :secure_text_input
new(options, &block)
end
def login_and_password_input(options = {}, &block)
options = {buttons: ["Cancel", "Log in"],
cancel_button_index: 0}.merge!(options)
options[:style] = :login_and_password_input
new(options, &block)
end
end
def style
alertViewStyle
end
def style=(value)
self.alertViewStyle = Constants.get("UIAlertViewStyle", value) if value
end
def cancel_button_index
cancelButtonIndex
end
def cancel_button_index=(value)
self.cancelButtonIndex = value if value
end
###############################################################################################
attr_accessor :clicked_button
protected :clicked_button=
class ClickedButton
def initialize(alert, index)
@index = index
@title = alert.buttonTitleAtIndex(index)
@cancel = alert.cancelButtonIndex == index
end
attr_reader :index, :title
def cancel?; @cancel end
end
###############################################################################################
attr_reader :handlers
protected :handlers
callbacks.each do |callback|
define_method(callback) do |&block|
return handlers[callback] unless block
handlers[callback] = block if block
self
end
end
# UIAlertViewDelegate protocol ################################################################
def willPresentAlertView(alert)
alert.clicked_button = nil
handlers[:will_present].call(alert) if handlers[:will_present]
end
def didPresentAlertView(alert)
alert.clicked_button = nil
handlers[:did_present].call(alert) if handlers[:did_present]
end
def alertViewCancel(alert)
alert.clicked_button = nil
handlers[:on_system_cancel].call(alert) if handlers[:on_system_cancel]
end
def alertViewShouldEnableFirstOtherButton(alert)
alert.clicked_button = nil
handlers[:enable_first_other_button?].call(alert) if handlers[:enable_first_other_button?]
end
def alertView(alert, clickedButtonAtIndex:index)
alert.clicked_button = ClickedButton.new(alert, index)
handlers[:on_click].call(alert) if handlers[:on_click]
end
def alertView(alert, willDismissWithButtonIndex:index)
alert.clicked_button = ClickedButton.new(alert, index)
handlers[:will_dismiss].call(alert) if handlers[:will_dismiss]
end
def alertView(alert, didDismissWithButtonIndex:index)
alert.clicked_button = ClickedButton.new(alert, index)
handlers[:did_dismiss].call(alert) if handlers[:did_dismiss]
end
###############################################################################################
def plain_text_field
textFieldAtIndex(0) if style == UIAlertViewStylePlainTextInput
end
def secure_text_field
textFieldAtIndex(0) if style == UIAlertViewStyleSecureTextInput
end
def login_text_field
textFieldAtIndex(0) if style == UIAlertViewStyleLoginAndPasswordInput
end
def password_text_field
textFieldAtIndex(1) if style == UIAlertViewStyleLoginAndPasswordInput
end
end
Constants.register(
UIAlertViewStyleDefault,
UIAlertViewStylePlainTextInput,
UIAlertViewStyleSecureTextInput,
UIAlertViewStyleLoginAndPasswordInput
)
end
================================================
FILE: motion/ui/ui_bar_button_item.rb
================================================
module BW
class UIBarButtonItem < ::UIBarButtonItem
class << self
def styled(type, *objects, &block)
if block.nil?
action = nil
else
block.weak! if BubbleWrap.use_weak_callbacks?
action = :call
end
object = objects.size == 1 ? objects.first : objects
style = Constants.get("UIBarButtonItemStyle", type)
item = if object.is_a?(String)
alloc.initWithTitle(object,
style:style,
target:block,
action:action
)
elsif object.is_a?(UIImage)
alloc.initWithImage(object,
style:style,
target:block,
action:action
)
elsif object.is_a?(Array) && object.size == 2 && object.all? { |o| o.is_a?(UIImage) }
alloc.initWithImage(object[0],
landscapeImagePhone:object[1],
style:style,
target:block,
action:action
)
else
raise ArgumentError, "invalid object - #{object.inspect}"
end
item.instance_variable_set(:@target, block)
item
end
def system(type, &block)
if block.nil?
action = nil
else
block.weak! if BubbleWrap.use_weak_callbacks?
action = :call
end
system_item = Constants.get("UIBarButtonSystemItem", type)
item = alloc.initWithBarButtonSystemItem(system_item, target:block, action:action)
item.instance_variable_set(:@target, block)
item
end
def custom(view, &block)
view.when_tapped(true, &block) if block
alloc.initWithCustomView(view)
end
def new(options = {}, &block)
if options[:styled]
args = options.values_at(:title, :image, :landscape).compact
return styled(options[:styled], *args, &block)
end
return system(options[:system], &block) if options[:system]
return custom(options[:custom], &block) if options[:custom]
return custom(options[:view], &block) if options[:view]
raise ArgumentError, "invalid options - #{options.inspect}"
end
def build(options = {}, &block)
NSLog "[DEPRECATED - BW::UIBarButtonItem.build] please use .new instead."
new(options, &block)
end
end
end
Constants.register(
UIBarButtonItemStylePlain,
UIBarButtonItemStyleBordered,
UIBarButtonItemStyleDone,
UIBarButtonSystemItemDone,
UIBarButtonSystemItemCancel,
UIBarButtonSystemItemEdit,
UIBarButtonSystemItemSave,
UIBarButtonSystemItemAdd,
UIBarButtonSystemItemFlexibleSpace,
UIBarButtonSystemItemFixedSpace,
UIBarButtonSystemItemCompose,
UIBarButtonSystemItemReply,
UIBarButtonSystemItemAction,
UIBarButtonSystemItemOrganize,
UIBarButtonSystemItemBookmarks,
UIBarButtonSystemItemSearch,
UIBarButtonSystemItemRefresh,
UIBarButtonSystemItemStop,
UIBarButtonSystemItemCamera,
UIBarButtonSystemItemTrash,
UIBarButtonSystemItemPlay,
UIBarButtonSystemItemPause,
UIBarButtonSystemItemRewind,
UIBarButtonSystemItemFastForward,
UIBarButtonSystemItemUndo,
UIBarButtonSystemItemRedo,
UIBarButtonSystemItemPageCurl,
)
end
================================================
FILE: motion/ui/ui_control_wrapper.rb
================================================
module BubbleWrap
module UIControlWrapper
def when(events, options = {}, &block)
events = BW::Constants.get("UIControlEvent", events)
@callback ||= {}
@callback[events] ||= []
unless options[:append]
@callback[events] = []
removeTarget(nil, action: nil, forControlEvents: events)
end
@callback[events] << block
block.weak! if BubbleWrap.use_weak_callbacks?
addTarget(@callback[events].last, action:'call', forControlEvents: events)
end
end
Constants.register(
UIControlEventTouchDown,
UIControlEventTouchDownRepeat,
UIControlEventTouchDragInside,
UIControlEventTouchDragOutside,
UIControlEventTouchDragEnter,
UIControlEventTouchDragExit,
UIControlEventTouchUpInside,
UIControlEventTouchUpOutside,
UIControlEventTouchCancel,
UIControlEventValueChanged,
UIControlEventEditingDidBegin,
UIControlEventEditingChanged,
UIControlEventEditingDidEnd,
UIControlEventEditingDidEndOnExit,
UIControlEventAllTouchEvents,
UIControlEventAllEditingEvents,
# UIControlEventApplicationReserved,
gitextract_83mw8g5j/
├── .gitignore
├── .travis.yml
├── .yardopts
├── CHANGELOG.md
├── GEM.md
├── GETTING_STARTED.md
├── Gemfile
├── HACKING.md
├── LICENSE
├── README.md
├── Rakefile
├── bubble-wrap.gemspec
├── lib/
│ ├── bubble-wrap/
│ │ ├── all.rb
│ │ ├── camera.rb
│ │ ├── core.rb
│ │ ├── ext/
│ │ │ └── motion_project_app.rb
│ │ ├── ext.rb
│ │ ├── font.rb
│ │ ├── loader.rb
│ │ ├── location.rb
│ │ ├── mail.rb
│ │ ├── media.rb
│ │ ├── motion.rb
│ │ ├── network-indicator.rb
│ │ ├── reactor.rb
│ │ ├── requirement/
│ │ │ └── path_manipulation.rb
│ │ ├── requirement.rb
│ │ ├── rss_parser.rb
│ │ ├── sms.rb
│ │ ├── test.rb
│ │ ├── ui.rb
│ │ └── version.rb
│ └── bubble-wrap.rb
├── motion/
│ ├── core/
│ │ ├── app.rb
│ │ ├── device/
│ │ │ ├── ios/
│ │ │ │ ├── camera.rb
│ │ │ │ ├── camera_wrapper.rb
│ │ │ │ └── screen.rb
│ │ │ ├── osx/
│ │ │ │ └── screen.rb
│ │ │ └── screen.rb
│ │ ├── device.rb
│ │ ├── ios/
│ │ │ ├── app.rb
│ │ │ ├── device.rb
│ │ │ └── ns_index_path.rb
│ │ ├── json.rb
│ │ ├── kvo.rb
│ │ ├── ns_index_path.rb
│ │ ├── ns_notification_center.rb
│ │ ├── ns_url_request.rb
│ │ ├── ns_user_defaults.rb
│ │ ├── osx/
│ │ │ ├── app.rb
│ │ │ └── device.rb
│ │ ├── persistence.rb
│ │ ├── pollute.rb
│ │ ├── string.rb
│ │ └── time.rb
│ ├── core.rb
│ ├── font/
│ │ └── font.rb
│ ├── ios/
│ │ └── 8/
│ │ └── location_constants.rb
│ ├── location/
│ │ ├── location.rb
│ │ └── pollute.rb
│ ├── mail/
│ │ ├── mail.rb
│ │ └── result.rb
│ ├── media/
│ │ ├── media.rb
│ │ └── player.rb
│ ├── motion/
│ │ ├── accelerometer.rb
│ │ ├── device_motion.rb
│ │ ├── gyroscope.rb
│ │ ├── magnetometer.rb
│ │ └── motion.rb
│ ├── network-indicator/
│ │ └── network-indicator.rb
│ ├── reactor/
│ │ ├── default_deferrable.rb
│ │ ├── deferrable.rb
│ │ ├── dependent_deferrable.rb
│ │ ├── eventable.rb
│ │ ├── future.rb
│ │ ├── periodic_timer.rb
│ │ ├── queue.rb
│ │ ├── thread_aware_deferrable.rb
│ │ └── timer.rb
│ ├── reactor.rb
│ ├── rss_parser.rb
│ ├── shortcut.rb
│ ├── sms/
│ │ ├── result.rb
│ │ └── sms.rb
│ ├── test_suite_delegate.rb
│ ├── ui/
│ │ ├── pollute.rb
│ │ ├── ui_activity_view_controller_wrapper.rb
│ │ ├── ui_alert_view.rb
│ │ ├── ui_bar_button_item.rb
│ │ ├── ui_control_wrapper.rb
│ │ ├── ui_view_controller_wrapper.rb
│ │ └── ui_view_wrapper.rb
│ └── util/
│ ├── constants.rb
│ └── deprecated.rb
├── resources/
│ ├── Localizable.strings
│ └── atom.xml
├── samples/
│ ├── alert/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── alert_view_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── camera/
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── camera_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── gesture/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ ├── controllers/
│ │ │ │ └── drawing_view_controller.rb
│ │ │ ├── helpers/
│ │ │ │ └── drawing_helper.rb
│ │ │ └── views/
│ │ │ └── drawing/
│ │ │ ├── gesture_view.rb
│ │ │ └── rect_view.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── location/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ ├── controllers/
│ │ │ │ └── places_list_controller.rb
│ │ │ └── models/
│ │ │ └── places.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ ├── media/
│ │ ├── .gitignore
│ │ ├── Gemfile
│ │ ├── Rakefile
│ │ ├── app/
│ │ │ ├── app_delegate.rb
│ │ │ └── controllers/
│ │ │ └── play_controller.rb
│ │ └── spec/
│ │ └── main_spec.rb
│ └── osx/
│ ├── Gemfile
│ ├── Rakefile
│ ├── app/
│ │ ├── app_delegate.rb
│ │ └── menu.rb
│ ├── resources/
│ │ └── Credits.rtf
│ └── spec/
│ └── main_spec.rb
└── spec/
├── lib/
│ ├── bubble-wrap/
│ │ ├── ext/
│ │ │ ├── motion_project_app_spec.rb
│ │ │ └── motion_project_config_spec.rb
│ │ ├── requirement/
│ │ │ └── path_manipulation_spec.rb
│ │ └── requirement_spec.rb
│ ├── bubble-wrap_spec.rb
│ └── motion_stub.rb
└── motion/
├── core/
│ ├── app_spec.rb
│ ├── device/
│ │ ├── ios/
│ │ │ ├── camera_spec.rb
│ │ │ ├── camera_wrapper_spec.rb
│ │ │ ├── device_spec.rb
│ │ │ └── screen_spec.rb
│ │ └── osx/
│ │ └── screen_spec.rb
│ ├── device_spec.rb
│ ├── ios/
│ │ ├── app_spec.rb
│ │ └── ns_index_path_spec.rb
│ ├── json_spec.rb
│ ├── kvo_spec.rb
│ ├── ns_index_path_spec.rb
│ ├── ns_notification_center_spec.rb
│ ├── osx/
│ │ └── app_spec.rb
│ ├── persistence_spec.rb
│ ├── string_spec.rb
│ └── time_spec.rb
├── core_spec.rb
├── font/
│ └── font_spec.rb
├── location/
│ └── location_spec.rb
├── mail/
│ ├── mail_spec.rb
│ └── result_spec.rb
├── media/
│ └── player_spec.rb
├── motion/
│ └── core_motion_spec.rb
├── network-indicator/
│ └── network_indicator_spec.rb
├── reactor/
│ ├── deferrable_spec.rb
│ ├── dependent_deferrable_spec.rb
│ ├── eventable_spec.rb
│ └── thread_aware_deferrable_spec.rb
├── reactor_spec.rb
├── rss_parser_spec.rb
├── sms/
│ ├── result_spec.rb
│ └── sms_spec.rb
├── ui/
│ ├── pollute_spec.rb
│ ├── ui_activity_view_controller_wrapper_spec.rb
│ ├── ui_alert_view_spec.rb
│ ├── ui_bar_button_item_spec.rb
│ ├── ui_control_wrapper_spec.rb
│ ├── ui_view_controller_wrapper_spec.rb
│ └── ui_view_wrapper_spec.rb
└── util/
├── constants_spec.rb
└── deprecated_spec.rb
SYMBOL INDEX (690 symbols across 99 files)
FILE: lib/bubble-wrap/ext/motion_project_app.rb
type BubbleWrap (line 1) | module BubbleWrap
type Ext (line 2) | module Ext
type BuildTask (line 3) | module BuildTask
function extended (line 5) | def self.extended(base)
type Config (line 22) | module Config
function config_with_bubblewrap (line 23) | def config_with_bubblewrap
function extended (line 29) | def self.extended(base)
type Platforms (line 36) | module Platforms
function osx? (line 37) | def osx?
FILE: lib/bubble-wrap/loader.rb
type BubbleWrap (line 14) | module BubbleWrap
function root (line 19) | def root
function require (line 23) | def require(file_spec, &block)
function require_ios (line 27) | def require_ios(requirement = nil, &callback)
function require_osx (line 35) | def require_osx(requirement = nil, &callback)
function before_config (line 43) | def before_config(app)
function after_config (line 49) | def after_config(config)
FILE: lib/bubble-wrap/requirement.rb
type BubbleWrap (line 3) | module BubbleWrap
class Requirement (line 4) | class Requirement
method initialize (line 11) | def initialize(file,root)
method relative (line 16) | def relative
method depends_on (line 20) | def depends_on(file_or_paths)
method uses_framework (line 29) | def uses_framework(framework_name)
method dependencies (line 33) | def dependencies
method to_s (line 38) | def to_s
method file_dependencies (line 42) | def file_dependencies
method frameworks (line 46) | def frameworks
method scan (line 54) | def scan(caller_location, file_spec, &block)
method file (line 65) | def file(relative)
method files (line 69) | def files(app_files=nil)
method clear! (line 75) | def clear!
method files_dependencies (line 79) | def files_dependencies
method frameworks (line 87) | def frameworks(app_frameworks=nil)
FILE: lib/bubble-wrap/requirement/path_manipulation.rb
type BubbleWrap (line 1) | module BubbleWrap
class Requirement (line 2) | class Requirement
type PathManipulation (line 3) | module PathManipulation
function convert_caller_to_root_path (line 5) | def convert_caller_to_root_path(path)
function convert_caller_to_path (line 11) | def convert_caller_to_path(string)
function convert_to_absolute_path (line 20) | def convert_to_absolute_path(path)
function strip_up_to_last_lib (line 24) | def strip_up_to_last_lib(path)
function convert_to_relative (line 39) | def convert_to_relative(path,root)
FILE: lib/bubble-wrap/version.rb
type BubbleWrap (line 1) | module BubbleWrap
FILE: motion/core.rb
type BubbleWrap (line 1) | module BubbleWrap
function rgb_color (line 5) | def rgb_color(r,g,b)
function rgba_color (line 10) | def rgba_color(r,g,b,a)
function localized_string (line 22) | def localized_string(key, value=nil)
function p (line 27) | def p(arg)
function create_uuid (line 31) | def create_uuid
FILE: motion/core/app.rb
type BubbleWrap (line 3) | module BubbleWrap
type App (line 4) | module App
function documents_path (line 11) | def documents_path
function resources_path (line 17) | def resources_path
function notification_center (line 23) | def notification_center
function user_cache (line 27) | def user_cache
function run_after (line 35) | def run_after(delay,&block)
function states (line 45) | def states
function info_plist (line 49) | def info_plist
function name (line 53) | def name
function identifier (line 57) | def identifier
function version (line 61) | def version
function short_version (line 65) | def short_version
function current_locale (line 70) | def current_locale
function environment (line 80) | def environment
function development? (line 84) | def development?
function test? (line 88) | def test?
function release? (line 92) | def release?
function osx? (line 96) | def osx?
function ios? (line 100) | def ios?
FILE: motion/core/device.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
function screen (line 6) | def screen
function retina? (line 11) | def retina?
FILE: motion/core/device/ios/camera.rb
type BubbleWrap (line 4) | module BubbleWrap
type Device (line 5) | module Device
class Camera (line 6) | class Camera
type Error (line 7) | module Error
method front (line 34) | def self.front
method rear (line 39) | def self.rear
method available? (line 44) | def self.available?
method any (line 50) | def any
method popover_from (line 56) | def popover_from(view)
method initialize (line 61) | def initialize(location = :none)
method location= (line 65) | def location=(location)
method flash? (line 72) | def flash?
method picture (line 99) | def picture(options = {}, presenting_controller = nil, &block)
method popoverControllerDidDismissPopover (line 166) | def popoverControllerDidDismissPopover(popoverController)
method imagePickerControllerDidCancel (line 172) | def imagePickerControllerDidCancel(picker)
method imagePickerController (line 181) | def imagePickerController(picker, didFinishPickingMediaWithInfo: i...
method picker (line 205) | def picker
method dismiss (line 210) | def dismiss
method source_type_available? (line 220) | def self.source_type_available?(source_type)
method media_type_available? (line 226) | def self.media_type_available?(media_type, for_source_type: source...
method camera_device (line 231) | def camera_device
method media_type_to_symbol (line 236) | def media_type_to_symbol(media_type)
method symbol_to_media_type (line 241) | def symbol_to_media_type(symbol)
method error (line 245) | def error(type)
FILE: motion/core/device/ios/camera_wrapper.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
type CameraWrapper (line 3) | module CameraWrapper
function front (line 9) | def front
function front? (line 15) | def front?
function rear (line 21) | def rear
function rear? (line 27) | def rear?
function any (line 34) | def any
function photo_library (line 38) | def photo_library
function any? (line 44) | def any?
function available? (line 50) | def available?
FILE: motion/core/device/ios/screen.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
type Screen (line 3) | module Screen
function retina? (line 9) | def retina?(screen=UIScreen.mainScreen)
function orientation (line 19) | def orientation(device_orientation=UIDevice.currentDevice.orientat...
function interface_orientation (line 40) | def interface_orientation(device_orientation=UIDevice.currentDevic...
function width (line 63) | def width
function height (line 73) | def height
function width_for_orientation (line 80) | def width_for_orientation(o=orientation)
function height_for_orientation (line 88) | def height_for_orientation(o=orientation)
FILE: motion/core/device/osx/screen.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
type Screen (line 3) | module Screen
function retina? (line 9) | def retina?(screen=NSScreen.mainScreen)
FILE: motion/core/device/screen.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
type Screen (line 3) | module Screen
FILE: motion/core/ios/app.rb
type BubbleWrap (line 1) | module BubbleWrap
type App (line 2) | module App
function open_url (line 10) | def open_url(url)
function can_open_url (line 21) | def can_open_url(url)
function alert (line 38) | def alert(title, *args, &block)
function frame (line 59) | def frame
function bounds (line 64) | def bounds
function delegate (line 69) | def delegate
function shared (line 74) | def shared
function windows (line 78) | def windows
function window (line 83) | def window
FILE: motion/core/ios/device.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
function iphone? (line 7) | def iphone?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
function ipad? (line 13) | def ipad?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
function long_screen? (line 19) | def long_screen?(idiom=UIDevice.currentDevice.userInterfaceIdiom, sc...
function camera (line 26) | def camera
function front_camera? (line 32) | def front_camera?(picker=UIImagePickerController)
function rear_camera? (line 39) | def rear_camera?(picker=UIImagePickerController)
function simulator? (line 46) | def simulator?
function force_touch? (line 56) | def force_touch?
function ios_version (line 66) | def ios_version
function vendor_identifier (line 72) | def vendor_identifier
function orientation (line 77) | def orientation
function interface_orientation (line 82) | def interface_orientation
FILE: motion/core/ios/ns_index_path.rb
type NSIndexPathWrap (line 1) | module NSIndexPathWrap
function + (line 3) | def +(aNumber)
function - (line 7) | def -(aNumber)
FILE: motion/core/json.rb
type BubbleWrap (line 1) | module BubbleWrap
type JSON (line 4) | module JSON
class ParserError (line 6) | class ParserError < StandardError; end
function parse (line 15) | def self.parse(str_data, &block)
function generate (line 30) | def self.generate(obj)
FILE: motion/core/kvo.rb
type BubbleWrap (line 19) | module BubbleWrap
type KVO (line 20) | module KVO
class Registry (line 21) | class Registry
method initialize (line 30) | def initialize(value_keys = [:old, :new])
method add (line 48) | def add(target, key_path, &block)
method remove (line 56) | def remove(target, key_path)
method registered? (line 69) | def registered?(target, key_path)
method remove_all (line 73) | def remove_all
method each_key_path (line 77) | def each_key_path
method observeValueForKeyPath (line 87) | def observeValueForKeyPath(key_path, ofObject: target, change: cha...
function observe (line 103) | def observe(target = self, key_paths, &block)
function observe! (line 116) | def observe!(target = self, key_paths, &block)
function unobserve (line 132) | def unobserve(target = self, key_paths)
function unobserve! (line 136) | def unobserve!(target = self, key_paths)
function unobserve_all (line 140) | def unobserve_all
function observers_registry (line 154) | def observers_registry
function immediate_observers_registry (line 158) | def immediate_observers_registry
function remove_from_registry_if_exists (line 162) | def remove_from_registry_if_exists(target, key_paths, registry)
FILE: motion/core/ns_index_path.rb
type NSIndexPathWrap (line 1) | module NSIndexPathWrap
function [] (line 6) | def [](position)
function each (line 14) | def each
FILE: motion/core/ns_notification_center.rb
class NSNotificationCenter (line 1) | class NSNotificationCenter
method observers (line 2) | def observers
method observe (line 6) | def observe(name, object=nil, &proc)
method unobserve (line 13) | def unobserve(observer)
method post (line 19) | def post(name, object=nil, info=nil)
FILE: motion/core/ns_url_request.rb
class NSURLRequest (line 1) | class NSURLRequest
method to_s (line 5) | def to_s
FILE: motion/core/ns_user_defaults.rb
class NSUserDefaults (line 3) | class NSUserDefaults
method [] (line 6) | def [](key)
method []= (line 11) | def []=(key, val)
FILE: motion/core/osx/app.rb
type BubbleWrap (line 1) | module BubbleWrap
type App (line 2) | module App
function open_url (line 9) | def open_url(url)
function delegate (line 15) | def delegate
function shared (line 20) | def shared
FILE: motion/core/osx/device.rb
type BubbleWrap (line 1) | module BubbleWrap
type Device (line 2) | module Device
FILE: motion/core/persistence.rb
type BubbleWrap (line 2) | module BubbleWrap
type Persistence (line 3) | module Persistence
function app_key (line 6) | def app_key
function []= (line 10) | def []=(key, value)
function [] (line 15) | def [](key)
function merge (line 25) | def merge(values)
function delete (line 32) | def delete(key)
function storage (line 39) | def storage
function storage_key (line 43) | def storage_key(key)
function all (line 47) | def all
FILE: motion/core/string.rb
type BubbleWrap (line 1) | module BubbleWrap
type String (line 5) | module String
function camelize (line 8) | def camelize(uppercase_first_letter = true)
function underscore (line 26) | def underscore
function to_url_encoded (line 36) | def to_url_encoded(encoding = nil, legacy = false)
function to_url_decoded (line 46) | def to_url_decoded(encoding = nil, legacy = false)
function to_encoded_data (line 59) | def to_encoded_data(encoding = NSUTF8StringEncoding)
function to_color (line 63) | def to_color
FILE: motion/core/time.rb
class Time (line 1) | class Time
method iso8601 (line 3) | def self.iso8601(time)
method iso8601_zulu (line 21) | def self.iso8601_zulu(time)
method iso8601_with_timezone (line 26) | def self.iso8601_with_timezone(time)
method iso8601_with_fractional_seconds (line 31) | def self.iso8601_with_fractional_seconds(time)
method iso8601_with_fractional_seconds_and_timesone (line 36) | def self.iso8601_with_fractional_seconds_and_timesone(time)
method cached_date_formatter (line 43) | def self.cached_date_formatter(dateFormat)
FILE: motion/font/font.rb
type BubbleWrap (line 1) | module BubbleWrap
type Font (line 2) | module Font
function bold (line 5) | def bold(size = nil)
function system (line 9) | def system(size = nil)
function italic (line 13) | def italic(size = nil)
function new (line 23) | def new(params = {}, *args)
function attributes (line 69) | def attributes(params = {})
FILE: motion/ios/8/location_constants.rb
type BW (line 1) | module BW
type Location (line 10) | module Location
function authorized? (line 13) | def authorized?
FILE: motion/location/location.rb
type BubbleWrap (line 4) | module BubbleWrap
type CLLocationWrap (line 5) | module CLLocationWrap
function latitude (line 7) | def latitude
function longitude (line 11) | def longitude
type Location (line 16) | module Location
type Error (line 17) | module Error
function get (line 57) | def get(options = {}, &block)
function get_significant (line 93) | def get_significant(options = {}, &block)
function get_once (line 122) | def get_once(options = {}, &block)
function get_compass (line 126) | def get_compass(options = {}, &block)
function get_compass_once (line 130) | def get_compass_once(options = {}, &block)
function start (line 135) | def start
function stop (line 147) | def stop
function location_manager (line 158) | def location_manager
function enabled? (line 165) | def enabled?
function initialized? (line 170) | def initialized?
function authorized? (line 175) | def authorized?
function error (line 181) | def error(type)
function locationManager (line 189) | def locationManager(manager, didUpdateLocations:locations)
function locationManager (line 205) | def locationManager(manager, didUpdateHeading:newHeading)
function locationManager (line 222) | def locationManager(manager, didFailWithError:error)
function locationManager (line 243) | def locationManager(manager, didChangeAuthorizationStatus:status)
function locationManagerShouldDisplayHeadingCalibration (line 252) | def locationManagerShouldDisplayHeadingCalibration(manager)
FILE: motion/mail/mail.rb
type BubbleWrap (line 1) | module BubbleWrap
type Mail (line 2) | module Mail
function compose (line 25) | def compose(options = {}, &callback)
function create_mail_controller (line 46) | def create_mail_controller(options = {})
function can_send_mail? (line 65) | def can_send_mail?
function mailComposeController (line 73) | def mailComposeController(controller, didFinishWithResult: result, e...
FILE: motion/mail/result.rb
type BubbleWrap (line 1) | module BubbleWrap
type Mail (line 2) | module Mail
class Result (line 3) | class Result
method initialize (line 6) | def initialize(result, error)
method sent? (line 11) | def sent?
method canceled? (line 15) | def canceled?
method saved? (line 19) | def saved?
method failed? (line 23) | def failed?
FILE: motion/media/media.rb
type BubbleWrap (line 1) | module BubbleWrap
type Media (line 2) | module Media
function play_modal (line 5) | def play_modal(*args, &block)
function play (line 9) | def play(*args, &block)
FILE: motion/media/player.rb
type BubbleWrap (line 1) | module BubbleWrap
type Media (line 2) | module Media
type Error (line 3) | module Error
class InvalidPlayerType (line 4) | class InvalidPlayerType < StandardError; end
class NilPlayerCallback (line 5) | class NilPlayerCallback < StandardError; end
class Player (line 8) | class Player
method play_modal (line 17) | def play_modal(content_url, options = {})
method play (line 66) | def play(content_url, options = {}, &block)
method stop (line 114) | def stop
method media_player (line 128) | def media_player
method set_player_options (line 138) | def set_player_options(options)
FILE: motion/motion/accelerometer.rb
type BubbleWrap (line 1) | module BubbleWrap
type Motion (line 2) | module Motion
class Accelerometer (line 3) | class Accelerometer < GenericMotionInterface
method start (line 5) | def start(options={}, &handler)
method handle_result (line 20) | def handle_result(result_data, error, handler)
method available? (line 36) | def available?
method active? (line 40) | def active?
method data (line 44) | def data
method stop (line 48) | def stop
FILE: motion/motion/device_motion.rb
type BubbleWrap (line 1) | module BubbleWrap
type Motion (line 2) | module Motion
class DeviceMotion (line 3) | class DeviceMotion < GenericMotionInterface
method start (line 5) | def start(options={}, &handler)
method handle_result (line 35) | def handle_result(result_data, error, handler)
method convert_reference_frame (line 105) | def convert_reference_frame(reference_frame)
method available? (line 120) | def available?
method active? (line 124) | def active?
method data (line 128) | def data
method stop (line 132) | def stop
FILE: motion/motion/gyroscope.rb
type BubbleWrap (line 1) | module BubbleWrap
type Motion (line 2) | module Motion
class Gyroscope (line 3) | class Gyroscope < GenericMotionInterface
method start (line 5) | def start(options={}, &handler)
method handle_result (line 20) | def handle_result(result_data, error, handler)
method available? (line 36) | def available?
method active? (line 40) | def active?
method data (line 44) | def data
method stop (line 48) | def stop
FILE: motion/motion/magnetometer.rb
type BubbleWrap (line 1) | module BubbleWrap
type Motion (line 2) | module Motion
class Magnetometer (line 3) | class Magnetometer < GenericMotionInterface
method start (line 5) | def start(options={}, &handler)
method handle_result (line 20) | def handle_result(result_data, error, handler)
method available? (line 36) | def available?
method active? (line 40) | def active?
method data (line 44) | def data
method stop (line 48) | def stop
FILE: motion/motion/motion.rb
type BubbleWrap (line 3) | module BubbleWrap
type Motion (line 30) | module Motion
function manager (line 33) | def manager
function accelerometer (line 37) | def accelerometer
function gyroscope (line 41) | def gyroscope
function magnetometer (line 45) | def magnetometer
function device (line 49) | def device
type Error (line 56) | module Error
class GenericMotionInterface (line 59) | class GenericMotionInterface
method initialize (line 61) | def initialize(manager)
method repeat (line 65) | def repeat(options={}, &blk)
method every (line 73) | def every(time=nil, options={}, &blk)
method once (line 87) | def once(options={}, &blk)
method convert_queue (line 103) | def convert_queue(queue_name)
method internal_handler (line 122) | def internal_handler(handler)
type Motion (line 55) | module Motion
function manager (line 33) | def manager
function accelerometer (line 37) | def accelerometer
function gyroscope (line 41) | def gyroscope
function magnetometer (line 45) | def magnetometer
function device (line 49) | def device
type Error (line 56) | module Error
class GenericMotionInterface (line 59) | class GenericMotionInterface
method initialize (line 61) | def initialize(manager)
method repeat (line 65) | def repeat(options={}, &blk)
method every (line 73) | def every(time=nil, options={}, &blk)
method once (line 87) | def once(options={}, &blk)
method convert_queue (line 103) | def convert_queue(queue_name)
method internal_handler (line 122) | def internal_handler(handler)
FILE: motion/network-indicator/network-indicator.rb
type BubbleWrap (line 1) | module BubbleWrap
type NetworkIndicator (line 2) | module NetworkIndicator
function counter (line 7) | def counter
function show (line 11) | def show
function hide (line 22) | def hide
function update_spinner_timer (line 39) | def update_spinner_timer
function update_spinner (line 43) | def update_spinner
function visible? (line 57) | def visible?
function reset! (line 61) | def reset!
FILE: motion/reactor.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
function reactor_running? (line 6) | def reactor_running?
function add_timer (line 14) | def add_timer(interval, callback=nil, &blk)
function cancel_timer (line 30) | def cancel_timer(timer)
function add_periodic_timer (line 45) | def add_periodic_timer(interval, *args, &blk)
function defer (line 70) | def defer(op=nil,cb=nil,&blk)
function defer_on_main (line 79) | def defer_on_main(op=nil,cb=nil,&blk)
function schedule (line 87) | def schedule(*args, &blk)
function schedule_on_main (line 101) | def schedule_on_main(*args, &blk)
FILE: motion/reactor/default_deferrable.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class DefaultDeferrable (line 5) | class DefaultDeferrable
FILE: motion/reactor/deferrable.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
type Deferrable (line 4) | module Deferrable
function callback (line 18) | def callback(&blk)
function cancel_timeout (line 30) | def cancel_timeout
function errback (line 41) | def errback(&blk)
function execute_block (line 53) | def execute_block(&blk)
function delegate (line 58) | def delegate(delegate)
function errback_delegate (line 64) | def errback_delegate(delegate)
function callback_delegate (line 71) | def callback_delegate(delegate)
function fail (line 79) | def fail(*args)
function set_deferred_status (line 110) | def set_deferred_status(status, *args)
function succeed (line 135) | def succeed(*args)
function timeout (line 144) | def timeout(seconds)
function deferred_status (line 150) | def deferred_status
function deferred_args (line 154) | def deferred_args
FILE: motion/reactor/dependent_deferrable.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class DependentDeferrable (line 3) | class DependentDeferrable < DefaultDeferrable
method on (line 10) | def self.on(*args)
FILE: motion/reactor/eventable.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
type Eventable (line 4) | module Eventable
function on (line 9) | def on(event, method = nil, &blk)
function off (line 17) | def off(event, method = nil, &blk)
function trigger (line 30) | def trigger(event, *args)
function __events__ (line 39) | def __events__
function _events_for_key (line 43) | def _events_for_key(event)
FILE: motion/reactor/future.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
type Future (line 3) | module Future
function future (line 6) | def future arg, cb=nil, eb=nil, &blk
FILE: motion/reactor/periodic_timer.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class PeriodicTimer (line 4) | class PeriodicTimer
method initialize (line 10) | def initialize(interval, *args, &blk)
method cancel (line 31) | def cancel
FILE: motion/reactor/queue.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class Queue (line 15) | class Queue
method initialize (line 18) | def initialize
method empty? (line 23) | def empty?
method size (line 28) | def size
method push (line 34) | def push(*items)
method pop (line 44) | def pop(*args, &blk)
FILE: motion/reactor/thread_aware_deferrable.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class ThreadAwareDeferrable (line 3) | class ThreadAwareDeferrable < DefaultDeferrable
method callback (line 8) | def callback(&blk)
method errback (line 14) | def errback(&blk)
method execute_block (line 20) | def execute_block(&blk)
method cache_block_queue (line 29) | def cache_block_queue(&blk)
FILE: motion/reactor/timer.rb
type BubbleWrap (line 1) | module BubbleWrap
type Reactor (line 2) | module Reactor
class Timer (line 4) | class Timer
method initialize (line 8) | def initialize(leeway, callback=nil, &blk)
method cancel (line 21) | def cancel
FILE: motion/rss_parser.rb
type BubbleWrap (line 22) | module BubbleWrap
class RSSParser (line 23) | class RSSParser
class RSSItem (line 30) | class RSSItem
method initialize (line 33) | def initialize
method to_hash (line 37) | def to_hash
method initialize (line 51) | def initialize(input, data=false)
method state= (line 64) | def state=(new_state)
method parse (line 78) | def parse(&block)
method parserDidStartDocument (line 94) | def parserDidStartDocument(parser)
method parser (line 100) | def parser(parser, didStartElement:element, namespaceURI:uri, qualif...
method parser (line 110) | def parser(parser, foundCharacters:string)
method parser (line 118) | def parser(parser, didEndElement:element, namespaceURI:uri, qualifie...
method parser (line 128) | def parser(parser, parseErrorOccurred:parse_error)
method parserDidEndDocument (line 137) | def parserDidEndDocument(parser)
method parserError (line 142) | def parserError
FILE: motion/shortcut.rb
type BubbleWrap (line 5) | module BubbleWrap
function debug= (line 8) | def self.debug=(val)
function debug? (line 12) | def self.debug?
function use_weak_callbacks= (line 16) | def self.use_weak_callbacks=(val)
function use_weak_callbacks? (line 20) | def self.use_weak_callbacks?
function version (line 24) | def version
FILE: motion/sms/result.rb
type BubbleWrap (line 1) | module BubbleWrap
type SMS (line 2) | module SMS
class Result (line 3) | class Result
method initialize (line 6) | def initialize(result)
method sent? (line 10) | def sent?
method canceled? (line 14) | def canceled?
method failed? (line 18) | def failed?
FILE: motion/sms/sms.rb
type BubbleWrap (line 1) | module BubbleWrap
type SMS (line 2) | module SMS
function compose (line 22) | def compose(options = {}, &callback)
function create_message_controller (line 32) | def create_message_controller(options = {})
function can_send_sms? (line 40) | def can_send_sms?
function messageComposeViewController (line 48) | def messageComposeViewController(controller, didFinishWithResult: re...
FILE: motion/test_suite_delegate.rb
class TestSuiteDelegate (line 1) | class TestSuiteDelegate
method application (line 4) | def application(application, didFinishLaunchingWithOptions:launchOptions)
class TestSuiteOSXDelegate (line 12) | class TestSuiteOSXDelegate
method applicationDidFinishLaunching (line 13) | def applicationDidFinishLaunching(notification)
method buildWindow (line 18) | def buildWindow
method buildMenu (line 26) | def buildMenu
method addMenu (line 55) | def addMenu(title, &b)
method createMenu (line 61) | def createMenu(title, &b)
FILE: motion/ui/ui_activity_view_controller_wrapper.rb
type BW (line 1) | module BW
class UIActivityViewController (line 2) | class UIActivityViewController < ::UIActivityViewController
method new (line 4) | def new(options = {}, presenting_controller = nil, &block)
FILE: motion/ui/ui_alert_view.rb
type BW (line 1) | module BW
class UIAlertView (line 2) | class UIAlertView < ::UIAlertView
method new (line 32) | def new(options = {}, &block)
method default (line 58) | def default(options = {}, &block)
method plain_text_input (line 64) | def plain_text_input(options = {}, &block)
method secure_text_input (line 77) | def secure_text_input(options = {}, &block)
method login_and_password_input (line 84) | def login_and_password_input(options = {}, &block)
method style (line 92) | def style
method style= (line 96) | def style=(value)
method cancel_button_index (line 100) | def cancel_button_index
method cancel_button_index= (line 104) | def cancel_button_index=(value)
class ClickedButton (line 113) | class ClickedButton
method initialize (line 114) | def initialize(alert, index)
method cancel? (line 121) | def cancel?; @cancel end
method willPresentAlertView (line 140) | def willPresentAlertView(alert)
method didPresentAlertView (line 145) | def didPresentAlertView(alert)
method alertViewCancel (line 150) | def alertViewCancel(alert)
method alertViewShouldEnableFirstOtherButton (line 155) | def alertViewShouldEnableFirstOtherButton(alert)
method alertView (line 160) | def alertView(alert, clickedButtonAtIndex:index)
method alertView (line 165) | def alertView(alert, willDismissWithButtonIndex:index)
method alertView (line 170) | def alertView(alert, didDismissWithButtonIndex:index)
method plain_text_field (line 177) | def plain_text_field
method secure_text_field (line 181) | def secure_text_field
method login_text_field (line 185) | def login_text_field
method password_text_field (line 189) | def password_text_field
FILE: motion/ui/ui_bar_button_item.rb
type BW (line 1) | module BW
class UIBarButtonItem (line 2) | class UIBarButtonItem < ::UIBarButtonItem
method styled (line 4) | def styled(type, *objects, &block)
method system (line 41) | def system(type, &block)
method custom (line 55) | def custom(view, &block)
method new (line 60) | def new(options = {}, &block)
method build (line 74) | def build(options = {}, &block)
FILE: motion/ui/ui_control_wrapper.rb
type BubbleWrap (line 1) | module BubbleWrap
type UIControlWrapper (line 2) | module UIControlWrapper
function when (line 3) | def when(events, options = {}, &block)
FILE: motion/ui/ui_view_controller_wrapper.rb
type BubbleWrap (line 1) | module BubbleWrap
type UIViewControllerWrapper (line 2) | module UIViewControllerWrapper
function content_frame (line 6) | def content_frame
FILE: motion/ui/ui_view_wrapper.rb
type BubbleWrap (line 1) | module BubbleWrap
type UIViewWrapper (line 2) | module UIViewWrapper
function when_tapped (line 3) | def when_tapped(enableInteraction=true, &proc)
function when_pinched (line 7) | def when_pinched(enableInteraction=true, &proc)
function when_rotated (line 11) | def when_rotated(enableInteraction=true, &proc)
function when_swiped (line 15) | def when_swiped(enableInteraction=true, &proc)
function when_panned (line 19) | def when_panned(enableInteraction=true, &proc)
function when_screen_edge_panned (line 23) | def when_screen_edge_panned(enableInteraction=true, &proc)
function when_pressed (line 27) | def when_pressed(enableInteraction=true, &proc)
function deprecated_methods (line 31) | def self.deprecated_methods
function handle_gesture (line 44) | def handle_gesture(recognizer)
function add_gesture_recognizer_helper (line 49) | def add_gesture_recognizer_helper(recognizer, enableInteraction, proc)
FILE: motion/util/constants.rb
type BubbleWrap (line 2) | module BubbleWrap
type Constants (line 3) | module Constants
function register (line 12) | def register(*ui_constants)
function get (line 26) | def get(base, *values)
FILE: motion/util/deprecated.rb
type BubbleWrap (line 1) | module BubbleWrap
type Deprecated (line 2) | module Deprecated
class DeprecatedError (line 4) | class DeprecatedError < StandardError; end
function deprecated (line 6) | def deprecated(method_sym, version)
function included (line 38) | def self.included(base)
FILE: samples/alert/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)
FILE: samples/alert/app/controllers/alert_view_controller.rb
class AlertViewController (line 1) | class AlertViewController < UIViewController
method init (line 6) | def init
method viewDidLoad (line 20) | def viewDidLoad
method build_text_view (line 34) | def build_text_view
method build_button (line 41) | def build_button(title)
method built_alert (line 51) | def built_alert(method)
method build_callback (line 63) | def build_callback(name, method)
FILE: samples/camera/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)
FILE: samples/camera/app/controllers/camera_controller.rb
class CameraController (line 1) | class CameraController < UIViewController
method init (line 4) | def init
method viewDidLoad (line 10) | def viewDidLoad
method build_button (line 18) | def build_button(title, camera_method)
method build_image_view (line 40) | def build_image_view(image)
FILE: samples/gesture/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method application (line 4) | def application(application, didFinishLaunchingWithOptions:launchOptions)
method setup_window (line 10) | def setup_window
FILE: samples/gesture/app/controllers/drawing_view_controller.rb
class DrawingViewController (line 1) | class DrawingViewController < UIViewController
method loadView (line 4) | def loadView
FILE: samples/gesture/app/helpers/drawing_helper.rb
type DrawingHelper (line 1) | module DrawingHelper
FILE: samples/gesture/app/views/drawing/gesture_view.rb
class GestureView (line 1) | class GestureView < UIView
method initWithCoder (line 4) | def initWithCoder(coder)
method initWithFrame (line 10) | def initWithFrame(coder)
method gestureRecognizer (line 19) | def gestureRecognizer(recognizer, shouldRecognizeSimultaneouslyWithGes...
method setup (line 35) | def setup
method setup_gesture (line 42) | def setup_gesture
method reset_transformation (line 85) | def reset_transformation
FILE: samples/gesture/app/views/drawing/rect_view.rb
class RectView (line 1) | class RectView < GestureView
method drawRect (line 2) | def drawRect(rect)
FILE: samples/location/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)
FILE: samples/location/app/controllers/places_list_controller.rb
class PlacesListController (line 1) | class PlacesListController < UITableViewController
method viewDidLoad (line 4) | def viewDidLoad
method viewWillAppear (line 10) | def viewWillAppear(animated)
method tableView (line 14) | def tableView(tableView, numberOfRowsInSection:section)
method reloadData (line 18) | def reloadData
method tableView (line 23) | def tableView(tableView, cellForRowAtIndexPath:indexPath)
FILE: samples/location/app/models/places.rb
class Places (line 1) | class Places
method load (line 5) | def self.load(places_list_controller)
FILE: samples/media/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)
FILE: samples/media/app/controllers/play_controller.rb
class PlayController (line 1) | class PlayController < UIViewController
method init (line 4) | def init
method viewDidLoad (line 10) | def viewDidLoad
method build_button (line 18) | def build_button(title, callback)
method local_file (line 32) | def local_file
method tapped_modal (line 36) | def tapped_modal
method tapped_frame (line 40) | def tapped_frame
FILE: samples/osx/app/app_delegate.rb
class AppDelegate (line 1) | class AppDelegate
method applicationDidFinishLaunching (line 2) | def applicationDidFinishLaunching(notification)
method buildWindow (line 7) | def buildWindow
method fetch_ip (line 34) | def fetch_ip
method make_button (line 43) | def make_button(title)
method make_label (line 52) | def make_label(text)
method add_constraint (line 64) | def add_constraint(ascii, params = {})
FILE: samples/osx/app/menu.rb
class AppDelegate (line 1) | class AppDelegate
method buildMenu (line 2) | def buildMenu
method addMenu (line 95) | def addMenu(title, &b)
method createMenu (line 101) | def createMenu(title, &b)
FILE: spec/lib/bubble-wrap/ext/motion_project_app_spec.rb
function setup (line 9) | def self.setup; end
function configs (line 10) | def self.configs
FILE: spec/lib/bubble-wrap/ext/motion_project_config_spec.rb
function initialize (line 9) | def initialize
function files_dependencies (line 14) | def files_dependencies
FILE: spec/lib/motion_stub.rb
type Motion (line 2) | module Motion
type Project (line 3) | module Project
class App (line 4) | class App
method setup (line 5) | def self.setup
class Config (line 9) | class Config
method files_dependencies (line 10) | def files_dependencies
FILE: spec/motion/core/app_spec.rb
class DelayedRunAfterTest (line 70) | class DelayedRunAfterTest; attr_accessor :test_value end
function url (line 91) | def application.url; @url end
function openURL (line 92) | def application.openURL(url); @url = url end
FILE: spec/motion/core/device/ios/camera_spec.rb
function camera_picker (line 1) | def camera_picker
function example_info (line 5) | def example_info
function presentViewController (line 15) | def presentViewController(*args)
function isCameraDeviceAvailable (line 25) | def self.isCameraDeviceAvailable(c)
function isFlashAvailableForCameraDevice (line 29) | def self.isFlashAvailableForCameraDevice(c)
class FakePickerClass (line 58) | class FakePickerClass
method isCameraDeviceAvailable (line 59) | def self.isCameraDeviceAvailable(c)
method isSourceTypeAvailable (line 63) | def self.isSourceTypeAvailable(c)
method availableMediaTypesForSourceType (line 67) | def self.availableMediaTypesForSourceType(c)
method dismissViewControllerAnimated (line 71) | def dismissViewControllerAnimated(*args)
method method_missing (line 75) | def self.method_missing(*args)
FILE: spec/motion/core/device/ios/camera_wrapper_spec.rb
function isCameraDeviceAvailable (line 11) | def isCameraDeviceAvailable(c)
function isSourceTypeAvailable (line 14) | def isSourceTypeAvailable(c)
function isCameraDeviceAvailable (line 42) | def isCameraDeviceAvailable(c)
function isSourceTypeAvailable (line 45) | def isSourceTypeAvailable(c)
function isCameraDeviceAvailable (line 73) | def isCameraDeviceAvailable(c)
function isSourceTypeAvailable (line 76) | def isSourceTypeAvailable(c)
FILE: spec/motion/core/device/ios/screen_spec.rb
function respondsToSelector (line 6) | def o.respondsToSelector(selector)
function scale (line 10) | def o.scale
function method_missing (line 13) | def o.method_missing(*args)
function respondsToSelector (line 29) | def o.respondsToSelector(selector)
function scale (line 33) | def o.scale
function method_missing (line 36) | def o.method_missing(*args)
FILE: spec/motion/core/device/osx/screen_spec.rb
function respondsToSelector (line 6) | def o.respondsToSelector(selector)
function backingScaleFactor (line 10) | def o.backingScaleFactor
function method_missing (line 13) | def o.method_missing(*args)
FILE: spec/motion/core/ios/app_spec.rb
class DelayedRunAfterTest (line 181) | class DelayedRunAfterTest; attr_accessor :test_value end
function url (line 198) | def application.url; @url end
function canOpenURL (line 199) | def application.canOpenURL(url); @url = url; super; end
FILE: spec/motion/core/kvo_spec.rb
class KvoExample (line 3) | class KvoExample
method initialize (line 10) | def initialize
method get_text (line 21) | def get_text
method set_text (line 25) | def set_text(text)
method observe_label (line 29) | def observe_label(&block)
method observe_label! (line 33) | def observe_label!(&block)
method observe_collection (line 37) | def observe_collection(&block)
method unobserve_label (line 41) | def unobserve_label
method unobserve_label! (line 45) | def unobserve_label!
method text_method_name (line 49) | def text_method_name
method text_class (line 53) | def text_class
method update_collection (line 57) | def update_collection
FILE: spec/motion/core/persistence_spec.rb
function synchronize (line 28) | def storage.synchronize; @sync_was_called = true; end
function synchronize (line 48) | def storage.synchronize; @sync_was_called = true; end
function synchronize (line 99) | def storage.synchronize; @sync_was_called = true; end
FILE: spec/motion/location/location_spec.rb
class BWCLHeading (line 10) | class BWCLHeading
class CLLocationManager (line 14) | class CLLocationManager
method enable (line 15) | def self.enable(enable)
method authorize (line 19) | def self.authorize(authorize)
method locationServicesEnabled (line 23) | def self.locationServicesEnabled
method authorizationStatus (line 28) | def self.authorizationStatus
method startUpdatingLocation (line 33) | def startUpdatingLocation
method stopUpdatingLocation (line 37) | def stopUpdatingLocation
method startUpdatingHeading (line 41) | def startUpdatingHeading
method stopUpdatingHeading (line 45) | def stopUpdatingHeading
method startMonitoringSignificantLocationChanges (line 49) | def startMonitoringSignificantLocationChanges
method stopMonitoringSignificantLocationChanges (line 53) | def stopMonitoringSignificantLocationChanges
function location_manager (line 58) | def location_manager
function reset (line 62) | def reset
FILE: spec/motion/mail/mail_spec.rb
class MailViewController (line 2) | class MailViewController < UIViewController
method presentViewController (line 5) | def presentViewController(modal, animated: animated, completion: compl...
class MFMailComposeViewController (line 14) | class MFMailComposeViewController
method setToRecipients (line 17) | def setToRecipients(r)
method setCcRecipients (line 21) | def setCcRecipients(r)
method setBccRecipients (line 25) | def setBccRecipients(r)
method setSubject (line 29) | def setSubject(r)
method setMessageBody (line 33) | def setMessageBody(message, isHTML: html)
FILE: spec/motion/reactor/eventable_spec.rb
function bar (line 20) | def bar; end
function bar (line 43) | def bar; end
function bar (line 52) | def bar; end
function bar (line 105) | def bar(r)
function bar (line 124) | def bar(r)
function bar (line 142) | def bar(r); @proxy.proof += r; end
function baz (line 143) | def baz(r); @proxy.proof += r; end
class TestUIViewControllerWithEventable (line 151) | class TestUIViewControllerWithEventable
method test_on (line 153) | def test_on
method bar (line 159) | def bar
method dealloc (line 162) | def dealloc
FILE: spec/motion/sms/sms_spec.rb
class MessageViewController (line 2) | class MessageViewController < UIViewController
method presentModalViewController (line 5) | def presentModalViewController(modal, animated: animated)
class MFMessageComposeViewController (line 14) | class MFMessageComposeViewController
method init (line 19) | def init
FILE: spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb
function presentViewController (line 5) | def presentViewController(*args)
FILE: spec/motion/ui/ui_bar_button_item_spec.rb
class NavigationItemContainingBarButtonItem (line 2) | class NavigationItemContainingBarButtonItem < UINavigationItem
method init_with_styled (line 3) | def init_with_styled
method tag= (line 12) | def tag=(value)
method init_with_system (line 16) | def init_with_system
method dealloc (line 25) | def dealloc
FILE: spec/motion/ui/ui_control_wrapper_spec.rb
class ControlSuperView (line 42) | class ControlSuperView < UIView
method initWithFrame (line 43) | def initWithFrame(frame)
method dealloc (line 53) | def dealloc
FILE: spec/motion/ui/ui_view_wrapper_spec.rb
class ViewSuperView (line 67) | class ViewSuperView < UIView
method initWithFrame (line 68) | def initWithFrame(frame)
method dealloc (line 78) | def dealloc
FILE: spec/motion/util/deprecated_spec.rb
type ModuleExample (line 1) | module ModuleExample
function a_method (line 6) | def a_method
class ClassExample (line 13) | class ClassExample
method a_method (line 16) | def a_method
type BubbleWrap (line 22) | module BubbleWrap
function set_version (line 23) | def self.set_version(version)
Condensed preview — 186 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (599K chars).
[
{
"path": ".gitignore",
"chars": 50,
"preview": ".rake_tasks~\npkg/*\nbuild/\n.DS_Store\n.repl_history\n"
},
{
"path": ".travis.yml",
"chars": 281,
"preview": "language: objective-c\nosx_image: xcode8\nbefore_install:\n - sudo motion update\n - motion repo\nscript:\n - bundle exec r"
},
{
"path": ".yardopts",
"chars": 26,
"preview": "lib/**/*.rb\nmotion/**/*.rb"
},
{
"path": "CHANGELOG.md",
"chars": 12943,
"preview": "## Unreleased\n\n[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.7...master)\n\n## 1.9.7\n\n["
},
{
"path": "GEM.md",
"chars": 2510,
"preview": "# Creating a RubyMotion gem with BubbleWrap\n\nLet's say we want to develop a simple library gem that lists the\npeople in "
},
{
"path": "GETTING_STARTED.md",
"chars": 3320,
"preview": "# Getting Started with BubbleWrap\n\nA short guide to starting a RubyMotion application using the bubble wrappers.\n\n## A q"
},
{
"path": "Gemfile",
"chars": 96,
"preview": "source 'https://rubygems.org'\n\n# Specify your gem's dependencies in bubble-wrap.gemspec\ngemspec\n"
},
{
"path": "HACKING.md",
"chars": 3694,
"preview": "# Hacking on BubbleWrap\n\n## A library in two parts\n\nRubyMotion forces a certain background-radiation of schizophrenia\ndu"
},
{
"path": "LICENSE",
"chars": 1207,
"preview": "LICENCE\n\nMIT: http://mattaimonetti.mit-license.org\n\n------------------------------------------------\n\nThe MIT License (M"
},
{
"path": "README.md",
"chars": 35837,
"preview": "# BubbleWrap for RubyMotion\n\nA collection of (tested) helpers and wrappers used to wrap Cocoa Touch and AppKit code and "
},
{
"path": "Rakefile",
"chars": 1347,
"preview": "$:.unshift(\"/Library/RubyMotion/lib\")\n$:.unshift(\"~/.rubymotion/rubymotion-templates\")\nrequire 'motion/project/template/"
},
{
"path": "bubble-wrap.gemspec",
"chars": 1460,
"preview": "# -*- encoding: utf-8 -*-\nrequire File.expand_path('../lib/bubble-wrap/version', __FILE__)\n\nGem::Specification.new do |g"
},
{
"path": "lib/bubble-wrap/all.rb",
"chars": 252,
"preview": "require File.expand_path('../loader', __FILE__)\n[\n 'core',\n 'font',\n 'location',\n 'mail',\n 'media',\n 'motion',\n '"
},
{
"path": "lib/bubble-wrap/camera.rb",
"chars": 652,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"camera\") do\n BubbleWrap.require('motion/util/constants.rb')\n Bub"
},
{
"path": "lib/bubble-wrap/core.rb",
"chars": 628,
"preview": "require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)\nrequire 'bubble-wrap/loader'\n\nBubbleWrap.require('mot"
},
{
"path": "lib/bubble-wrap/ext/motion_project_app.rb",
"chars": 1217,
"preview": "module BubbleWrap\n module Ext\n module BuildTask\n\n def self.extended(base)\n base.instance_eval do\n "
},
{
"path": "lib/bubble-wrap/ext.rb",
"chars": 45,
"preview": "require 'bubble-wrap/ext/motion_project_app'\n"
},
{
"path": "lib/bubble-wrap/font.rb",
"chars": 111,
"preview": "require 'bubble-wrap/loader'\nBubbleWrap.require_ios(\"font\") do\n BubbleWrap.require('motion/font/font.rb')\nend\n"
},
{
"path": "lib/bubble-wrap/loader.rb",
"chars": 2047,
"preview": "unless defined?(Motion::Project::Config)\n raise 'This file must be required within a RubyMotion project Rakefile.'\nend\n"
},
{
"path": "lib/bubble-wrap/location.rb",
"chars": 453,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"location\") do\n BubbleWrap.require('motion/util/constants.rb')\n B"
},
{
"path": "lib/bubble-wrap/mail.rb",
"chars": 292,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"mail\") do\n BubbleWrap.require('motion/core/app.rb')\n BubbleWrap."
},
{
"path": "lib/bubble-wrap/media.rb",
"chars": 577,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"media\") do\n BubbleWrap.require('motion/core/app.rb')\n BubbleWrap"
},
{
"path": "lib/bubble-wrap/motion.rb",
"chars": 680,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios('motion') do\n BubbleWrap.require('motion/util/constants.rb')\n Bub"
},
{
"path": "lib/bubble-wrap/network-indicator.rb",
"chars": 181,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"network-indicator\") do\n BubbleWrap.require('motion/core/app.rb')\n"
},
{
"path": "lib/bubble-wrap/reactor.rb",
"chars": 532,
"preview": "require 'bubble-wrap/loader'\n\nBW.require 'motion/reactor.rb'\nBW.require 'motion/reactor/**/*.rb' do\n file('motion/react"
},
{
"path": "lib/bubble-wrap/requirement/path_manipulation.rb",
"chars": 1099,
"preview": "module BubbleWrap\n class Requirement\n module PathManipulation\n\n def convert_caller_to_root_path(path)\n p"
},
{
"path": "lib/bubble-wrap/requirement.rb",
"chars": 2247,
"preview": "require 'bubble-wrap/requirement/path_manipulation'\n\nmodule BubbleWrap\n class Requirement\n extend PathManipulation\n "
},
{
"path": "lib/bubble-wrap/rss_parser.rb",
"chars": 72,
"preview": "require 'bubble-wrap/loader'\nBubbleWrap.require('motion/rss_parser.rb')\n"
},
{
"path": "lib/bubble-wrap/sms.rb",
"chars": 285,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"sms\") do\n BubbleWrap.require('motion/core/app.rb')\n BubbleWrap.r"
},
{
"path": "lib/bubble-wrap/test.rb",
"chars": 335,
"preview": "require 'webstub'\nrequire 'bubble-wrap/loader'\nBW.require 'motion/util/*.rb'\nBW.require 'motion/test_suite_delegate.rb'\n"
},
{
"path": "lib/bubble-wrap/ui.rb",
"chars": 339,
"preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"ui\") do\n BubbleWrap.require('motion/util/constants.rb')\n BubbleW"
},
{
"path": "lib/bubble-wrap/version.rb",
"chars": 109,
"preview": "module BubbleWrap\n VERSION = '1.9.7' unless defined?(BubbleWrap::VERSION)\n MIN_MOTION_VERSION = '3.12'\nend\n"
},
{
"path": "lib/bubble-wrap.rb",
"chars": 125,
"preview": "require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)\nrequire File.expand_path('../bubble-wrap/core', __FIL"
},
{
"path": "motion/core/app.rb",
"chars": 2547,
"preview": "# Provides a module to store global states\n#\nmodule BubbleWrap\n module App\n include BubbleWrap::Deprecated\n\n modu"
},
{
"path": "motion/core/device/ios/camera.rb",
"chars": 9083,
"preview": "# Provides a nice DSL for interacting with the standard\n# UIImagePickerController\n#\nmodule BubbleWrap\n module Device\n "
},
{
"path": "motion/core/device/ios/camera_wrapper.rb",
"chars": 1835,
"preview": "module BubbleWrap\n module Device\n module CameraWrapper\n\n module_function\n\n # The front-facing camera used "
},
{
"path": "motion/core/device/ios/screen.rb",
"chars": 3813,
"preview": "module BubbleWrap\n module Device\n module Screen\n\n module_function\n\n # Certifies that the device running th"
},
{
"path": "motion/core/device/osx/screen.rb",
"chars": 487,
"preview": "module BubbleWrap\n module Device\n module Screen\n\n module_function\n\n # Certifies that the device running th"
},
{
"path": "motion/core/device/screen.rb",
"chars": 71,
"preview": "module BubbleWrap\n module Device\n module Screen\n\n end\n end\nend\n"
},
{
"path": "motion/core/device.rb",
"chars": 328,
"preview": "module BubbleWrap\n module Device\n module_function\n\n # Shameless shorthand for accessing BubbleWrap::Screen\n de"
},
{
"path": "motion/core/ios/app.rb",
"chars": 2754,
"preview": "module BubbleWrap\n module App\n module_function\n\n # Opens an url (string or instance of `NSURL`)\n # in the devi"
},
{
"path": "motion/core/ios/device.rb",
"chars": 3402,
"preview": "module BubbleWrap\n module Device\n module_function\n\n # Verifies that the device running the app is an iPhone.\n "
},
{
"path": "motion/core/ios/ns_index_path.rb",
"chars": 202,
"preview": "module NSIndexPathWrap\n\n def +(aNumber)\n self.class.indexPathForRow(row+aNumber, inSection:section)\n end\n\n def -(a"
},
{
"path": "motion/core/json.rb",
"chars": 1222,
"preview": "module BubbleWrap\n\n # Handles JSON encoding and decoding in a similar way Ruby 1.9 does.\n module JSON\n\n class Parse"
},
{
"path": "motion/core/kvo.rb",
"chars": 5068,
"preview": "# Usage example:\n#\n# class ExampleViewController < UIViewController\n# include BubbleWrap::KVO\n#\n# def viewDidLoa"
},
{
"path": "motion/core/ns_index_path.rb",
"chars": 566,
"preview": "module NSIndexPathWrap\n\n # Gives access to an index at a given position.\n # @param [Integer] position to use to fetch "
},
{
"path": "motion/core/ns_notification_center.rb",
"chars": 582,
"preview": "class NSNotificationCenter\n def observers\n @observers ||= []\n end\n\n def observe(name, object=nil, &proc)\n proc."
},
{
"path": "motion/core/ns_url_request.rb",
"chars": 468,
"preview": "class NSURLRequest\n\n # Provides a to_s method so we can use inspect in instances and get\n # valuable information.\n de"
},
{
"path": "motion/core/ns_user_defaults.rb",
"chars": 477,
"preview": "# Reopens the NSUserDefaults class to add Array like accessors\n# @see https://developer.apple.com/library/ios/#documenta"
},
{
"path": "motion/core/osx/app.rb",
"chars": 523,
"preview": "module BubbleWrap\n module App\n module_function\n\n # Opens an url (string or instance of `NSURL`)\n # in the defa"
},
{
"path": "motion/core/osx/device.rb",
"chars": 65,
"preview": "module BubbleWrap\n module Device\n module_function\n\n end\nend\n"
},
{
"path": "motion/core/persistence.rb",
"chars": 1465,
"preview": "# Persistence module built on top of NSUserDefaults\nmodule BubbleWrap\n module Persistence\n module_function\n\n def "
},
{
"path": "motion/core/pollute.rb",
"chars": 98,
"preview": "[\n [NSIndexPath, NSIndexPathWrap]\n].each do |base, wrapper|\n base.send(:include, wrapper)\nend\n"
},
{
"path": "motion/core/string.rb",
"chars": 3082,
"preview": "module BubbleWrap\n # This module contains simplified version of the `camelize` and\n # `underscore` methods from Active"
},
{
"path": "motion/core/time.rb",
"chars": 1300,
"preview": "class Time\n\n def self.iso8601(time)\n if time.include?(\".\")\n # Fractional Seconds\n if time.include?('Z')\n "
},
{
"path": "motion/core.rb",
"chars": 733,
"preview": "module BubbleWrap\n module_function\n\n # @return [UIcolor]\n def rgb_color(r,g,b)\n rgba_color(r,g,b,1)\n end\n\n # @re"
},
{
"path": "motion/font/font.rb",
"chars": 2129,
"preview": "module BubbleWrap\n module Font\n module_function\n\n def bold(size = nil)\n Font.new(:bold, size)\n end\n\n d"
},
{
"path": "motion/ios/8/location_constants.rb",
"chars": 746,
"preview": "module BW\n # New additions to CLAuthorizationStatus in ios8\n # see: https://developer.apple.com/library/prerelease/ios"
},
{
"path": "motion/location/location.rb",
"chars": 8990,
"preview": "# Provides a nice DSL for interacting with the standard\n# CLLocationManager\n#\nmodule BubbleWrap\n module CLLocationWrap\n"
},
{
"path": "motion/location/pollute.rb",
"chars": 109,
"preview": "[\n [CLLocation, BubbleWrap::CLLocationWrap],\n].each do |base, wrapper|\n base.send(:include, wrapper)\nend\n"
},
{
"path": "motion/mail/mail.rb",
"chars": 2778,
"preview": "module BubbleWrap\n module Mail\n\n module_function\n\n # Base method to create your in-app mail\n # ---------------"
},
{
"path": "motion/mail/result.rb",
"chars": 532,
"preview": "module BubbleWrap\n module Mail\n class Result\n attr_accessor :result, :error\n\n def initialize(result, error"
},
{
"path": "motion/media/media.rb",
"chars": 319,
"preview": "module BubbleWrap\n module Media\n module_function\n\n def play_modal(*args, &block)\n Media::Player.new.retain.s"
},
{
"path": "motion/media/player.rb",
"chars": 6558,
"preview": "module BubbleWrap\n module Media\n module Error\n class InvalidPlayerType < StandardError; end\n class NilPlay"
},
{
"path": "motion/motion/accelerometer.rb",
"chars": 1220,
"preview": "module BubbleWrap\n module Motion\n class Accelerometer < GenericMotionInterface\n\n def start(options={}, &handler"
},
{
"path": "motion/motion/device_motion.rb",
"chars": 4094,
"preview": "module BubbleWrap\n module Motion\n class DeviceMotion < GenericMotionInterface\n\n def start(options={}, &handler)"
},
{
"path": "motion/motion/gyroscope.rb",
"chars": 1149,
"preview": "module BubbleWrap\n module Motion\n class Gyroscope < GenericMotionInterface\n\n def start(options={}, &handler)\n "
},
{
"path": "motion/motion/magnetometer.rb",
"chars": 1209,
"preview": "module BubbleWrap\n module Motion\n class Magnetometer < GenericMotionInterface\n\n def start(options={}, &handler)"
},
{
"path": "motion/motion/motion.rb",
"chars": 3305,
"preview": "# Provides a nice DSL for interacting with the standard CMMotionManager from\n# CoreMotion\nmodule BubbleWrap\n # These mo"
},
{
"path": "motion/network-indicator/network-indicator.rb",
"chars": 1626,
"preview": "module BubbleWrap\n module NetworkIndicator\n DELAY = 0.2\n\n module_function\n\n def counter\n @counter ||= 0\n "
},
{
"path": "motion/reactor/default_deferrable.rb",
"chars": 244,
"preview": "module BubbleWrap\n module Reactor\n # A basic class which includes Deferrable when all\n # you need is a deferrable"
},
{
"path": "motion/reactor/deferrable.rb",
"chars": 5547,
"preview": "module BubbleWrap\n module Reactor\n # Provides a mixin for deferrable jobs.\n module Deferrable\n\n # def self.i"
},
{
"path": "motion/reactor/dependent_deferrable.rb",
"chars": 987,
"preview": "module BubbleWrap\n module Reactor\n class DependentDeferrable < DefaultDeferrable\n # args are Deferrable(s) whic"
},
{
"path": "motion/reactor/eventable.rb",
"chars": 1194,
"preview": "module BubbleWrap\n module Reactor\n # A simple mixin that adds events to your object.\n module Eventable\n\n # W"
},
{
"path": "motion/reactor/future.rb",
"chars": 471,
"preview": "module BubbleWrap\n module Reactor\n module Future\n\n # A future is a sugaring of a typical deferrable usage.\n "
},
{
"path": "motion/reactor/periodic_timer.rb",
"chars": 1059,
"preview": "module BubbleWrap\n module Reactor\n # Creates a repeating timer.\n class PeriodicTimer\n include Eventable\n\n "
},
{
"path": "motion/reactor/queue.rb",
"chars": 1510,
"preview": "module BubbleWrap\n module Reactor\n # A GCD scheduled, linear queue.\n #\n # This class provides a simple “Queue”"
},
{
"path": "motion/reactor/thread_aware_deferrable.rb",
"chars": 818,
"preview": "module BubbleWrap\n module Reactor\n class ThreadAwareDeferrable < DefaultDeferrable\n include ::BubbleWrap::React"
},
{
"path": "motion/reactor/timer.rb",
"chars": 663,
"preview": "module BubbleWrap\n module Reactor\n # Creates a one-time timer.\n class Timer\n include Eventable\n\n # Crea"
},
{
"path": "motion/reactor.rb",
"chars": 3631,
"preview": "module BubbleWrap\n module Reactor\n module_function\n\n # Always returns true - for compatibility with EM\n def re"
},
{
"path": "motion/rss_parser.rb",
"chars": 4526,
"preview": "# Asynchronous and non blocking RSS Parser based on NSXMLParser.\n# The parser will progressively parse a feed and yield "
},
{
"path": "motion/shortcut.rb",
"chars": 614,
"preview": "# Make sure that\n# Both BubbleWrap and BW are defined. This file is depended on by everything\n# else in BubbleWrap, so "
},
{
"path": "motion/sms/result.rb",
"chars": 402,
"preview": "module BubbleWrap\n module SMS\n class Result\n attr_accessor :result\n\n def initialize(result)\n self.r"
},
{
"path": "motion/sms/sms.rb",
"chars": 1835,
"preview": "module BubbleWrap\n module SMS\n\n module_function\n\n # Base method to create your in-app mail\n # ----------------"
},
{
"path": "motion/test_suite_delegate.rb",
"chars": 2277,
"preview": "class TestSuiteDelegate\n attr_accessor :window\n\n def application(application, didFinishLaunchingWithOptions:launchOpti"
},
{
"path": "motion/ui/pollute.rb",
"chars": 284,
"preview": "# Please, no more! It'll hurt BubbleWrap's compatibility with other libraries.\n[\n [UIControl, BW::UIControlWra"
},
{
"path": "motion/ui/ui_activity_view_controller_wrapper.rb",
"chars": 1666,
"preview": "module BW\n class UIActivityViewController < ::UIActivityViewController\n class << self\n def new(options = {}, pr"
},
{
"path": "motion/ui/ui_alert_view.rb",
"chars": 6044,
"preview": "module BW\n class UIAlertView < ::UIAlertView\n @callbacks = [\n :will_present,\n :did_present,\n :on_syst"
},
{
"path": "motion/ui/ui_bar_button_item.rb",
"chars": 3284,
"preview": "module BW\n class UIBarButtonItem < ::UIBarButtonItem\n class << self\n def styled(type, *objects, &block)\n "
},
{
"path": "motion/ui/ui_control_wrapper.rb",
"chars": 1201,
"preview": "module BubbleWrap\n module UIControlWrapper\n def when(events, options = {}, &block)\n events = BW::Constants.get("
},
{
"path": "motion/ui/ui_view_controller_wrapper.rb",
"chars": 449,
"preview": "module BubbleWrap\n module UIViewControllerWrapper\n # Short hand to get the content frame\n #\n # Return content "
},
{
"path": "motion/ui/ui_view_wrapper.rb",
"chars": 2421,
"preview": "module BubbleWrap\n module UIViewWrapper\n def when_tapped(enableInteraction=true, &proc)\n add_gesture_recognizer"
},
{
"path": "motion/util/constants.rb",
"chars": 1692,
"preview": "# Stupid hack because the RubyMotion dependency detection has a bug.\nmodule BubbleWrap\n module Constants\n module_fun"
},
{
"path": "motion/util/deprecated.rb",
"chars": 1344,
"preview": "module BubbleWrap\n module Deprecated\n\n class DeprecatedError < StandardError; end\n\n def deprecated(method_sym, ve"
},
{
"path": "resources/Localizable.strings",
"chars": 24,
"preview": "\"real_key\" = \"Real Key\";"
},
{
"path": "resources/atom.xml",
"chars": 161863,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<?xml-stylesheet type=\"text/xsl\" media=\"screen\" href=\"/~d/styles/rss2enclosuresf"
},
{
"path": "samples/alert/.gitignore",
"chars": 169,
"preview": ".repl_history\nbuild\ntags\napp/pixate_code.rb\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n.DS_Store\nnbproject"
},
{
"path": "samples/alert/Gemfile",
"chars": 79,
"preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
},
{
"path": "samples/alert/Rakefile",
"chars": 252,
"preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bundler'\nBu"
},
{
"path": "samples/alert/app/app_delegate.rb",
"chars": 278,
"preview": "class AppDelegate\n def application(application, didFinishLaunchingWithOptions:launchOptions)\n @window = UIWindow.all"
},
{
"path": "samples/alert/app/controllers/alert_view_controller.rb",
"chars": 2073,
"preview": "class AlertViewController < UIViewController\n attr_reader :text_view\n attr_reader :buttons\n attr_reader :alerts\n\n de"
},
{
"path": "samples/alert/spec/main_spec.rb",
"chars": 165,
"preview": "describe \"Application 'alert'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one window\" do"
},
{
"path": "samples/camera/Gemfile",
"chars": 79,
"preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
},
{
"path": "samples/camera/README.md",
"chars": 67,
"preview": "## Camera Demo\n\nA bubble-wrap demo to show how to use camera API.\n\n"
},
{
"path": "samples/camera/Rakefile",
"chars": 219,
"preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bubble-wrap"
},
{
"path": "samples/camera/app/app_delegate.rb",
"chars": 308,
"preview": "class AppDelegate\n def application(application, didFinishLaunchingWithOptions:launchOptions)\n @window = UIWindow.all"
},
{
"path": "samples/camera/app/controllers/camera_controller.rb",
"chars": 1393,
"preview": "class CameraController < UIViewController\n attr_accessor :buttons\n\n def init\n super.tap do\n @buttons = []\n "
},
{
"path": "samples/camera/spec/main_spec.rb",
"chars": 175,
"preview": "describe \"Application 'google_location'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one "
},
{
"path": "samples/gesture/.gitignore",
"chars": 77,
"preview": ".repl_history\nbuild\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n"
},
{
"path": "samples/gesture/Gemfile",
"chars": 98,
"preview": "source \"https://rubygems.org\"\n\ngem 'rake'\ngem \"bubble-wrap\", :path => \"../../\"\ngem 'motion-dryer'\n"
},
{
"path": "samples/gesture/README.md",
"chars": 198,
"preview": "## Gesture Demo\n\nA bubble-wrap demo to show how to use gesture API.\n\n\nrequire 'motion/project/template/ios'\nrequire 'bundler'\nBu"
},
{
"path": "samples/gesture/app/app_delegate.rb",
"chars": 419,
"preview": "class AppDelegate\n attr_reader :window\n\n def application(application, didFinishLaunchingWithOptions:launchOptions)\n "
},
{
"path": "samples/gesture/app/controllers/drawing_view_controller.rb",
"chars": 392,
"preview": "class DrawingViewController < UIViewController\n attr_reader :drawing_view\n\n def loadView\n screen = UIScreen.mainScr"
},
{
"path": "samples/gesture/app/helpers/drawing_helper.rb",
"chars": 24,
"preview": "module DrawingHelper\nend"
},
{
"path": "samples/gesture/app/views/drawing/gesture_view.rb",
"chars": 2556,
"preview": "class GestureView < UIView\n attr_accessor :rotation, :scale, :translation\n\n def initWithCoder(coder)\n super\n set"
},
{
"path": "samples/gesture/app/views/drawing/rect_view.rb",
"chars": 448,
"preview": "class RectView < GestureView\n def drawRect(rect)\n super(rect)\n\n context = UIGraphicsGetCurrentContext()\n CGCon"
},
{
"path": "samples/gesture/spec/main_spec.rb",
"chars": 167,
"preview": "describe \"Application 'gesture'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one window\" "
},
{
"path": "samples/location/.gitignore",
"chars": 77,
"preview": ".repl_history\nbuild\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n"
},
{
"path": "samples/location/Gemfile",
"chars": 102,
"preview": "source \"https://rubygems.org\"\n\ngem 'rake'\ngem \"bubble-wrap\", :path => \"../../\"\ngem 'bubble-wrap-http'\n"
},
{
"path": "samples/location/README.md",
"chars": 71,
"preview": "## Location Demo\n\nA bubble-wrap demo to show how to use location API.\n\n"
},
{
"path": "samples/location/Rakefile",
"chars": 258,
"preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bubble-wrap"
},
{
"path": "samples/location/app/app_delegate.rb",
"chars": 322,
"preview": "class AppDelegate\n def application(application, didFinishLaunchingWithOptions:launchOptions)\n @window = UIWindow.all"
},
{
"path": "samples/location/app/controllers/places_list_controller.rb",
"chars": 726,
"preview": "class PlacesListController < UITableViewController\n attr_accessor :places_list\n\n def viewDidLoad\n @places_list = []"
},
{
"path": "samples/location/app/models/places.rb",
"chars": 634,
"preview": "class Places\n API_KEY = \"\"\n #See google places documentation at https://developers.google.com/places/documentation/ to"
},
{
"path": "samples/location/spec/main_spec.rb",
"chars": 175,
"preview": "describe \"Application 'google_location'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one "
},
{
"path": "samples/media/.gitignore",
"chars": 169,
"preview": ".repl_history\nbuild\ntags\napp/pixate_code.rb\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n.DS_Store\nnbproject"
},
{
"path": "samples/media/Gemfile",
"chars": 79,
"preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
},
{
"path": "samples/media/Rakefile",
"chars": 271,
"preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\n\n$:.unshift(\"../../l"
},
{
"path": "samples/media/app/app_delegate.rb",
"chars": 306,
"preview": "class AppDelegate\n def application(application, didFinishLaunchingWithOptions:launchOptions)\n @window = UIWindow.all"
},
{
"path": "samples/media/app/controllers/play_controller.rb",
"chars": 1222,
"preview": "class PlayController < UIViewController\n attr_accessor :buttons\n\n def init\n super.tap do\n @buttons = []\n en"
},
{
"path": "samples/media/spec/main_spec.rb",
"chars": 165,
"preview": "describe \"Application 'media'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one window\" do"
},
{
"path": "samples/osx/Gemfile",
"chars": 102,
"preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem 'bubble-wrap', :path => \"../../\"\ngem 'bubble-wrap-http'\n"
},
{
"path": "samples/osx/Rakefile",
"chars": 260,
"preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/osx'\n\nrequire 'bundler'\nB"
},
{
"path": "samples/osx/app/app_delegate.rb",
"chars": 2077,
"preview": "class AppDelegate\n def applicationDidFinishLaunching(notification)\n buildMenu\n buildWindow\n end\n\n def buildWind"
},
{
"path": "samples/osx/app/menu.rb",
"chars": 4953,
"preview": "class AppDelegate\n def buildMenu\n @mainMenu = NSMenu.new\n\n appName = NSBundle.mainBundle.infoDictionary['CFBundle"
},
{
"path": "samples/osx/resources/Credits.rtf",
"chars": 436,
"preview": "{\\rtf0\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\paperw9840\\paperh8400\n\\pard\\tx560\\tx11"
},
{
"path": "samples/osx/spec/main_spec.rb",
"chars": 163,
"preview": "describe \"Application 'osx'\" do\n before do\n @app = UIApplication.sharedApplication\n end\n\n it \"has one window\" do\n "
},
{
"path": "spec/lib/bubble-wrap/ext/motion_project_app_spec.rb",
"chars": 4024,
"preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe Bubb"
},
{
"path": "spec/lib/bubble-wrap/ext/motion_project_config_spec.rb",
"chars": 1254,
"preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe Bubb"
},
{
"path": "spec/lib/bubble-wrap/requirement/path_manipulation_spec.rb",
"chars": 1564,
"preview": "require File.expand_path('../../../../../lib/bubble-wrap/requirement/path_manipulation', __FILE__)\n\ndescribe BubbleWrap:"
},
{
"path": "spec/lib/bubble-wrap/requirement_spec.rb",
"chars": 2154,
"preview": "require File.expand_path('../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe BubbleWrap::Requirement do\n\n be"
},
{
"path": "spec/lib/bubble-wrap_spec.rb",
"chars": 870,
"preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../motion_stub.rb', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe BubbleW"
},
{
"path": "spec/lib/motion_stub.rb",
"chars": 230,
"preview": "# Create a fake Motion class hierarchy for testing.\nmodule Motion\n module Project\n class App\n def self.setup\n "
},
{
"path": "spec/motion/core/app_spec.rb",
"chars": 3216,
"preview": "describe BubbleWrap::App do\n describe '.documents_path' do\n it 'should end in \"/Documents\"' do\n App.documents_p"
},
{
"path": "spec/motion/core/device/ios/camera_spec.rb",
"chars": 4057,
"preview": "def camera_picker\n @camera.instance_variable_get(\"@picker\")\nend\n\ndef example_info\n { UIImagePickerControllerMediaType "
},
{
"path": "spec/motion/core/device/ios/camera_wrapper_spec.rb",
"chars": 2263,
"preview": "describe BubbleWrap::Device::CameraWrapper do\n\n before do\n BW::Device.camera.instance_variable_set(:@front, nil)\n "
},
{
"path": "spec/motion/core/device/ios/device_spec.rb",
"chars": 1778,
"preview": "describe BubbleWrap::Device do\ndescribe \"iOS\" do\n describe 'on iPhone' do\n before do\n @idiom = UIUserInterfaceI"
},
{
"path": "spec/motion/core/device/ios/screen_spec.rb",
"chars": 6750,
"preview": "describe BubbleWrap::Device::Screen do\ndescribe \"iOS\" do\n describe 'on retina enabled screen' do\n before do\n @s"
},
{
"path": "spec/motion/core/device/osx/screen_spec.rb",
"chars": 682,
"preview": "describe BubbleWrap::Device::Screen do\n describe \"OS X\" do\n describe 'on retina enabled screen' do\n before do\n "
},
{
"path": "spec/motion/core/device_spec.rb",
"chars": 319,
"preview": "describe BubbleWrap::Device do\n\n describe '.screen' do\n it 'return BubbleWrap::Screen' do\n BW::Device.screen.sh"
},
{
"path": "spec/motion/core/ios/app_spec.rb",
"chars": 6176,
"preview": "describe BubbleWrap::App do\n describe \"iOS\" do\n describe '.alert' do\n after do\n @alert.dismissWithClicke"
},
{
"path": "spec/motion/core/ios/ns_index_path_spec.rb",
"chars": 414,
"preview": "describe \"NSIndexPathWrap\" do\n\n before do\n @index = NSIndexPath.indexPathForRow(0, inSection:3)\n end\n\n it \"shoul"
},
{
"path": "spec/motion/core/json_spec.rb",
"chars": 4234,
"preview": "describe \"JSON\" do\n\n before do\n @json_string = <<-EOS\n {\n \"public_gists\": 248,\n \"type\": \"User\",\n \"blog\": \"http"
},
{
"path": "spec/motion/core/kvo_spec.rb",
"chars": 9087,
"preview": "describe BubbleWrap::KVO do\n\n class KvoExample\n include BubbleWrap::KVO\n\n attr_accessor :age\n attr_accessor :l"
},
{
"path": "spec/motion/core/ns_index_path_spec.rb",
"chars": 496,
"preview": "describe \"NSIndexPathWrap\" do\n\n before do\n if App.osx?\n @index = NSIndexPath.indexPathWithIndex(3)\n else\n "
},
{
"path": "spec/motion/core/ns_notification_center_spec.rb",
"chars": 1007,
"preview": "describe \"NSNotificationCenter\" do\n SampleNotification = \"SampleNotification\"\n\n after do\n @observer = nil\n end\n\n "
},
{
"path": "spec/motion/core/osx/app_spec.rb",
"chars": 380,
"preview": "describe BubbleWrap::App do\n describe \"OS X\" do\n\n describe '.delegate' do\n it 'returns a TestSuiteDelegate' do\n"
},
{
"path": "spec/motion/core/persistence_spec.rb",
"chars": 3091,
"preview": "describe BubbleWrap::Persistence do\n\n describe '.app_key' do\n\n it \"caches the @app_key\" do\n BubbleWrap::Persist"
},
{
"path": "spec/motion/core/string_spec.rb",
"chars": 6747,
"preview": "describe BubbleWrap::String do\n\n describe ::NSString do\n it 'should include BubbleWrap::String' do\n ::NSString."
},
{
"path": "spec/motion/core/time_spec.rb",
"chars": 4047,
"preview": "describe \"Time\" do\n\n describe \"Caching the date formatter\" do\n\n it \"should reuse the created formatter\" do\n 100"
},
{
"path": "spec/motion/core_spec.rb",
"chars": 1849,
"preview": "describe 'BubbleWrap' do\n\n\n describe \"debug flag\" do\n\n after do\n BubbleWrap.debug = false\n end\n\n it \"can"
},
{
"path": "spec/motion/font/font_spec.rb",
"chars": 1924,
"preview": "describe BubbleWrap::Font do\n [[:system, \"systemFontOfSize:\"], [:bold, \"boldSystemFontOfSize:\"], [:italic, \"italicSyste"
},
{
"path": "spec/motion/location/location_spec.rb",
"chars": 9441,
"preview": "describe \"CLLocationWrap\" do\n it \"should have correct values for lat and lng\" do\n coordinate = CLLocation.alloc.init"
},
{
"path": "spec/motion/mail/mail_spec.rb",
"chars": 4258,
"preview": "# Mocking the presentViewController\nclass MailViewController < UIViewController\n attr_accessor :expectation\n\n def pres"
},
{
"path": "spec/motion/mail/result_spec.rb",
"chars": 1331,
"preview": "describe BW::Mail::Result do\n\n before do\n @subject = BW::Mail::Result.new(MFMailComposeResultCancelled, nil)\n end\n\n"
},
{
"path": "spec/motion/media/player_spec.rb",
"chars": 2658,
"preview": "describe BubbleWrap::Media::Player do\n describe \".play\" do\n before do\n @player = BW::Media::Player.new\n @l"
},
{
"path": "spec/motion/motion/core_motion_spec.rb",
"chars": 7497,
"preview": "describe BubbleWrap::Motion do\n\n it 'should be able to instantiate all the things' do\n mgr = CMMotionManager.alloc.i"
},
{
"path": "spec/motion/network-indicator/network_indicator_spec.rb",
"chars": 3684,
"preview": "describe BW::NetworkIndicator do\n\n before do\n BW::NetworkIndicator.reset!\n end\n\n after do\n BW::NetworkIndicator"
},
{
"path": "spec/motion/reactor/deferrable_spec.rb",
"chars": 2129,
"preview": "describe BubbleWrap::Reactor::Deferrable do\n\n before do\n @subject = Class.new do\n include BubbleWrap::Reactor::"
},
{
"path": "spec/motion/reactor/dependent_deferrable_spec.rb",
"chars": 2433,
"preview": "describe BubbleWrap::Reactor::DependentDeferrable do\n\n before do\n @subject = Class.new do\n include BubbleWrap::"
},
{
"path": "spec/motion/reactor/eventable_spec.rb",
"chars": 5643,
"preview": "describe BubbleWrap::Reactor::Eventable do\n before do\n @subject = Class.new do\n include BubbleWrap::Reactor::Ev"
},
{
"path": "spec/motion/reactor/thread_aware_deferrable_spec.rb",
"chars": 2199,
"preview": "shared :queue_caching_deferrable_method do\n it \"stores the current queue that is being used when a callback is added\" d"
},
{
"path": "spec/motion/reactor_spec.rb",
"chars": 4115,
"preview": "describe BubbleWrap::Reactor do\n before do\n @subject = ::BubbleWrap::Reactor\n @proxy = Class.new do\n attr_ac"
},
{
"path": "spec/motion/rss_parser_spec.rb",
"chars": 1739,
"preview": "describe \"RSSParser\" do\n extend WebStub::SpecHelpers\n\n before do\n @feed_url = 'https://raw.github.com/gist/2952427/"
},
{
"path": "spec/motion/sms/result_spec.rb",
"chars": 916,
"preview": "describe BW::SMS::Result do\n\n before do\n @subject = BW::SMS::Result.new(MessageComposeResultCancelled)\n end\n\n it \""
},
{
"path": "spec/motion/sms/sms_spec.rb",
"chars": 2437,
"preview": "# Mocking the presentViewController\nclass MessageViewController < UIViewController\n attr_accessor :expectation\n\n def p"
},
{
"path": "spec/motion/ui/pollute_spec.rb",
"chars": 333,
"preview": "describe \"UIKit pollution\" do\n it \"pollutes UIControl\" do\n UIControl.ancestors.should.include BW::UIControlWrapper\n "
},
{
"path": "spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb",
"chars": 1887,
"preview": "describe BubbleWrap::UIActivityViewController do\n before do\n @controller = UIViewController.alloc.init\n @controll"
},
{
"path": "spec/motion/ui/ui_alert_view_spec.rb",
"chars": 38872,
"preview": "shared \"an instance with no options\" do\n it \"has the correct class\" do\n @subject.class.should.equal(BW::UIAlertView)"
},
{
"path": "spec/motion/ui/ui_bar_button_item_spec.rb",
"chars": 17833,
"preview": "describe BW::UIBarButtonItem do\n class NavigationItemContainingBarButtonItem < UINavigationItem\n def init_with_style"
},
{
"path": "spec/motion/ui/ui_control_wrapper_spec.rb",
"chars": 2936,
"preview": "describe BW::UIControlWrapper do\n describe \"#when\" do\n before do\n @subject = UIControl.alloc.init\n @touche"
},
{
"path": "spec/motion/ui/ui_view_controller_wrapper_spec.rb",
"chars": 1054,
"preview": "describe BW::UIViewControllerWrapper do\n describe \"#content_frame\" do\n describe \"given a UIViewController\" do\n "
},
{
"path": "spec/motion/ui/ui_view_wrapper_spec.rb",
"chars": 2776,
"preview": "describe BW::UIViewWrapper do\n describe \"gestures\" do\n before do\n @view = App.delegate.window.rootViewControlle"
},
{
"path": "spec/motion/util/constants_spec.rb",
"chars": 1258,
"preview": "describe BubbleWrap::Constants do\n describe \".get\" do\n BubbleWrap::Constants.register NSStringEncodingConversionAllo"
},
{
"path": "spec/motion/util/deprecated_spec.rb",
"chars": 1860,
"preview": "module ModuleExample\n include BubbleWrap::Deprecated\n\n module_function\n\n def a_method\n @called = true\n end\n\n dep"
}
]
About this extraction
This page contains the full source code of the rubymotion/BubbleWrap GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 186 files (553.1 KB), approximately 153.9k tokens, and a symbol index with 690 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.