Error handling in capture competition blocks. Permissions fixes.

This commit is contained in:
Natalia Terlecka 2015-03-20 10:46:01 +00:00
parent 2a86fe5140
commit 0ea8751297
4 changed files with 61 additions and 51 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="bhK-VL-qY4">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1066" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="bhK-VL-qY4">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
</dependencies>
<scenes>
<!--Camera-->
@ -73,7 +73,7 @@
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3WP-Xo-FaJ">
<rect key="frame" x="256" y="20" width="88" height="33"/>
<color key="backgroundColor" red="1" green="0.87630701789999998" blue="0.35755069969999997" alpha="1" colorSpace="calibratedRGB"/>
<state key="normal" title="Image">
<state key="normal" title="Video">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>

View File

@ -13,7 +13,7 @@ import AssetsLibrary
private let _singletonSharedInstance = CameraManager()
public enum CameraState {
case Ready, AccessDenied, NoDeviceFound
case Ready, AccessDenied, NoDeviceFound, NotDetermined
}
public enum CameraDevice {
@ -170,7 +170,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
}
private weak var embedingView: UIView?
private var videoCompletition: ((videoURL: NSURL) -> Void)?
private var videoCompletition: ((videoURL: NSURL, error: NSError?) -> Void)?
private var sessionQueue: dispatch_queue_t = dispatch_queue_create("CameraSessionQueue", DISPATCH_QUEUE_SERIAL)
@ -223,7 +223,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
public func addPreviewLayerToView(view: UIView, newCameraOutputMode: CameraOutputMode) -> CameraState
{
let currentCameraState = _checkIfCameraIsAvailable()
if currentCameraState == .Ready {
if currentCameraState == .Ready || currentCameraState == .NotDetermined {
if let validEmbedingView = self.embedingView? {
if let validPreviewLayer = self.previewLayer? {
validPreviewLayer.removeFromSuperlayer()
@ -262,15 +262,17 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
self._startFollowingDeviceOrientation()
}
} else {
if self.cameraIsSetup {
self.stopAndRemoveCaptureSession()
}
self._setupCamera({Void -> Void in
if let validEmbedingView = self.embedingView? {
self._addPreeviewLayerToView(validEmbedingView)
if self._checkIfCameraIsAvailable() == .Ready || _checkIfCameraIsAvailable() == .NotDetermined {
if self.cameraIsSetup {
self.stopAndRemoveCaptureSession()
}
self._startFollowingDeviceOrientation()
})
self._setupCamera({Void -> Void in
if let validEmbedingView = self.embedingView? {
self._addPreeviewLayerToView(validEmbedingView)
}
self._startFollowingDeviceOrientation()
})
}
}
}
@ -296,7 +298,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
:param: imageCompletition Completition block containing the captured UIImage
*/
public func capturePictureWithCompletition(imageCompletition: UIImage -> Void)
public func capturePictureWithCompletition(imageCompletition: (UIImage?, NSError?) -> Void)
{
if self.cameraIsSetup {
if self.cameraOutputMode == .StillImage {
@ -308,6 +310,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
weakSelf._show("error", message: error.localizedDescription)
}
})
imageCompletition(nil, error)
} else {
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sample)
if let weakSelf = self {
@ -324,7 +327,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
}
}
}
imageCompletition(UIImage(data: imageData)!)
imageCompletition(UIImage(data: imageData), nil)
}
})
})
@ -351,7 +354,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
/**
Stop recording a video. Save it to the cameraRoll and give back the url.
*/
public func stopRecordingVideo(completition:(videoURL: NSURL) -> Void)
public func stopRecordingVideo(completition:(videoURL: NSURL, error: NSError?) -> Void)
{
if let runningMovieOutput = self.movieOutput {
if runningMovieOutput.recording {
@ -381,12 +384,12 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
self._show("Unable to save video to the iPhone.", message: error!.localizedDescription)
} else {
if let validAssetURL = assetURL {
self._executeVideoCompletitionWithURL(validAssetURL)
self._executeVideoCompletitionWithURL(validAssetURL, error: error)
}
}
})
} else {
self._executeVideoCompletitionWithURL(outputFileURL)
self._executeVideoCompletitionWithURL(outputFileURL, error: error)
}
}
}
@ -394,10 +397,10 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
// PRAGMA MARK - CameraManager()
private func _executeVideoCompletitionWithURL(url: NSURL)
private func _executeVideoCompletitionWithURL(url: NSURL, error: NSError?)
{
if let validCompletition = self.videoCompletition {
validCompletition(videoURL: url)
validCompletition(videoURL: url, error: error)
self.videoCompletition = nil
}
}
@ -481,28 +484,26 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
private func _setupCamera(completition: Void -> Void)
{
if self._checkIfCameraIsAvailable() == .Ready {
self.captureSession = AVCaptureSession()
dispatch_async(sessionQueue, {
if let validCaptureSession = self.captureSession? {
validCaptureSession.beginConfiguration()
validCaptureSession.sessionPreset = AVCaptureSessionPresetHigh
self._addVideoInput()
self._setupOutputs()
self._setupOutputMode(self._cameraOutputMode)
self.cameraOutputQuality = self._cameraOutputQuality
self._setupPreviewLayer()
validCaptureSession.commitConfiguration()
validCaptureSession.startRunning()
self._startFollowingDeviceOrientation()
self.cameraIsSetup = true
self._orientationChanged()
completition()
}
})
}
self.captureSession = AVCaptureSession()
dispatch_async(sessionQueue, {
if let validCaptureSession = self.captureSession? {
validCaptureSession.beginConfiguration()
validCaptureSession.sessionPreset = AVCaptureSessionPresetHigh
self._addVideoInput()
self._setupOutputs()
self._setupOutputMode(self._cameraOutputMode)
self.cameraOutputQuality = self._cameraOutputQuality
self._setupPreviewLayer()
validCaptureSession.commitConfiguration()
validCaptureSession.startRunning()
self._startFollowingDeviceOrientation()
self.cameraIsSetup = true
self._orientationChanged()
completition()
}
})
}
private func _startFollowingDeviceOrientation()
@ -535,9 +536,13 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
{
let deviceHasCamera = UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Rear) || UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Front)
if deviceHasCamera {
let userAgreedToUseIt = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) == .Authorized
let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
let userAgreedToUseIt = authorizationStatus == .Authorized
if userAgreedToUseIt {
return .Ready
} else if authorizationStatus == AVAuthorizationStatus.NotDetermined {
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (alowedAccess) -> Void in })
return .NotDetermined
} else {
return .AccessDenied
}
@ -545,7 +550,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
return .NoDeviceFound
}
}
private func _addVideoInput()
{
var error: NSError?

View File

@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>1.0.10</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>2</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>

View File

@ -72,11 +72,13 @@ class ViewController: UIViewController {
{
switch (self.cameraManager.cameraOutputMode) {
case .StillImage:
self.cameraManager.capturePictureWithCompletition({ (image) -> Void in
self.cameraManager.capturePictureWithCompletition({ (image, error) -> Void in
let vc: ImageViewController? = self.storyboard?.instantiateViewControllerWithIdentifier("ImageVC") as? ImageViewController
if let validVC: ImageViewController = vc {
validVC.image = image
self.navigationController?.pushViewController(validVC, animated: true)
if let capturedImage = image? {
validVC.image = capturedImage
self.navigationController?.pushViewController(validVC, animated: true)
}
}
})
case .VideoWithMic, .VideoOnly:
@ -86,8 +88,11 @@ class ViewController: UIViewController {
if sender.selected {
self.cameraManager.startRecordingVideo()
} else {
self.cameraManager.stopRecordingVideo({ (videoURL) -> Void in
self.cameraManager.stopRecordingVideo({ (videoURL, error) -> Void in
println(videoURL)
if let errorOccured = error? {
UIAlertView(title: "Error occured", message: errorOccured.localizedDescription, delegate: nil, cancelButtonTitle: "OK").show()
}
})
}
}