@@ -139,11 +139,9 @@ - (BOOL)popoverSupported
139139- (void )takePicture : (CDVInvokedUrlCommand*)command
140140{
141141 self.hasPendingOperation = YES ;
142-
143142 __weak CDVCamera* weakSelf = self;
144143
145144 [self .commandDelegate runInBackground: ^{
146-
147145 CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments: command];
148146 pictureOptions.popoverSupported = [weakSelf popoverSupported ];
149147 pictureOptions.usesGeolocation = [weakSelf usesGeolocation ];
@@ -158,82 +156,72 @@ - (void)takePicture:(CDVInvokedUrlCommand*)command
158156 }
159157
160158 // Validate the app has permission to access the camera
161- if (pictureOptions.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice respondsToSelector: @selector (authorizationStatusForMediaType: )]) {
162- AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType: AVMediaTypeVideo];
163- if (authStatus == AVAuthorizationStatusDenied ||
164- authStatus == AVAuthorizationStatusRestricted) {
165- // If iOS 8+, offer a link to the Settings app
166- #pragma clang diagnostic push
167- #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
168- NSString * settingsButton = (&UIApplicationOpenSettingsURLString != NULL )
169- ? NSLocalizedString(@" Settings" , nil )
170- : nil ;
171- #pragma clang diagnostic pop
172-
173- // Denied; show an alert
174- dispatch_async (dispatch_get_main_queue (), ^{
175- [[[UIAlertView alloc ] initWithTitle: [[NSBundle mainBundle ]
176- objectForInfoDictionaryKey: @" CFBundleDisplayName" ]
177- message: NSLocalizedString(@" Access to the camera has been prohibited; please enable it in the Settings app to continue." , nil )
178- delegate: weakSelf
179- cancelButtonTitle: NSLocalizedString(@" OK" , nil )
180- otherButtonTitles: settingsButton, nil ] show ];
181- });
182- }
159+ if (pictureOptions.sourceType == UIImagePickerControllerSourceTypeCamera) {
160+ [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler: ^(BOOL granted)
161+ {
162+ if (!granted)
163+ {
164+ // Denied; show an alert
165+ dispatch_async (dispatch_get_main_queue (), ^{
166+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle: [[NSBundle mainBundle ] objectForInfoDictionaryKey: @" CFBundleDisplayName" ] message: NSLocalizedString(@" Access to the camera has been prohibited; please enable it in the Settings app to continue." , nil ) preferredStyle: UIAlertControllerStyleAlert];
167+ [alertController addAction: [UIAlertAction actionWithTitle: NSLocalizedString(@" OK" , nil ) style: UIAlertActionStyleDefault handler: ^(UIAlertAction * _Nonnull action) {
168+ [weakSelf sendNoPermissionResult: command.callbackId];
169+ }]];
170+ [alertController addAction: [UIAlertAction actionWithTitle: NSLocalizedString(@" Settings" , nil ) style: UIAlertActionStyleDefault handler: ^(UIAlertAction * _Nonnull action) {
171+ [[UIApplication sharedApplication ] openURL: [NSURL URLWithString: UIApplicationOpenSettingsURLString]];
172+ [weakSelf sendNoPermissionResult: command.callbackId];
173+ }]];
174+ [weakSelf.viewController presentViewController: alertController animated: YES completion: nil ];
175+ });
176+ } else {
177+ [weakSelf showCameraPicker: command.callbackId withOptions: pictureOptions];
178+ }
179+ }];
180+ } else {
181+ [weakSelf showCameraPicker: command.callbackId withOptions: pictureOptions];
183182 }
184-
185- CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions: pictureOptions];
186- weakSelf.pickerController = cameraPicker;
187-
188- cameraPicker.delegate = weakSelf;
189- cameraPicker.callbackId = command.callbackId ;
190- // we need to capture this state for memory warnings that dealloc this object
191- cameraPicker.webView = weakSelf.webView ;
192-
193- // Perform UI operations on the main thread
194- dispatch_async (dispatch_get_main_queue (), ^{
195- // If a popover is already open, close it; we only want one at a time.
196- if (([[weakSelf pickerController ] pickerPopoverController ] != nil ) && [[[weakSelf pickerController ] pickerPopoverController ] isPopoverVisible ]) {
197- [[[weakSelf pickerController ] pickerPopoverController ] dismissPopoverAnimated: YES ];
198- [[[weakSelf pickerController ] pickerPopoverController ] setDelegate: nil ];
199- [[weakSelf pickerController ] setPickerPopoverController: nil ];
200- }
201-
202- if ([weakSelf popoverSupported ] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
203- if (cameraPicker.pickerPopoverController == nil ) {
204- cameraPicker.pickerPopoverController = [[NSClassFromString (@" UIPopoverController" ) alloc ] initWithContentViewController: cameraPicker];
205- }
206- [weakSelf displayPopover: pictureOptions.popoverOptions];
207- weakSelf.hasPendingOperation = NO ;
208- } else {
209- cameraPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
210- [weakSelf.viewController presentViewController: cameraPicker animated: YES completion: ^{
211- weakSelf.hasPendingOperation = NO ;
212- }];
213- }
214- });
215183 }];
216184}
217185
218- // Delegate for camera permission UIAlertView
219- - (void )alertView : (UIAlertView *)alertView clickedButtonAtIndex : (NSInteger )buttonIndex
186+ - (void )showCameraPicker : (NSString *)callbackId withOptions : (CDVPictureOptions *) pictureOptions
220187{
221- // If Settings button (on iOS 8), open the settings app
222- if (buttonIndex == 1 ) {
223- #pragma clang diagnostic push
224- #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
225- if (&UIApplicationOpenSettingsURLString != NULL ) {
226- [[UIApplication sharedApplication ] openURL: [NSURL URLWithString: UIApplicationOpenSettingsURLString]];
188+ CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions: pictureOptions];
189+ self.pickerController = cameraPicker;
190+
191+ cameraPicker.delegate = self;
192+ cameraPicker.callbackId = callbackId;
193+ // we need to capture this state for memory warnings that dealloc this object
194+ cameraPicker.webView = self.webView ;
195+
196+ // Perform UI operations on the main thread
197+ dispatch_async (dispatch_get_main_queue (), ^{
198+ // If a popover is already open, close it; we only want one at a time.
199+ if (([[self pickerController ] pickerPopoverController ] != nil ) && [[[self pickerController ] pickerPopoverController ] isPopoverVisible ]) {
200+ [[[self pickerController ] pickerPopoverController ] dismissPopoverAnimated: YES ];
201+ [[[self pickerController ] pickerPopoverController ] setDelegate: nil ];
202+ [[self pickerController ] setPickerPopoverController: nil ];
227203 }
228- #pragma clang diagnostic pop
229- }
230204
231- // Dismiss the view
232- [[self .pickerController presentingViewController ] dismissViewControllerAnimated: YES completion: nil ];
205+ if ([self popoverSupported ] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
206+ if (cameraPicker.pickerPopoverController == nil ) {
207+ cameraPicker.pickerPopoverController = [[NSClassFromString (@" UIPopoverController" ) alloc ] initWithContentViewController: cameraPicker];
208+ }
209+ [self displayPopover: pictureOptions.popoverOptions];
210+ self.hasPendingOperation = NO ;
211+ } else {
212+ cameraPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
213+ [self .viewController presentViewController: cameraPicker animated: YES completion: ^{
214+ self.hasPendingOperation = NO ;
215+ }];
216+ }
217+ });
218+ }
233219
220+ - (void )sendNoPermissionResult : (NSString *)callbackId
221+ {
234222 CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_ERROR messageAsString: @" has no access to camera" ]; // error callback expects string ATM
235223
236- [self .commandDelegate sendPluginResult: result callbackId: self .pickerController. callbackId];
224+ [self .commandDelegate sendPluginResult: result callbackId: callbackId];
237225
238226 self.hasPendingOperation = NO ;
239227 self.pickerController = nil ;
0 commit comments