AVCaptureLocation/AAPLViewController.m
/* |
Copyright (C) 2014 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
View controller for the camera interface and selecting location capture mode. |
*/ |
#import "AAPLViewController.h" |
#import "AAPLCaptureManager.h" |
@import AssetsLibrary; |
@interface AAPLViewController () <AAPLCaptureManagerDelegate> |
{ |
AAPLCaptureManager *_captureManager; |
UIBackgroundTaskIdentifier _backgroundRecordingID; |
} |
@property IBOutlet UIView *previewView; |
@property IBOutlet UIBarButtonItem *recordButton; |
@property IBOutlet UISegmentedControl *locationUpdateModeButton; |
@property IBOutlet UILabel *currentLocation; |
- (IBAction)toggleLocationUpdateMode:(id)sender; |
- (IBAction)toggleRecording:(id)sender; |
@end |
@implementation AAPLViewController |
#pragma mark - View Loading |
- (void)viewDidLoad |
{ |
[super viewDidLoad]; |
// Initialize the class responsible for managing AV capture session and asset writer |
_captureManager = [[AAPLCaptureManager alloc] init]; |
_captureManager.delegate = self; |
//Set default distance senstivity to 5 meters, which for this sample code purpose is considered as sensitivity for walking |
_captureManager.distanceUpdateInMeters = 5.0; |
// Keep track of changes to the device orientation so we can update the capture manager |
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; |
[notificationCenter addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil]; |
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; |
// Setup and start the capture session |
[_captureManager setupAndStartCaptureSession]; |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]]; |
// Setup preview layer |
if (_captureManager.session) |
{ |
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:_captureManager.session]; |
layer.videoGravity = AVLayerVideoGravityResizeAspect; |
layer.frame = self.previewView.bounds; |
[self.previewView.layer addSublayer:layer]; |
} |
} |
- (void)viewDidUnload |
{ |
[super viewDidUnload]; |
[self cleanup]; |
} |
- (void)cleanup |
{ |
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; |
[notificationCenter removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; |
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; |
[notificationCenter removeObserver:self name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]]; |
// Stop and tear down the capture session |
[_captureManager stopAndTearDownCaptureSession]; |
_captureManager.delegate = nil; |
} |
- (void)applicationDidBecomeActive:(NSNotification*)notifcation |
{ |
// For performance reasons, we manually pause/resume the session when saving a recording. |
// If we try to resume the session in the background it will fail. Resume the session here as well to ensure we will succeed. |
[_captureManager resumeCaptureSession]; |
} |
- (void)deviceOrientationDidChange |
{ |
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; |
// Don't update the reference orientation when the device orientation is face up/down or unknown. |
if (UIDeviceOrientationIsPortrait(orientation) || UIDeviceOrientationIsLandscape(orientation)) |
[_captureManager setReferenceOrientation:(AVCaptureVideoOrientation)orientation]; |
} |
#pragma mark - IBActions |
- (IBAction)toggleRecording:(id)sender |
{ |
// Wait for the recording to start/stop before re-enabling the record button. |
self.recordButton.enabled = NO; |
if ([_captureManager isRecording]) |
{ |
// The recordingWill/DidStop delegate methods will fire asynchronously in response to this call |
[_captureManager stopRecording]; |
} |
else |
{ |
// The recordingWill/DidStart delegate methods will fire asynchronously in response to this call |
[_captureManager startRecording]; |
} |
} |
- (IBAction)toggleLocationUpdateMode:(id)sender |
{ |
if(_locationUpdateModeButton.selectedSegmentIndex == 0) // Walking - set distance sensitibity to 5 meters |
{ |
_captureManager.distanceUpdateInMeters = 5.0; |
} |
else // Driving - set distance sensitivity to 20 meters |
{ |
_captureManager.distanceUpdateInMeters = 20.0; |
} |
} |
#pragma mark - AVCLVideoProcessorDelegate |
- (void)recordingWillStart |
{ |
dispatch_async(dispatch_get_main_queue(), ^{ |
self.recordButton.enabled = NO; |
self.recordButton.title = @"Stop"; |
self.locationUpdateModeButton.enabled = NO; |
// Disable the idle timer while we are recording |
[UIApplication sharedApplication].idleTimerDisabled = YES; |
// Make sure we have time to finish saving the movie if the app is backgrounded during recording |
if ([UIDevice currentDevice].multitaskingSupported) |
_backgroundRecordingID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}]; |
}); |
} |
- (void)recordingDidStart |
{ |
dispatch_async(dispatch_get_main_queue(), ^{ |
// Enable the stop button now that the recording has started |
self.recordButton.enabled = YES; |
}); |
} |
- (void)recordingWillStop |
{ |
dispatch_async(dispatch_get_main_queue(), ^{ |
// Disable until saving to the camera roll is complete |
self.recordButton.title = @"Record"; |
self.recordButton.enabled = NO; |
self.locationUpdateModeButton.enabled = NO; |
// Pause the capture session so that saving will be as fast as possible. |
// We resume the sesssion in recordingDidStop: |
[_captureManager pauseCaptureSession]; |
}); |
} |
- (void)recordingDidStop |
{ |
dispatch_async(dispatch_get_main_queue(), ^{ |
// Enable record and update mode buttons |
self.recordButton.enabled = YES; |
self.locationUpdateModeButton.enabled = YES; |
[self newLocationUpdate:@""]; // clear out the current location label |
[UIApplication sharedApplication].idleTimerDisabled = NO; |
[_captureManager resumeCaptureSession]; |
if ([UIDevice currentDevice].multitaskingSupported) |
{ |
[[UIApplication sharedApplication] endBackgroundTask:_backgroundRecordingID]; |
_backgroundRecordingID = UIBackgroundTaskInvalid; |
} |
}); |
} |
- (void)newLocationUpdate:(NSString *)locationDescription |
{ |
// Use this method to update the label which indicates the current location |
self.currentLocation.textColor = [UIColor colorWithWhite:1.0 alpha:1.0]; |
self.currentLocation.text = locationDescription; |
} |
@end |
Copyright © 2014 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2014-09-17