react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

🐛 Using callback (RCTResponseSenderBlock) as an argument in a frame processor

Open peterzadori opened this issue 2 years ago • 3 comments

What were you trying to do?

Hello

I'm having issues using callbacks as arguments for my exported function.

I would like to use something like this in my frame processor:

__detectRectangles(frame, (result, error) => { // callback });

However, I don't know how to cast the arguments into RCTResponseSenderBlock or how to call the callback from my Swfit code.

Reproduceable Code

No response

What happened instead?

Can't call provided callback

Relevant log output

No response

Device

iOS

VisionCamera Version

2.13.3

Additional information

peterzadori avatar Aug 04 '22 18:08 peterzadori

Everything should be synchronous, callbacks will introduce async callback hell. I think it would be possible to support them though if really needed

mrousavy avatar Aug 05 '22 07:08 mrousavy

You can do it in Objective-C. I tried with React Native 0.69 and OK.

@implementation YourProcessor

+ (void)asyncProcessFrame:(Frame * _Nonnull)frame args:(NSArray * _Nonnull)args callback:(void (^ _Nonnull)(NSDictionary<NSString *, id> * _Nullable, NSError * _Nullable))callback 
{
   /* async operation */
   /* ... */
   callback(dict, [NSNull null]);
}

static inline id processFrame(Frame* frame, NSArray* args) {
    
    RCTResponseSenderBlock responseSender = args[1];
    
    [YourProcessor asyncProcessFrame:frame args:args callback:^(NSDictionary<NSString *,id> * _Nullable result, NSError * _Nullable error) {
        
        responseSender(@[
            error != nil ? error : [NSNull null],
            result != nil ? result : [NSNull null]
        ]);
        
    }];
    
    return @[];
}

VISION_EXPORT_FRAME_PROCESSOR(processFrame)

@end


eddy-lau avatar Aug 06 '22 00:08 eddy-lau

You can do it in Objective-C. I tried with React Native 0.69 and OK.

@implementation YourProcessor

+ (void)asyncProcessFrame:(Frame * _Nonnull)frame args:(NSArray * _Nonnull)args callback:(void (^ _Nonnull)(NSDictionary<NSString *, id> * _Nullable, NSError * _Nullable))callback 
{
   /* async operation */
   /* ... */
   callback(dict, [NSNull null]);
}

static inline id processFrame(Frame* frame, NSArray* args) {
    
    RCTResponseSenderBlock responseSender = args[1];
    
    [YourProcessor asyncProcessFrame:frame args:args callback:^(NSDictionary<NSString *,id> * _Nullable result, NSError * _Nullable error) {
        
        responseSender(@[
            error != nil ? error : [NSNull null],
            result != nil ? result : [NSNull null]
        ]);
        
    }];
    
    return @[];
}

VISION_EXPORT_FRAME_PROCESSOR(processFrame)

@end

Thanks, I'm going to try this and report back

peterzadori avatar Aug 06 '22 09:08 peterzadori

Hey - callbacks don't really make sense here as FPs are synchronous. You can't really have long running tasks here, this will just stall the Camera

mrousavy avatar Sep 30 '23 09:09 mrousavy