class BubbleWrap::Device::Camera
Constants
- CAMERA_LOCATIONS
- MEDIA_TYPE_HASH
Attributes
The camera location; if :none, then we can't use source_type: :camera in picture
- :front, :rear, :none
Public Class Methods
# File motion/core/device/ios/camera.rb, line 50 def any @any ||= Camera.new end
# File motion/core/device/ios/camera.rb, line 44 def self.available? UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera) end
# File motion/core/device/ios/camera.rb, line 34 def self.front return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront) @front ||= Camera.new(:front) end
@param [String] (either KUTTypeMovie or KUTTypeImage) @param [UIImagePickerControllerSourceType]
# File motion/core/device/ios/camera.rb, line 226 def self.media_type_available?(media_type, for_source_type: source_type) UIImagePickerController.availableMediaTypesForSourceType(source_type).member? media_type end
# File motion/core/device/ios/camera.rb, line 61 def initialize(location = :none) self.location = location end
# File motion/core/device/ios/camera.rb, line 39 def self.rear return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear) @rear ||= Camera.new(:rear) end
@param [UIImagePickerControllerSourceType] source_type to check
# File motion/core/device/ios/camera.rb, line 220 def self.source_type_available?(source_type) UIImagePickerController.isSourceTypeAvailable(source_type) end
Public Instance Methods
# File motion/core/device/ios/camera.rb, line 210 def dismiss if @options[:on_dismiss] @options[:on_dismiss].call(self.picker) return end self.picker.dismissViewControllerAnimated(@options[:animated], completion: @options[:dismiss_completed]) end
# File motion/core/device/ios/camera.rb, line 72 def flash? return false if self.location == :none UIImagePickerController.isFlashAvailableForCameraDevice(camera_device) 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
# File motion/core/device/ios/camera.rb, line 181 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
UIImagePickerControllerDelegate Methods
# File motion/core/device/ios/camera.rb, line 172 def imagePickerControllerDidCancel(picker) error(Error::CANCELED) dismiss end
# File motion/core/device/ios/camera.rb, line 65 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
Short Helper Methods
# File motion/core/device/ios/camera.rb, line 205 def picker @picker_klass ||= UIImagePickerController @picker ||= @picker_klass.alloc.init 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
# File motion/core/device/ios/camera.rb, line 99 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
# File motion/core/device/ios/camera.rb, line 166 def popoverControllerDidDismissPopover(popoverController) @popover = nil end
# File motion/core/device/ios/camera.rb, line 56 def popover_from(view) @popover_in_view = view self end
Private Instance Methods
# File motion/core/device/ios/camera.rb, line 231 def camera_device Constants.get("UIImagePickerControllerCameraDevice", self.location) end
# File motion/core/device/ios/camera.rb, line 245 def error(type) @callback.call({ error: type }) end
ex media_type_to_symbol
(KUTTypeMovie) => :movie
# File motion/core/device/ios/camera.rb, line 236 def media_type_to_symbol(media_type) MEDIA_TYPE_HASH.invert[media_type] end
ex symbol_to_media_type
(:movie) => :KUTTypeMovie
# File motion/core/device/ios/camera.rb, line 241 def symbol_to_media_type(symbol) MEDIA_TYPE_HASH[symbol] end