From 7a94ac3f1da37263cc53ff16d24ef55d2679508c Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 4 Oct 2023 16:26:58 -0700 Subject: [PATCH] dispatch async RCTNetworking methods (#39761) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39761 Changelog: [Internal] as part of the sync void tm methods test, there are some modules that do not behave correctly when trying to execute their methods on the js thread. to maintain the old behavior, we dispatch them explicitly in the implementation. Reviewed By: mdvacca Differential Revision: D49693966 fbshipit-source-id: 870118d0aeb5cfb4155eebf6afa7dfc724d4cecc --- .../Libraries/Network/RCTNetworking.mm | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/packages/react-native/Libraries/Network/RCTNetworking.mm b/packages/react-native/Libraries/Network/RCTNetworking.mm index 4e78d8e798e..7abc90d75c2 100644 --- a/packages/react-native/Libraries/Network/RCTNetworking.mm +++ b/packages/react-native/Libraries/Network/RCTNetworking.mm @@ -700,49 +700,64 @@ RCT_EXPORT_METHOD(sendRequest : (JS::NativeNetworkingIOS::SpecSendRequestQuery &)query callback : (RCTResponseSenderBlock)responseSender) { - NSDictionary *queryDict = @{ - @"method" : query.method(), - @"url" : query.url(), - @"data" : query.data(), - @"headers" : query.headers(), - @"responseType" : query.responseType(), - @"incrementalUpdates" : @(query.incrementalUpdates()), - @"timeout" : @(query.timeout()), - @"withCredentials" : @(query.withCredentials()), - }; + NSString *method = query.method(); + NSString *url = query.url(); + id data = query.data(); + id headers = query.headers(); + NSString *queryResponseType = query.responseType(); + bool queryIncrementalUpdates = query.incrementalUpdates(); + double timeout = query.timeout(); + bool withCredentials = query.withCredentials(); - // TODO: buildRequest returns a cancellation block, but there's currently - // no way to invoke it, if, for example the request is cancelled while - // loading a large file to build the request body - [self buildRequest:queryDict - completionBlock:^(NSURLRequest *request) { - NSString *responseType = [RCTConvert NSString:queryDict[@"responseType"]]; - BOOL incrementalUpdates = [RCTConvert BOOL:queryDict[@"incrementalUpdates"]]; - [self sendRequest:request - responseType:responseType - incrementalUpdates:incrementalUpdates - responseSender:responseSender]; - }]; + dispatch_async(_methodQueue, ^{ + NSDictionary *queryDict = @{ + @"method" : method, + @"url" : url, + @"data" : data, + @"headers" : headers, + @"responseType" : queryResponseType, + @"incrementalUpdates" : @(queryIncrementalUpdates), + @"timeout" : @(timeout), + @"withCredentials" : @(withCredentials), + }; + + // TODO: buildRequest returns a cancellation block, but there's currently + // no way to invoke it, if, for example the request is cancelled while + // loading a large file to build the request body + [self buildRequest:queryDict + completionBlock:^(NSURLRequest *request) { + NSString *responseType = [RCTConvert NSString:queryDict[@"responseType"]]; + BOOL incrementalUpdates = [RCTConvert BOOL:queryDict[@"incrementalUpdates"]]; + [self sendRequest:request + responseType:responseType + incrementalUpdates:incrementalUpdates + responseSender:responseSender]; + }]; + }); } RCT_EXPORT_METHOD(abortRequest : (double)requestID) { - [_tasksByRequestID[[NSNumber numberWithDouble:requestID]] cancel]; - [_tasksByRequestID removeObjectForKey:[NSNumber numberWithDouble:requestID]]; + dispatch_async(_methodQueue, ^{ + [self->_tasksByRequestID[[NSNumber numberWithDouble:requestID]] cancel]; + [self->_tasksByRequestID removeObjectForKey:[NSNumber numberWithDouble:requestID]]; + }); } RCT_EXPORT_METHOD(clearCookies : (RCTResponseSenderBlock)responseSender) { - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if (!storage.cookies.count) { - responseSender(@[ @NO ]); - return; - } + dispatch_async(_methodQueue, ^{ + NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + if (!storage.cookies.count) { + responseSender(@[ @NO ]); + return; + } - for (NSHTTPCookie *cookie in storage.cookies) { - [storage deleteCookie:cookie]; - } - responseSender(@[ @YES ]); + for (NSHTTPCookie *cookie in storage.cookies) { + [storage deleteCookie:cookie]; + } + responseSender(@[ @YES ]); + }); } - (std::shared_ptr)getTurboModule: