bubble-wrap 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +6 -14
  2. data/.travis.yml +2 -1
  3. data/CHANGELOG.md +26 -2
  4. data/GETTING_STARTED.md +1 -1
  5. data/Gemfile.lock +1 -1
  6. data/HACKING.md +6 -4
  7. data/README.md +83 -3
  8. data/Rakefile +9 -7
  9. data/lib/bubble-wrap/all.rb +2 -2
  10. data/lib/bubble-wrap/mail.rb +9 -0
  11. data/lib/bubble-wrap/sms.rb +9 -0
  12. data/lib/bubble-wrap/ui.rb +6 -2
  13. data/lib/bubble-wrap/version.rb +1 -1
  14. data/motion/core.rb +1 -1
  15. data/motion/core/app.rb +7 -2
  16. data/motion/core/device/ios/camera.rb +3 -2
  17. data/motion/core/device/ios/screen.rb +19 -0
  18. data/motion/core/ios/app.rb +13 -1
  19. data/motion/core/ios/device.rb +5 -0
  20. data/motion/core/json.rb +1 -3
  21. data/motion/core/kvo.rb +11 -13
  22. data/motion/core/persistence.rb +8 -1
  23. data/motion/core/string.rb +3 -3
  24. data/motion/core/time.rb +5 -0
  25. data/motion/http.rb +1 -1
  26. data/motion/http/query.rb +39 -19
  27. data/motion/http/response.rb +4 -4
  28. data/motion/mail/mail.rb +59 -0
  29. data/motion/mail/result.rb +29 -0
  30. data/motion/reactor/eventable.rb +3 -2
  31. data/motion/reactor/periodic_timer.rb +12 -8
  32. data/motion/reactor/timer.rb +11 -7
  33. data/motion/sms/result.rb +24 -0
  34. data/motion/sms/sms.rb +47 -0
  35. data/motion/ui/pollute.rb +4 -1
  36. data/motion/ui/ui_alert_view.rb +15 -8
  37. data/motion/ui/ui_control_wrapper.rb +16 -0
  38. data/motion/ui/ui_view_controller_wrapper.rb +13 -0
  39. data/motion/ui/ui_view_wrapper.rb +55 -0
  40. data/resources/Localizable.strings +1 -0
  41. data/samples/gesture/Gemfile +2 -2
  42. data/samples/location/Gemfile +1 -1
  43. data/samples/osx/Gemfile +2 -2
  44. data/spec/motion/core/app_spec.rb +6 -0
  45. data/spec/motion/core/device/ios/camera_spec.rb +3 -3
  46. data/spec/motion/core/device/ios/screen_spec.rb +45 -0
  47. data/spec/motion/core/ios/app_spec.rb +29 -0
  48. data/spec/motion/core/persistence_spec.rb +25 -0
  49. data/spec/motion/core/string_spec.rb +2 -2
  50. data/spec/motion/core/time_spec.rb +14 -4
  51. data/spec/motion/core_spec.rb +9 -8
  52. data/spec/motion/http/query_spec.rb +92 -15
  53. data/spec/motion/http/response_spec.rb +4 -3
  54. data/spec/motion/location/location_spec.rb +1 -1
  55. data/spec/motion/mail/mail_spec.rb +125 -0
  56. data/spec/motion/mail/result_spec.rb +53 -0
  57. data/spec/motion/reactor/eventable_spec.rb +85 -0
  58. data/spec/motion/reactor_spec.rb +0 -20
  59. data/spec/motion/sms/result_spec.rb +38 -0
  60. data/spec/motion/sms/sms_spec.rb +71 -0
  61. data/spec/motion/ui/pollute_spec.rb +13 -0
  62. data/spec/motion/ui/ui_bar_button_item_spec.rb +8 -8
  63. data/spec/motion/ui/ui_control_wrapper_spec.rb +35 -0
  64. data/spec/motion/ui/ui_view_controller_wrapper_spec.rb +34 -0
  65. data/spec/motion/ui/ui_view_wrapper_spec.rb +62 -0
  66. data/travis.sh +7 -0
  67. metadata +52 -22
  68. data/motion/ui/gestures.rb +0 -57
  69. data/motion/ui/ui_control.rb +0 -14
  70. data/motion/ui/ui_view_controller.rb +0 -11
  71. data/spec/motion/ui/gestures_spec.rb +0 -62
  72. data/spec/motion/ui/ui_control_spec.rb +0 -42
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MTMyNzRlMzhmMzlkODllNWQxMmIwOGNkZWZjZWI1MzliY2UzMThkMw==
5
- data.tar.gz: !binary |-
6
- ODU4NjExZjljN2ViYTNmYjk0YmQ2NjU5ZTVlYzRiNTQ3OTIyZjE1MQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- YjY5ZTNmMjc2NzIzMGUxZmI1NDYyN2U1NGQwNWYxY2VlYjI0OTExMWU5MTJk
10
- NWRjODAzMTNjYmVmODg0NWZhZWI5MDE2N2NiZDg2ZmJhZTcyNDgzZThkZjYz
11
- MzUyYzViMzU4MzM2ODU3NGIzZjA0OWVkNDM2OTVhNGEwOTg2MDk=
12
- data.tar.gz: !binary |-
13
- MGEyZmMyNDRjYjdiNjFhZWQ5NmMxMjJiNWMyNWUwZmE5NzE2ODMwMjBiZmYz
14
- MDk3YjIzZTY2ZTQ4MmVkZDBlYTVlOGVjY2YzYTUyNzM4NGU1ZWMxMzAzZGVj
15
- ZmE4ODc4NjZiM2Q5ZGU2ZTE0MGMyNDhhYzM4YWYwNjI5MDRkMTM=
2
+ SHA1:
3
+ metadata.gz: f49e903b8cbae3bf9a475a04c9fa209aa944ab60
4
+ data.tar.gz: aa486c325db87d7d54eb5647f8acce0e28ef6e48
5
+ SHA512:
6
+ metadata.gz: 83bf22da6648b81fbc4b7717445ea63154ad10fad278767958fb074ec41c2fce7d792022d87ff629925940e5d6f20cea2791e97614155963e071aa8580f82867
7
+ data.tar.gz: 1e5d77f5ec252c58a78fe372eddb3a0f7468d13b36344dd4cb12cf6162d3fdd70ba1db5d9911f709b4865d978ca698b040a9e0dba27a64e930aa99e054e84647
@@ -1,4 +1,5 @@
1
1
  language: objective-c
