bubble-wrap 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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