0

I have a framework where I have to send the captured image back to the callee. So I have to wait for the delegate to finish

I am using dispatch_asyc to wait for the async operation of the delegate method.

But the delegate method is not called and the application is stuck NSLog(@"dispatch_get_global_queue"); here.

I have added my code below. Please help

NoPreviewCamera.h

#import <AVFoundation/AVFoundation.h>



NS_ASSUME_NONNULL_BEGIN

@interface NoPreviewCamera : NSObject <AVCapturePhotoCaptureDelegate>

@end

static NoPreviewCamera *noPreviewCamera = nil;
static NSString *imageDataBase64 = nil;
static dispatch_group_t group = nil;


NS_ASSUME_NONNULL_END

NoPreviewCamera.m


#import "NoPreviewCamera.h"
AVCaptureSession *captureSession;
AVCapturePhotoOutput *photoOutput;
AVCapturePhotoSettings *photoSetting;
AVCaptureConnection *captureConnection;
id<AVCapturePhotoCaptureDelegate> avCaptureDelegate;

@interface NoPreviewCamera ()

@end

@implementation NoPreviewCamera

+ (void) initCaptureSession {
    captureSession = [[AVCaptureSession alloc] init];
    
    if([captureSession canSetSessionPreset: AVCaptureSessionPresetPhoto] ) {
        [captureSession setSessionPreset:AVCaptureSessionPresetPhoto];
    }
    
    [captureSession startRunning];
}

+ (void) setNewPhotoSetting {
    photoSetting = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey : AVVideoCodecTypeJPEG}];
    [photoOutput setPhotoSettingsForSceneMonitoring:photoSetting];
}


+ (void) initInputDevice: (AVCaptureDevice *) inputDevice {
    AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:inputDevice error:nil];
    if ([captureSession canAddInput:deviceInput]) {
        [captureSession addInput:deviceInput];
    }
}

+ (void) initOuput {
    photoOutput = [[AVCapturePhotoOutput alloc] init];
    if ([captureSession canAddOutput:photoOutput]) {
        [captureSession addOutput:photoOutput];
    }
}

+ (AVCaptureDevice *) frontFacingCameraIfAvailable {
    AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
    NSArray *captureDevices = [captureDeviceDiscoverySession devices];
    if (!captureDevices || !captureDevices[0]){
        return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    } else {
        return captureDevices[0];
    }
}

+ (NSString *) takePictureWithNoPreviewFrontFacingCamera {
    NSLog(@"NoPreviewCameraNoPreviewCameraNoPreviewCameraNoPreviewCamera");
    
    
    noPreviewCamera = [[NoPreviewCamera alloc]init];
    [NoPreviewCamera initCaptureSession];
    [NoPreviewCamera initInputDevice:[NoPreviewCamera frontFacingCameraIfAvailable]];
    [NoPreviewCamera initOuput];
    [NoPreviewCamera setNewPhotoSetting];
    captureConnection = nil;
    for (AVCaptureConnection *connection in photoOutput.connections) {
        for (AVCaptureInputPort *port in [connection inputPorts]) {
            if ([[port mediaType] isEqual: AVMediaTypeVideo]) {
                captureConnection = connection;
                break;
            }
        }
        if (captureConnection) {
            break;
        }
    }
    
    [NoPreviewCamera getOutputPhoto:^(BOOL success) {
        NSLog(@"FINNNNNENENEENENENEN %o", success );
    }];
    
    return imageDataBase64;
}

+ (void)getOutputPhoto:(void (^) (BOOL success))completion
{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
        noPreviewCamera = [[NoPreviewCamera alloc]init];
        [photoOutput capturePhotoWithSettings:photoSetting delegate:noPreviewCamera];
        NSLog(@"dispatch_get_global_queue");
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"dispatch_get_main_queue");
            completion(true);
            dispatch_group_leave(group);
        });
    });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}


- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(nullable NSError *)error
{
    NSLog(@"image delegate");
    NSData *imageData = [photo fileDataRepresentation];
    imageDataBase64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSLog(@"image captured");
}

- (void)captureOutput:(AVCapturePhotoOutput *)output didCapturePhotoForResolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings {
    NSLog(@"Finised");
}

@end
Kuldeep Bhimte
  • 961
  • 1
  • 10
  • 25

1 Answers1

0

As I see you creating instance of NoPreviewCamera inside a static method of this class. And setting this instance as delegate. And this "instance" is static property as well. And after you expecting this to call instance methods.

Try to drop it to heap instead. Make it an object with some reference to.