2
2
  before_install:
3
3
  - (ruby --version)
4
- script: "(bundle install) && (bundle exec rake clean) && (bundle exec rake spec) && (bundle exec rake clean) && (bundle exec rake spec osx=true)"
4
+ before_script: sudo chown -R travis ~/Library/RubyMotion
5
+ script: ./travis.sh
@@ -1,16 +1,40 @@
1
1
  ## Unreleased
2
2
 
3
+ [Commit history](https://github.com/rubymotion/BubbleWrap/compare/v1.4.0...master)
4
+
5
+ ## 1.4.0
6
+
3
7
  [Commit history](https://github.com/rubymotion/BubbleWrap/compare/v1.3.0...master)
4
8
 
9
+ * Added `BW::Mail` for sending emails ([#247](https://github.com/rubymotion/BubbleWrap/pull/247))
10
+ * Added `BW::SMS` for sending SMS/iMessages ([#287](https://github.com/rubymotion/BubbleWrap/pull/287))
11
+ * Added `App::Persistence.delete` ([#286](https://github.com/rubymotion/BubbleWrap/pull/286))
12
+ * Added `BW::HTTP::Response#error`, which is an `NSError` instance ([#284](https://github.com/rubymotion/BubbleWrap/pull/284))
13
+ * Added `BW::HTTP::Query#cancel` to chancel URL requests ([#278](https://github.com/rubymotion/BubbleWrap/pull/278))
14
+ * Added `App.info_plist` ([#273](https://github.com/rubymotion/BubbleWrap/pull/273/))
15
+ * Added `BW::Device.interface_orientation` ([#265](https://github.com/rubymotion/BubbleWrap/pull/265))
16
+ * Added `OPTIONS` request method to `BW::HTTP` ([#260](https://github.com/rubymotion/BubbleWrap/pull/260))
17
+ * Added `Time.iso8601_with_timezone` ([#255](https://github.com/rubymotion/BubbleWrap/pull/255))
18
+ * Added `:encoding` option to `BW::HTTP` ([#251](https://github.com/rubymotion/BubbleWrap/pull/251))
19
+ * Moved `BW::Reactor::Timer` and `BW::Reactor::PeriodicTimer` from `NSTimer` to GCD `Dispatch::Source.timer` ([#242](https://github.com/rubymotion/BubbleWrap/pull/242))
20
+ * Option `:common_modes` for BW::Reactor::PeriodicTimer has been deprecated, it's not needed anymore.
21
+ * Fixed App#window (and thus `BW::Camera`) to work with iOS7 modals ([#305](https://github.com/rubymotion/BubbleWrap/pull/305))
22
+ * Fixed patches on `String` to be on `NSString` ([#292](https://github.com/rubymotion/BubbleWrap/pull/292))
23
+ * Fixed `BW::HTTP` success heuristic to match RFC 2616 ([#282](https://github.com/rubymotion/BubbleWrap/pull/282))
24
+ * Fixed `BW::HTTP` to correctly identify `false` parameters ([#261](https://github.com/rubymotion/BubbleWrap/issues/261) [#262](https://github.com/rubymotion/BubbleWrap/pull/262))
25
+ * Fixed `BW::Reactor` to correctly handle unregistered procs ([#253](https://github.com/rubymotion/BubbleWrap/pull/253))
26
+ * Fixed `BW::localized_string` to mirror Cocoa API by returning the `key` if no localization exists ([#181](https://github.com/rubymotion/BubbleWrap/pull/181))
27
+ * Addressed a few memory related problems ([#270](https://github.com/rubymotion/BubbleWrap/pull/270) [#275](https://github.com/rubymotion/BubbleWrap/pull/275) [#276](https://github.com/rubymotion/BubbleWrap/pull/276))
28
+
5
29
  ## 1.3.0
6
30
 
7
31
  [Commit history](https://github.com/rubymotion/BubbleWrap/compare/v1.2.0...v1.3.0)
8
32
 
9
33
  * Added OS X support for RubyMotion 2.0 ([#233](https://github.com/rubymotion/BubbleWrap/pull/233)). BubbleWrap *drops support* for RubyMotion 1.x.
10
- * Changed `BW::UIBarButtonItem` internals; `.build` is now deprecated and forwards to `.ne` ([#226](https://github.com/rubymotion/BubbleWrap/pull/226))
34
+ * Changed `BW::UIBarButtonItem` internals; `.build` is now deprecated and forwards to `.new` ([#226](https://github.com/rubymotion/BubbleWrap/pull/226))
11
35
  * 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/BubbleWrap/pull/199))
12
36
  * Fixed `HTTP` to not append a question-mark (`?`) at the end of URL requests with empty `:payload`s ([#221](https://github.com/rubymotion/BubbleWrap/pull/221))
13
- * Fixed `HTTP` to correct parameterize an array of hashes, Rails-style ([#219](https://github.com/rubymotion/BubbleWrap/pull/219))
37
+ * Fixed `HTTP` to correctly parameterize an array of hashes, Rails-style ([#219](https://github.com/rubymotion/BubbleWrap/pull/219))
14
38
 
15
39
  ## 1.2.0
16
40
 
@@ -12,7 +12,7 @@ RubyMotion install take a look at the [getting started guide](http://www.rubymot
12
12
  ## Create a new RubyMotion project
13
13
 
14
14
  RubyMotion ships with the `motion` command-line tool to handle creating projects,
15
- updating and creatint support tickets.
15
+ updating and creating support tickets.
16
16
 
17
17
  ```
18
18
  $ motion create bw-demo
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bubble-wrap (1.3.0)
4
+ bubble-wrap (1.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/HACKING.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## A library in two parts
4
4
 
5
- RubyMotion forces a certain background-radiation of schitzophrenia
5
+ RubyMotion forces a certain background-radiation of schizophrenia
6
6
  due to the fact that it's build tools run using the system ruby
7
7
  via Rake. BubbleWrap manipulates the build environment in order
8
8
  to make it possible to include itself (and other code) into the
9
- build process from outsite the project heirarchy.
9
+ build process from outside the project hierarchy.
10
10
 
11
11
  ### Part the first: `lib/`
12
12
 
@@ -17,7 +17,9 @@ code when you call
17
17
  require 'bubble-wrap'
18
18
  ```
19
19
 
20
- 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
20
+ When `bubble-wrap` is required it immediately requires `bubble-wrap/loader`
21
+ which sets up the infrastructure needed to manipulate the `Rakefile` build process.
22
+ Once that is done we can freely call
21
23
 
22
24
  ```ruby
23
25
  BubbleWrap.require 'motion/core/**/*.rb'
@@ -76,7 +78,7 @@ of RubyMotion users that use BubbleWrap in their daily development then
76
78
  feel free to fork [the repository on GitHub](https://github.com/mattetti/BubbleWrap)
77
79
  and send us a pull request.
78
80
 
79
- You should place your implemenation files in a subdirectory of `motion`
81
+ You should place your implementation files in a subdirectory of `motion`
80
82
  (eg `motion/my_awesome_project`), your tests in a subdirectory of `spec`
81
83
  (eg `spec/my_awesome_project`) and you can create a require file in
82
84
  `lib/bubble-wrap` for example `lib/bubble-wrap/my_awesome_project.rb`:
data/README.md CHANGED
@@ -81,6 +81,18 @@ If you wish to only include the `Media` wrapper:
81
81
  require 'bubble-wrap/media'
82
82
  ```
83
83
 
84
+ If you wish to only include the `Mail` wrapper:
85
+
86
+ ```ruby
87
+ require 'bubble-wrap/mail'
88
+ ```
89
+
90
+ If you wish to only include the `SMS` wrapper:
91
+
92
+ ```ruby
93
+ require 'bubble-wrap/sms'
94
+ ```
95
+
84
96
  If you want to include everything (ie kitchen sink mode) you can save time and do:
85
97
 
86
98
  ```ruby
@@ -207,6 +219,8 @@ Examples:
207
219
  # true
208
220
  > Device.orientation
209
221
  # :portrait
222
+ > Device.interface_orientation
223
+ # :portrait
210
224
  > Device.simulator?
211
225
  # true
212
226
  > Device.ios_version
@@ -246,7 +260,7 @@ end
246
260
 
247
261
  ### JSON
248
262
 
249
- `BW::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
263
+ `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).
250
264
 
251
265
  ```ruby
252
266
  BW::JSON.generate({'foo => 1, 'bar' => [1,2,3], 'baz => 'awesome'})
@@ -271,7 +285,7 @@ def viewWillAppear(animated)
271
285
  loadAndRefresh
272
286
  end
273
287
 
274
- @reload_observer = App.notification_center.observe ReloadNotification do |notification|
288
+ @reload_observer = App.notification_center.observe 'ReloadNotification' do |notification|
275
289
  loadAndRefresh
276
290
  end
277
291
  end
@@ -282,7 +296,7 @@ def viewWillDisappear(animated)
282
296
  end
283
297
 
284
298
  def reload
285
- App.notification_center.post ReloadNotification
299
+ App.notification_center.post 'ReloadNotification'
286
300
  end
287
301
  ```
288
302
 
@@ -302,6 +316,8 @@ simple interface:
302
316
  # ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
303
317
  > App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
304
318
  # ['TF1', 'France 2', 'France 3']
319
+ > App::Persistence.delete('channels')
320
+ # ['TF1', 'France 2', 'France 3']
305
321
  > App::Persistence['something__new'] # something previously never stored
306
322
  # nil
307
323
  ```
@@ -386,6 +402,50 @@ end
386
402
  BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
387
403
  ```
388
404
 
405
+ ## Mail
406
+
407
+ Wrapper for showing an in-app mail composer view.
408
+
409
+ ```ruby
410
+ # Opens as a modal in the current UIViewController
411
+ BW::Mail.compose {
412
+ delegate: self, # optional, defaults to rootViewController
413
+ to: [ "tom@example.com" ],
414
+ cc: [ "itchy@example.com", "scratchy@example.com" ],
415
+ bcc: [ "jerry@example.com" ],
416
+ html: false,
417
+ subject: "My Subject",
418
+ message: "This is my message. It isn't very long.",
419
+ animated: false
420
+ } do |result, error|
421
+ result.sent? # => boolean
422
+ result.canceled? # => boolean
423
+ result.saved? # => boolean
424
+ result.failed? # => boolean
425
+ error # => NSError
426
+ end
427
+ ```
428
+
429
+ ## SMS
430
+
431
+ Wrapper for showing an in-app message (SMS) composer view.
432
+
433
+ ```ruby
434
+ # Opens as a modal in the current UIViewController
435
+ BW::SMS.compose (
436
+ {
437
+ delegate: self, # optional, will use root view controller by default
438
+ to: [ "1(234)567-8910" ],
439
+ message: "This is my message. It isn't very long.",
440
+ animated: false
441
+ }) {|result, error|
442
+ result.sent? # => boolean
443
+ result.canceled? # => boolean
444
+ result.failed? # => boolean
445
+ error # => NSError
446
+ }
447
+ ```
448
+
389
449
  ## UI
390
450
 
391
451
  ### Gestures
@@ -571,6 +631,20 @@ would be a Proc that takes two arguments: a float representing the
571
631
  amount of data currently received and another float representing the
572
632
  total amount of data expected.
573
633
 
634
+ Connections can also be cancelled. Just keep a refrence,
635
+
636
+ ```ruby
637
+ @conn = BW::HTTP.get("https://api.github.com/users/mattetti") do |response|
638
+ p response.body.to_str
639
+ end
640
+ ```
641
+
642
+ and send the `cancel` method to it asynchronously as desired. The block will not be executed.
643
+
644
+ ```ruby
645
+ @conn.cancel
646
+ ```
647
+
574
648
  ### Gotchas
575
649
 
576
650
  Because of how RubyMotion currently works, you sometimes need to assign objects as `@instance_variables` in order to retain their callbacks.
@@ -650,6 +724,12 @@ end
650
724
  def when_parser_is_done
651
725
  p "The feed is entirely parsed, congratulations!"
652
726
  end
727
+
728
+ def when_parser_errors
729
+ p "The parser encountered an error"
730
+ ns_error = feed_parser.parserError
731
+ p ns_error.localizedDescription
732
+ end
653
733
  ```
654
734
 
655
735
  These delegate methods are optional, however, you might find the
data/Rakefile CHANGED
@@ -11,13 +11,15 @@ Bundler.require
11
11
  require 'bubble-wrap/all'
12
12
  require 'bubble-wrap/test'
13
13
 
14
- module Motion; module Project
15
- class Config
16
- def spec_files=(spec_files)
17
- @spec_files = spec_files
14
+ module Motion
15
+ module Project
16
+ class Config
17
+ def spec_files=(spec_files)
18
+ @spec_files = spec_files
19
+ end
18
20
  end
19
21
  end
20
- end; end
22
+ end
21
23
 
22
24
  Motion::Project::App.setup do |app|
23
25
  app.name = 'testSuite'
@@ -26,7 +28,7 @@ Motion::Project::App.setup do |app|
26
28
  app.spec_files
27
29
  if Motion::Project::App.osx?
28
30
  app.spec_files -= Dir.glob("./spec/motion/**/ios/**.rb")
29
- ["font", "location", "media", "ui"].each do |package|
31
+ ["font", "location", "media", "ui", "mail", "sms"].each do |package|
30
32
  app.spec_files -= Dir.glob("./spec/motion/#{package}/**/*.rb")
31
33
  end
32
34
  else
@@ -43,4 +45,4 @@ namespace :spec do
43
45
  task :motion => 'spec'
44
46
 
45
47
  task :all => [:lib, :motion]
46
- end
48
+ end
@@ -1,4 +1,4 @@
1
1
  require File.expand_path('../loader', __FILE__)
2
- ['core', 'http', 'reactor', 'rss_parser', 'ui', 'location', 'media', 'font'].each { |sub|
2
+ ['core', 'http', 'reactor', 'rss_parser', 'ui', 'location', 'media', 'font', 'mail','sms'].each { |sub|
3
3
  require File.expand_path("../#{sub}", __FILE__)
4
- }
4
+ }
@@ -0,0 +1,9 @@
1
+ require 'bubble-wrap/loader'
2
+
3
+ BubbleWrap.require_ios("mail") do
4
+ BubbleWrap.require('motion/core/app.rb')
5
+ BubbleWrap.require('motion/mail/**/*.rb') do
6
+ file('motion/mail/mail.rb').depends_on('motion/mail/result.rb')
7
+ file('motion/mail/mail.rb').uses_framework('MessageUI')
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'bubble-wrap/loader'
2
+
3
+ BubbleWrap.require_ios("sms") do
4
+ BubbleWrap.require('motion/core/app.rb')
5
+ BubbleWrap.require('motion/sms/**/*.rb') do
6
+ file('motion/sms/sms.rb').depends_on('motion/sms/result.rb')
7
+ file('motion/sms/sms.rb').uses_framework('MessageUI')
8
+ end
9
+ end
@@ -2,6 +2,10 @@ require 'bubble-wrap/loader'
2
2
 
3
3
  BubbleWrap.require_ios("ui") do
4
4
  BubbleWrap.require('motion/ui/**/*.rb') do
5
- file('motion/ui/pollute.rb').depends_on 'motion/ui/ui_control.rb'
5
+ file('motion/ui/pollute.rb').depends_on %w(
6
+ motion/ui/ui_control_wrapper.rb
7
+ motion/ui/ui_view_wrapper.rb
8
+ motion/ui/ui_view_controller_wrapper.rb
9
+ )
6
10
  end
7
- end
11
+ end
@@ -1,4 +1,4 @@
1
1
  module BubbleWrap
2
- VERSION = '1.3.0' unless defined?(BubbleWrap::VERSION)
2
+ VERSION = '1.4.0' unless defined?(BubbleWrap::VERSION)
3
3
  MIN_MOTION_VERSION = '2.0'
4
4
  end
@@ -16,7 +16,7 @@ module BubbleWrap
16
16
  end
17
17
  end
18
18
 
19
- def localized_string(key, value)
19
+ def localized_string(key, value=nil)
20
20
  NSBundle.mainBundle.localizedStringForKey(key, value:value, table:nil)
21
21
  end
22
22
 
@@ -43,8 +43,12 @@ module BubbleWrap
43
43
  @states
44
44
  end
45
45
 
46
+ def info_plist
47
+ NSBundle.mainBundle.infoDictionary
48
+ end
49
+
46
50
  def name
47
- NSBundle.mainBundle.objectForInfoDictionaryKey 'CFBundleDisplayName'
51
+ info_plist['CFBundleDisplayName']
48
52
  end
49
53
 
50
54
  def identifier
@@ -52,7 +56,7 @@ module BubbleWrap
52
56
  end
53
57
 
54
58
  def version
55
- NSBundle.mainBundle.infoDictionary['CFBundleVersion']
59
+ info_plist['CFBundleVersion']
56
60
  end
57
61
 
58
62
  # @return [NSLocale] locale of user settings
@@ -90,5 +94,6 @@ module BubbleWrap
90
94
  Kernel.const_defined?(:UIApplication)
91
95
  end
92
96
  end
97
+
93
98
  end
94
99
  ::App = BubbleWrap::App unless defined?(::App)
@@ -17,6 +17,8 @@ module BubbleWrap
17
17
 
18
18
  MEDIA_TYPE_HASH = {movie: KUTTypeMovie, image: KUTTypeImage}
19
19
 
20
+ CAMERA_LOCATIONS = [:front, :rear, :none]
21
+
20
22
  # The camera location; if :none, then we can't use source_type: :camera
21
23
  # in #picture
22
24
  # [:front, :rear, :none]
@@ -42,7 +44,7 @@ module BubbleWrap
42
44
  end
43
45
 
44
46
  def location=(location)
45
- if not [:front, :rear, :none].member? location
47
+ if not CAMERA_LOCATIONS.member? location
46
48
  raise Error::INVALID_CAMERA_LOCATION, "#{location} is not a valid camera location"
47
49
  end
48
50
  @location = location
@@ -137,7 +139,6 @@ module BubbleWrap
137
139
  # instead of UIImagePickerControllerThisForm, and then sends it
138
140
  # to the callback
139
141
  def imagePickerController(picker, didFinishPickingMediaWithInfo: info)
140
- delete_keys = []
141
142
  callback_info = {}
142
143
 
143
144
  info.keys.each { |k|
@@ -35,6 +35,25 @@ module BubbleWrap
35
35
  end
36
36
  end
37
37
 
38
+ # Figure out the current orientation of the interface
39
+ # @return [:portrait, :portrait_upside_down, :landscape_left, :landscape_right]
40
+ def interface_orientation(device_orientation=UIDevice.currentDevice.orientation, fallback=true)
41
+ case device_orientation
42
+ when UIInterfaceOrientationPortrait then :portrait
43
+ when UIInterfaceOrientationPortraitUpsideDown then :portrait_upside_down
44
+ when UIInterfaceOrientationLandscapeLeft then :landscape_left
45
+ when UIInterfaceOrientationLandscapeRight then :landscape_right
46
+ else
47
+ # In some cases, the accelerometer can't get an accurate read of orientation so we fall back on the orientation of
48
+ # the status bar.
49
+ if fallback && (device_orientation != UIApplication.sharedApplication.statusBarOrientation)
50
+ orientation(UIApplication.sharedApplication.statusBarOrientation)
51
+ else
52
+ :unknown
53
+ end
54
+ end
55
+ end
56
+
38
57
  # The width of the device's screen.
39
58
  # The real resolution is dependant on the scale
40
59
  # factor (see `retina?`) but the coordinate system