bubble-wrap 1.0.0 → 1.1.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.
- data/.gitignore +0 -1
- data/.yardopts +2 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +24 -0
- data/HACKING.md +2 -2
- data/README.md +363 -21
- data/Rakefile +6 -2
- data/lib/bubble-wrap.rb +0 -1
- data/lib/bubble-wrap/all.rb +4 -0
- data/lib/bubble-wrap/camera.rb +7 -0
- data/lib/bubble-wrap/core.rb +3 -2
- data/lib/bubble-wrap/ext/motion_project_app.rb +2 -2
- data/lib/bubble-wrap/http.rb +1 -0
- data/lib/bubble-wrap/loader.rb +19 -12
- data/lib/bubble-wrap/location.rb +6 -0
- data/lib/bubble-wrap/reactor.rb +10 -0
- data/lib/bubble-wrap/requirement.rb +11 -3
- data/lib/bubble-wrap/rss_parser.rb +2 -0
- data/lib/bubble-wrap/ui.rb +4 -0
- data/lib/bubble-wrap/version.rb +1 -1
- data/motion/core.rb +8 -2
- data/motion/core/app.rb +34 -6
- data/motion/core/device.rb +10 -1
- data/motion/core/device/camera.rb +219 -0
- data/motion/core/device/camera_wrapper.rb +45 -0
- data/motion/core/ns_url_request.rb +10 -0
- data/motion/core/persistence.rb +7 -0
- data/motion/core/pollute.rb +1 -2
- data/motion/core/string.rb +23 -0
- data/motion/http.rb +142 -83
- data/motion/location/location.rb +152 -0
- data/motion/location/pollute.rb +5 -0
- data/motion/reactor.rb +105 -0
- data/motion/reactor/default_deferrable.rb +9 -0
- data/motion/reactor/deferrable.rb +126 -0
- data/motion/reactor/eventable.rb +24 -0
- data/motion/reactor/future.rb +22 -0
- data/motion/reactor/periodic_timer.rb +27 -0
- data/motion/reactor/queue.rb +60 -0
- data/motion/reactor/timer.rb +25 -0
- data/motion/rss_parser.rb +131 -0
- data/motion/shortcut.rb +18 -0
- data/motion/{core → ui}/gestures.rb +15 -9
- data/motion/ui/pollute.rb +5 -0
- data/motion/{core → ui}/ui_control.rb +0 -0
- data/motion/{core → ui}/ui_view_controller.rb +0 -0
- data/resources/atom.xml +1705 -0
- data/spec/lib/bubble-wrap/ext/motion_project_app_spec.rb +7 -11
- data/spec/lib/bubble-wrap/requirement_spec.rb +4 -4
- data/spec/lib/bubble-wrap_spec.rb +2 -2
- data/spec/motion/core/app_spec.rb +118 -14
- data/spec/motion/core/device/camera_spec.rb +130 -0
- data/spec/motion/core/device/camera_wrapper_spec.rb +45 -0
- data/spec/motion/core/device_spec.rb +0 -50
- data/spec/motion/core/gestures_spec.rb +5 -0
- data/spec/motion/core/persistence_spec.rb +24 -2
- data/spec/motion/core/string_spec.rb +55 -0
- data/spec/motion/core_spec.rb +72 -1
- data/spec/motion/http_spec.rb +100 -65
- data/spec/motion/location/location_spec.rb +152 -0
- data/spec/motion/reactor/eventable_spec.rb +40 -0
- data/spec/motion/reactor_spec.rb +163 -0
- data/spec/motion/rss_parser_spec.rb +36 -0
- metadata +75 -16
data/Rakefile
CHANGED
@@ -4,12 +4,17 @@ require 'motion/project'
|
|
4
4
|
Bundler.setup
|
5
5
|
Bundler.require
|
6
6
|
|
7
|
+
require 'bubble-wrap/all'
|
7
8
|
require 'bubble-wrap/test'
|
8
9
|
|
9
10
|
Motion::Project::App.setup do |app|
|
10
11
|
app.name = 'testSuite'
|
11
12
|
app.identifier = 'io.bubblewrap.testSuite'
|
12
|
-
app.specs_dir = './spec/motion'
|
13
|
+
app.specs_dir = './spec/motion/'
|
14
|
+
# Hold your breath, we're going API spelunking!
|
15
|
+
spec_files = app.spec_files + Dir.glob(File.join(app.specs_dir, '**/*.rb'))
|
16
|
+
spec_files.uniq!
|
17
|
+
app.instance_variable_set(:@spec_files, spec_files)
|
13
18
|
end
|
14
19
|
|
15
20
|
namespace :spec do
|
@@ -21,4 +26,3 @@ namespace :spec do
|
|
21
26
|
|
22
27
|
task :all => [:lib, :motion]
|
23
28
|
end
|
24
|
-
|
data/lib/bubble-wrap.rb
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'bubble-wrap/loader'
|
2
|
+
BubbleWrap.require('motion/core/device.rb')
|
3
|
+
BubbleWrap.require('motion/core/device/**/*.rb') do
|
4
|
+
file('motion/core/device/camera_wrapper.rb').depends_on 'motion/core/device/camera.rb'
|
5
|
+
file('motion/core/device/camera.rb').depends_on 'motion/core/device.rb'
|
6
|
+
file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
|
7
|
+
end
|
data/lib/bubble-wrap/core.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'bubble-wrap/loader'
|
2
2
|
BubbleWrap.require('motion/core.rb')
|
3
|
-
BubbleWrap.require('motion/core/**/*.rb') do
|
3
|
+
BubbleWrap.require('motion/core/**/*.rb') do
|
4
|
+
file('motion/core/device/camera.rb').depends_on 'motion/core/device.rb'
|
4
5
|
file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
|
5
6
|
file('motion/core/pollute.rb').depends_on 'motion/core/ns_index_path.rb'
|
6
|
-
file('motion/core/pollute.rb').depends_on 'motion/core/ui_control.rb'
|
7
7
|
end
|
8
|
+
require 'bubble-wrap/ui'
|
@@ -6,9 +6,9 @@ module BubbleWrap
|
|
6
6
|
base.instance_eval do
|
7
7
|
def setup_with_bubblewrap(&block)
|
8
8
|
bw_config = proc do |app|
|
9
|
-
app.files =
|
9
|
+
app.files = ::BubbleWrap::Requirement.files(app.files)
|
10
10
|
app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
|
11
|
-
app.frameworks =
|
11
|
+
app.frameworks = ::BubbleWrap::Requirement.frameworks(app.frameworks)
|
12
12
|
block.call(app) unless block.nil?
|
13
13
|
end
|
14
14
|
configs.each_value &bw_config
|
data/lib/bubble-wrap/http.rb
CHANGED
data/lib/bubble-wrap/loader.rb
CHANGED
@@ -2,22 +2,29 @@ unless defined?(Motion::Project::Config)
|
|
2
2
|
raise "This file must be required within a RubyMotion project Rakefile."
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
require 'bubble-wrap/ext'
|
7
|
-
require 'bubble-wrap/requirement'
|
5
|
+
unless defined?(BubbleWrap::LOADER_PRESENT)
|
8
6
|
|
9
|
-
|
7
|
+
require 'bubble-wrap/version' unless defined?(VERSION)
|
8
|
+
require 'bubble-wrap/ext'
|
9
|
+
require 'bubble-wrap/requirement'
|
10
10
|
|
11
|
-
|
11
|
+
module BubbleWrap
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
LOADER_PRESENT=true
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def root
|
17
|
+
File.expand_path('../../../', __FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
def require(file_spec, &block)
|
21
|
+
Requirement.scan(caller.first, file_spec, &block)
|
22
|
+
end
|
16
23
|
|
17
|
-
def require(file_spec, &block)
|
18
|
-
Requirement.scan(caller.first, file_spec, &block)
|
19
24
|
end
|
20
25
|
|
21
|
-
|
26
|
+
BW = BubbleWrap unless defined?(BW)
|
22
27
|
|
23
|
-
BW
|
28
|
+
BW.require 'motion/shortcut.rb'
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require 'bubble-wrap/loader'
|
2
|
+
BubbleWrap.require('motion/core/string.rb')
|
3
|
+
BubbleWrap.require('motion/location/**/*.rb') do
|
4
|
+
file('motion/location/pollute.rb').depends_on 'motion/location/location.rb'
|
5
|
+
file('motion/location/location.rb').uses_framework('CoreLocation')
|
6
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'bubble-wrap/loader'
|
2
|
+
|
3
|
+
BW.require 'motion/reactor.rb'
|
4
|
+
BW.require 'motion/reactor/**/*.rb' do
|
5
|
+
file('motion/reactor.rb').depends_on Dir.glob('motion/reactor/**/*.rb')
|
6
|
+
file('motion/reactor/timer.rb').depends_on 'motion/reactor/eventable.rb'
|
7
|
+
file('motion/reactor/periodic_timer.rb').depends_on 'motion/reactor/eventable.rb'
|
8
|
+
file('motion/reactor/deferrable.rb').depends_on ['motion/reactor/timer.rb', 'motion/reactor/future.rb']
|
9
|
+
file('motion/reactor/default_deferrable.rb').depends_on 'motion/reactor/deferrable.rb'
|
10
|
+
end
|
@@ -57,6 +57,7 @@ module BubbleWrap
|
|
57
57
|
Dir.glob(File.expand_path(file_spec, root)).each do |file|
|
58
58
|
p = new(file,root)
|
59
59
|
self.paths[p.relative] = p
|
60
|
+
p.depends_on('motion/shortcut.rb') unless p.relative == 'motion/shortcut.rb'
|
60
61
|
end
|
61
62
|
self.class_eval(&block) if block
|
62
63
|
end
|
@@ -65,8 +66,14 @@ module BubbleWrap
|
|
65
66
|
paths.fetch(relative)
|
66
67
|
end
|
67
68
|
|
68
|
-
def files
|
69
|
-
paths.values.map(&:to_s)
|
69
|
+
def files(app_files=nil)
|
70
|
+
files = paths.values.map(&:to_s)
|
71
|
+
files += app_files if app_files
|
72
|
+
files.uniq
|
73
|
+
end
|
74
|
+
|
75
|
+
def clear!
|
76
|
+
paths.select! { |k,v| v.relative == 'motion/shortcut.rb' }
|
70
77
|
end
|
71
78
|
|
72
79
|
def files_dependencies
|
@@ -77,9 +84,10 @@ module BubbleWrap
|
|
77
84
|
deps
|
78
85
|
end
|
79
86
|
|
80
|
-
def frameworks
|
87
|
+
def frameworks(app_frameworks=nil)
|
81
88
|
frameworks = ['UIKit', 'Foundation', 'CoreGraphics'] +
|
82
89
|
paths.values.map(&:frameworks)
|
90
|
+
frameworks += app_frameworks if app_frameworks
|
83
91
|
frameworks.flatten.compact.sort.uniq
|
84
92
|
end
|
85
93
|
|
data/lib/bubble-wrap/version.rb
CHANGED
data/motion/core.rb
CHANGED
@@ -11,7 +11,7 @@ module BubbleWrap
|
|
11
11
|
UIColor.colorWithRed((r/255.0), green:(g/255.0), blue:(b/255.0), alpha:a)
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def localized_string(key, value)
|
15
15
|
NSBundle.mainBundle.localizedStringForKey(key, value:value, table:nil)
|
16
16
|
end
|
17
17
|
|
@@ -20,5 +20,11 @@ module BubbleWrap
|
|
20
20
|
NSLog arg.inspect
|
21
21
|
end
|
22
22
|
|
23
|
+
def create_uuid
|
24
|
+
uuid = CFUUIDCreate(nil)
|
25
|
+
uuid_string = CFUUIDCreateString(nil, uuid)
|
26
|
+
CFRelease(uuid)
|
27
|
+
uuid_string
|
28
|
+
end
|
29
|
+
|
23
30
|
end
|
24
|
-
BW = BubbleWrap
|
data/motion/core/app.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Provides a module to store global states
|
1
|
+
# Provides a module to store global states
|
2
2
|
#
|
3
3
|
module BubbleWrap
|
4
4
|
module App
|
@@ -26,12 +26,30 @@ module BubbleWrap
|
|
26
26
|
NSUserDefaults.standardUserDefaults
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
# Displays a UIAlertView.
|
30
|
+
#
|
31
|
+
# title - The title as a String.
|
32
|
+
# args - The title of the cancel button as a String, or a Hash of options.
|
33
|
+
# (Default: { cancel_button_title: 'OK' })
|
34
|
+
# cancel_button_title - The title of the cancel button as a String.
|
35
|
+
# message - The main message as a String.
|
36
|
+
# block - Yields the alert object if a block is given, and does so before the alert is shown.
|
37
|
+
def alert(title, *args, &block)
|
38
|
+
options = { cancel_button_title: 'OK' }
|
39
|
+
options.merge!(args.pop) if args.last.is_a?(Hash)
|
40
|
+
|
41
|
+
if args.size > 0 && args.first.is_a?(String)
|
42
|
+
options[:cancel_button_title] = args.shift
|
43
|
+
end
|
44
|
+
|
45
|
+
alert = UIAlertView.alloc.initWithTitle title,
|
46
|
+
message: options[:message],
|
47
|
+
delegate: nil,
|
48
|
+
cancelButtonTitle: options[:cancel_button_title],
|
34
49
|
otherButtonTitles: nil
|
50
|
+
|
51
|
+
yield(alert) if block_given?
|
52
|
+
|
35
53
|
alert.show
|
36
54
|
alert
|
37
55
|
end
|
@@ -47,6 +65,16 @@ module BubbleWrap
|
|
47
65
|
repeats: false)
|
48
66
|
end
|
49
67
|
|
68
|
+
# Opens an url (string or instance of `NSURL`)
|
69
|
+
# in the device's web browser.
|
70
|
+
# Usage Example:
|
71
|
+
# App.open_url("http://matt.aimonetti.net")
|
72
|
+
def open_url(url)
|
73
|
+
unless url.is_a?(NSURL)
|
74
|
+
url = NSURL.URLWithString(url)
|
75
|
+
end
|
76
|
+
UIApplication.sharedApplication.openURL(url)
|
77
|
+
end
|
50
78
|
|
51
79
|
@states = {}
|
52
80
|
|
data/motion/core/device.rb
CHANGED
@@ -14,15 +14,24 @@ module BubbleWrap
|
|
14
14
|
idiom == UIUserInterfaceIdiomPad
|
15
15
|
end
|
16
16
|
|
17
|
+
# Use this to make a DSL-style call for picking images
|
18
|
+
# @example Device.camera.front
|
19
|
+
# @return [Device::Camera::CameraWrapper]
|
20
|
+
def camera
|
21
|
+
BubbleWrap::Device::CameraWrapper
|
22
|
+
end
|
23
|
+
|
17
24
|
# Verifies that the device running has a front facing camera.
|
18
25
|
# @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
|
19
|
-
def front_camera?
|
26
|
+
def front_camera?
|
27
|
+
p "This method (front_camera?) is DEPRECATED. Transition to using Device.camera.front?"
|
20
28
|
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
|
21
29
|
end
|
22
30
|
|
23
31
|
# Verifies that the device running has a rear facing camera.
|
24
32
|
# @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
|
25
33
|
def rear_camera?(picker=UIImagePickerController)
|
34
|
+
p "This method (rear_camera?) is DEPRECATED. Transition to using Device.camera.rear?"
|
26
35
|
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
|
27
36
|
end
|
28
37
|
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# Provides a nice DSL for interacting with the standard
|
2
|
+
# UIImagePickerController
|
3
|
+
#
|
4
|
+
module BubbleWrap
|
5
|
+
module Device
|
6
|
+
class Camera
|
7
|
+
module Error
|
8
|
+
SOURCE_TYPE_NOT_AVAILABLE=0
|
9
|
+
INVALID_MEDIA_TYPE=1
|
10
|
+
MEDIA_TYPE_NOT_AVAILABLE=2
|
11
|
+
INVALID_CAMERA_LOCATION=3
|
12
|
+
CANCELED=1000
|
13
|
+
end
|
14
|
+
|
15
|
+
MEDIA_TYPE_HASH = {movie: KUTTypeMovie, image: KUTTypeImage}
|
16
|
+
|
17
|
+
# The camera location; if :none, then we can't use source_type: :camera
|
18
|
+
# in #picture
|
19
|
+
# [:front, :rear, :none]
|
20
|
+
attr_accessor :location
|
21
|
+
|
22
|
+
def self.front
|
23
|
+
return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
|
24
|
+
Camera.new(:front).retain
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.rear
|
28
|
+
return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
|
29
|
+
Camera.new(:rear).retain
|
30
|
+
end
|
31
|
+
|
32
|
+
# For uploading photos from the library.
|
33
|
+
def self.any
|
34
|
+
Camera.new.retain
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(location = :none)
|
38
|
+
self.location = location
|
39
|
+
end
|
40
|
+
|
41
|
+
def location=(location)
|
42
|
+
if not [:front, :rear, :none].member? location
|
43
|
+
raise Error::INVALID_CAMERA_LOCATION, "#{location} is not a valid camera location"
|
44
|
+
end
|
45
|
+
@location = location
|
46
|
+
end
|
47
|
+
|
48
|
+
def flash?
|
49
|
+
return false if self.location == :none
|
50
|
+
UIImagePickerController.isFlashAvailableForCameraDevice(camera_device)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param [Hash] options to open the UIImagePickerController with
|
54
|
+
# the form {
|
55
|
+
# source_type: :photo_library, :camera, or :saved_photos_album; default :photo_library
|
56
|
+
# media_types: [] containing :image and/or :movie; default [:image]
|
57
|
+
# allows_editing: true/false; default false
|
58
|
+
# animated: true/false; default true
|
59
|
+
# }
|
60
|
+
#
|
61
|
+
# @param [UIViewController] view controller from which to present the image picker;
|
62
|
+
# if nil, uses the keyWindow's rootViewController.
|
63
|
+
#
|
64
|
+
# @block for callback. takes one argument.
|
65
|
+
# - On error or cancelled, is called with a hash {error: BW::Camera::Error::<Type>}
|
66
|
+
# - On success, is called with a hash with a possible set of keys
|
67
|
+
# [:media_type, :original_image, :edited_image, :crop_rect, :media_url,
|
68
|
+
# :reference_url, :media_metadata]
|
69
|
+
#
|
70
|
+
# Example
|
71
|
+
# BW::Camera.picture(source_type: :photo_library, media_types: [:image]) do |result|
|
72
|
+
# image_view = UIImageView.alloc.initWithImage(result[:original_image])
|
73
|
+
# end
|
74
|
+
def picture(options = {}, presenting_controller = nil, &block)
|
75
|
+
@callback = block
|
76
|
+
|
77
|
+
@options = options
|
78
|
+
@options[:allows_editing] = false if not @options.has_key? :allows_editing
|
79
|
+
@options[:animated] = true if not @options.has_key? :animated
|
80
|
+
@options[:media_types] = [:image] if not @options.has_key? :media_types
|
81
|
+
|
82
|
+
# If we're using Camera.any, by default use photo library
|
83
|
+
if !@options.has_key?(:source_type) and self.location == :none
|
84
|
+
@options[:source_type] = :photo_library
|
85
|
+
# If we're using a real Camera, by default use the camera.
|
86
|
+
elsif !@options.has_key?(:source_type)
|
87
|
+
@options[:source_type] = :camera
|
88
|
+
end
|
89
|
+
|
90
|
+
source_type = const_int_get("UIImagePickerControllerSourceType", @options[:source_type])
|
91
|
+
if not Camera.source_type_available?(source_type)
|
92
|
+
error(Error::SOURCE_TYPE_NOT_AVAILABLE) and return
|
93
|
+
end
|
94
|
+
|
95
|
+
media_types = @options[:media_types].collect { |mt| symbol_to_media_type(mt) }
|
96
|
+
if media_types.member? nil
|
97
|
+
error(Error::INVALID_MEDIA_TYPE) and return
|
98
|
+
end
|
99
|
+
|
100
|
+
media_types.each { |media_type|
|
101
|
+
if not Camera.media_type_available?(media_type, for_source_type: source_type)
|
102
|
+
error(Error::MEDIA_TYPE_NOT_AVAILABLE) and return
|
103
|
+
end
|
104
|
+
}
|
105
|
+
|
106
|
+
self.picker.delegate = self
|
107
|
+
self.picker.sourceType = source_type
|
108
|
+
self.picker.mediaTypes = media_types
|
109
|
+
self.picker.allowsEditing = @options[:allows_editing]
|
110
|
+
|
111
|
+
if source_type == :camera && ![:front, :rear].member?(self.location)
|
112
|
+
raise Error::INVALID_CAMERA_LOCATION, "Can't use camera location #{self.location} with source type :camera"
|
113
|
+
end
|
114
|
+
|
115
|
+
if source_type == :camera
|
116
|
+
self.picker.cameraDevice = camera_device
|
117
|
+
end
|
118
|
+
|
119
|
+
presenting_controller ||= UIApplication.sharedApplication.keyWindow.rootViewController
|
120
|
+
presenting_controller.presentViewController(self.picker, animated:@options[:animated], completion: lambda {})
|
121
|
+
end
|
122
|
+
|
123
|
+
##########
|
124
|
+
# UIImagePickerControllerDelegate Methods
|
125
|
+
def imagePickerControllerDidCancel(picker)
|
126
|
+
error(Error::CANCELED)
|
127
|
+
dismiss
|
128
|
+
end
|
129
|
+
|
130
|
+
# Takes the default didFinishPickingMediaWithInfo hash,
|
131
|
+
# transforms the keys to be nicer symbols of :this_form
|
132
|
+
# instead of UIImagePickerControllerThisForm, and then sends it
|
133
|
+
# to the callback
|
134
|
+
def imagePickerController(picker, didFinishPickingMediaWithInfo: info)
|
135
|
+
delete_keys = []
|
136
|
+
callback_info = {}
|
137
|
+
|
138
|
+
info.keys.each { |k|
|
139
|
+
nice_key = k.gsub("UIImagePickerController", "").underscore.to_sym
|
140
|
+
val = info[k]
|
141
|
+
callback_info[nice_key] = val
|
142
|
+
info.delete k
|
143
|
+
}
|
144
|
+
|
145
|
+
if media_type = callback_info[:media_type]
|
146
|
+
callback_info[:media_type] = media_type_to_symbol(media_type)
|
147
|
+
end
|
148
|
+
|
149
|
+
@callback.call(callback_info)
|
150
|
+
dismiss
|
151
|
+
end
|
152
|
+
|
153
|
+
##########
|
154
|
+
# Short Helper Methods
|
155
|
+
def picker
|
156
|
+
@picker_klass ||= UIImagePickerController
|
157
|
+
@picker ||= @picker_klass.alloc.init
|
158
|
+
end
|
159
|
+
|
160
|
+
def dismiss
|
161
|
+
self.picker.dismissViewControllerAnimated(@options[:animated], completion: lambda {})
|
162
|
+
end
|
163
|
+
|
164
|
+
# @param [UIImagePickerControllerSourceType] source_type to check
|
165
|
+
def self.source_type_available?(source_type)
|
166
|
+
UIImagePickerController.isSourceTypeAvailable(source_type)
|
167
|
+
end
|
168
|
+
|
169
|
+
# @param [String] (either KUTTypeMovie or KUTTypeImage)
|
170
|
+
# @param [UIImagePickerControllerSourceType]
|
171
|
+
def self.media_type_available?(media_type, for_source_type: source_type)
|
172
|
+
UIImagePickerController.availableMediaTypesForSourceType(source_type).member? media_type
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
def camera_device
|
177
|
+
const_int_get("UIImagePickerControllerCameraDevice", self.location)
|
178
|
+
end
|
179
|
+
|
180
|
+
# ex media_type_to_symbol(KUTTypeMovie) => :movie
|
181
|
+
def media_type_to_symbol(media_type)
|
182
|
+
MEDIA_TYPE_HASH.invert[media_type]
|
183
|
+
end
|
184
|
+
|
185
|
+
# ex symbol_to_media_type(:movie) => :KUTTypeMovie
|
186
|
+
def symbol_to_media_type(symbol)
|
187
|
+
MEDIA_TYPE_HASH[symbol]
|
188
|
+
end
|
189
|
+
|
190
|
+
def error(type)
|
191
|
+
@callback.call({ error: type })
|
192
|
+
end
|
193
|
+
|
194
|
+
# @param [String] base of the constant
|
195
|
+
# @param [Integer, String, Symbol] the
|
196
|
+
# @return [Integer] the constant for this base
|
197
|
+
# Examples
|
198
|
+
# const_int_get("UIReturnKey", :done) => UIReturnKeyDone == 9
|
199
|
+
# const_int_get("UIReturnKey", "done") => UIReturnKeyDone == 9
|
200
|
+
# const_int_get("UIReturnKey", 9) => 9
|
201
|
+
def const_int_get(base, value)
|
202
|
+
return value if value.is_a? Numeric
|
203
|
+
value = value.to_s.camelize
|
204
|
+
Kernel.const_get("#{base}#{value}")
|
205
|
+
end
|
206
|
+
|
207
|
+
# Looks like RubyMotion adds UIKit constants
|
208
|
+
# at compile time. If you don't use these
|
209
|
+
# directly in your code, they don't get added
|
210
|
+
# to Kernel and const_int_get crashes.
|
211
|
+
def load_constants_hack
|
212
|
+
[UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera,
|
213
|
+
UIImagePickerControllerSourceTypeSavedPhotosAlbum
|
214
|
+
]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
::Camera = BubbleWrap::Device::Camera
|