react-native
react-native copied to clipboard
dispatch_queue_t DISPATCH_QUEUE_SERIAL in react native ios project objective-C not working
Description
I want to call a delegate method of class AVCaptureMetadataOutput
. Implementation as below,
//Protocol inheritance
@interface QRScannerVC : UIViewController<AVCaptureMetadataOutputObjectsDelegate>{
//Code of delegate assignment of AVCaptureMetadataOutput
capturedMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_captureSession addOutput:capturedMetadataOutput];
capturedMetadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
dispatch_queue_t dispatchQueue = dispatch_queue_create("qrQueue", DISPATCH_QUEUE_SERIAL);
//Delegate method assignment
[capturedMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
Delegate method,
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
if (metadataObjects != nil && metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
if ([[metadataObject type] isEqualToString:AVMetadataObjectTypeQRCode]) {
[_labelStatus performSelectorOnMainThread:@selector(setText:) withObject:[metadataObject stringValue] waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
}
}
As per apple documentation capturedMetadataOutput:setMetadataObjectsDelegate:queue
method must be call on the serial queue for continuous streaming. And as per react native documentation we can invoke our method if operation take long time to complete.
But in my case capturedMetadataOutput:setMetadataObjectsDelegate:queue
method not calling. If i use same code in pure iOS native Objective-C project then it will works good.
Doesn't get what is is an issue in React native.
Mac os version - Ventura 13.5, Apple M2 XCode version - 14.3.1
React Native Version
0.72.6
Output of npx react-native info
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
method not calling after the camera launch and QR code scanning.
Steps to reproduce
- Create a react library using https://github.com/callstack/react-native-builder-bob (Turbo and Fabric both I tried.)
- Add AVFoundation camera functionality in the iOS code given in the query.
- Configure the above lib in your react native code or in the example given when created by RN bob builder.
- Run code on iOS device
- After camera lunch try to scan QR code image.
Snack, screenshot, or link to a repository
There is only live camera view.
:warning: | Missing Reproducible Example |
---|---|
:information_source: | We could not detect a reproducible example in your issue report. Please provide either:
|
@rajendrabhole Hi try to use somethink like that
you native module
- (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); }
....... setMetadataObjectsDelegate: (NSOperationQueue *)[NSOperationQueue currentQueue] ......
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This issue was closed because it has been stalled for 7 days with no activity.
@cortinico
There is any update? Is there any option to interact with the UI thread from Turbo modules (new architecture)? https://reactnative.dev/docs/native-modules-ios#threading
I can see its deprecated:
`/**
- This property is deprecated. This selector used to support two functionalities.
-
- Providing a queue to do additional async work.
- Instead of synthesizing this selector, retrieve a queue from GCD to do any asynchronous work.
- Example: _myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
-
- Overriding this in order to run all the module's methods on a specific queue, usually main.
- Instead of overriding this, directly dispatch the code onto main queue when necessary.
- Example: dispatch_async(dispatch_get_main_queue, ^{ ... }); */ @property (nonatomic, strong, readonly) dispatch_queue_t methodQueue RCT_DEPRECATED;`
@DanielFrTB, I got the solution. Actually, we need to understand deep level of working of React Native with native, in other words understanding of architecture and data structure. Read selected para from below image,
So in my case AVCaptureSession
, AVCaptureMetadataOutput
, AVCaptureMetadataOutputDelegate
are running separate queue's. Of course, your code running without crashing but delegates doesn't call because for seperate queue allocation. So the solution would be all your code stuff come under a queue, when your camera detected any QR code then the delegate method should call inside the same queue where your camera session was executed.