A while back I asked similar question here: Difference requiresMainQueueSetup and dispatch_get_main_queue?
I came back to it today and realised I did not grasp it completely yet. When we are writing react native modules for iOS there is dispatch_get_main_queue
on ios side and requiresMainQueueSetup
needed by react-native.
How and which one of these should be used for following packages and use cases?
asq-react-native-device - package that exports constants like bundle id
asq-react-native-sensors - package that allows to subscribe and receive data from device gyroscope and oher sensors
asq-react-native-google-sign-in - package tat exposes google sign in sdk
For all of these I receive warnings in my dev console i.e.
So I assume requiresMainQueueSetup
needs to be used regardless for all packages? I struggle to grasp when it needs to be set to YES
or NO
however. None of the modules are ui components, google sign in one, however, opens up safari view controller to perform oAuth, does this mean value needs to be set to YES
here?
Do I need to use dispatch_get_main_queue
whenever I use any of react-native resolver / rejecter bridge methods?
While both methods are related to the way that RN interacts with your module, they are not the same.
+ (BOOL)requiresMainQueueSetup
This method determines if your module will be initialized on the main thread or not; in other words, if your module's constructor (init
method) and the constantsToExport
method will be called on the main thread.
- (dispatch_queue_t)methodQueue
This method is an override where you can tell RN which dispatch queue to use when calling your module's exported methods (exported using the RCT_EXPORT_METHOD
macro). Returning dispatch_get_main_queue()
here returns the main queue which belongs to the main thread, asking RN to invoke your exported methods on the main thread, but you can use any other custom dispatch queue if you have such requirement.
If we're to simplify this, any operation that involves UI manipulation is required to be executed on the main thread or main dispatch queue. Even if your modules are not UI components there are other UI operations that can be executed from native modules, for example: presenting a view-controller (can be a system view-controller or a custom one)
As you see, all the warning that you get originate from the lack of requiresMainQueueSetup
implementation, and it tells you the exact reason - a module is overriding the init
or the constantsToExport
method but doesn't specify if it wishes for it to be executed on the main thread. Up until now, modules that were overriding the init
or the constantsToExport
were initialized on the main thread by default, assuming that they might need access to UI elements or UIKit
. In future RN versions this is going to change - these methods will get called on the main thread only if you explicitly say so.
It doesn't look like you're doing something in your init
or constantsToExport
that requires the main thread, but at the moment it's as if you are overriding requiresMainQueueSetup
and returning YES
. I recommend that you do override it and return NO, so you can test that everything works as expected and make sure that you won't have any surprises when RN defaults to this in your case in future RN versions.
Notice that even though these are not UI components, you sometimes do need the main thread when exported methods are called, like in asq-react-native-google-sign-in
- the signIn
methods are presenting and dismissing view-controllers. In this case you correctly override methodQueue
and use the main queue for your exported methods.
Note that it's also possible to keep the method calls in RN background threads by not overriding methodQueue
, and dispatch to the main queue yourself when necessary. For example:
dispatch_async(dispatch_get_main_queue(), ^{
[RCTPresentedViewController() dismissViewControllerAnimated:YES completion:nil];
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With