@@ -38,6 +38,7 @@ @interface RCTWKWebView () <WKNavigationDelegate, RCTAutoInsetsProtocol, WKScrip
3838@property (nonatomic , copy ) RCTDirectEventBlock onUrlChanged;
3939@property (nonatomic , copy ) RCTDirectEventBlock onNavigationResponse;
4040@property (assign ) BOOL sendCookies;
41+ @property (assign ) BOOL useWKCookieStore;
4142@property (nonatomic , strong ) WKUserScript *atStartScript;
4243@property (nonatomic , strong ) WKUserScript *atEndScript;
4344
@@ -348,6 +349,50 @@ - (void)stopLoading
348349 [_webView stopLoading ];
349350}
350351
352+ - (NSString *) cookieDescription : (NSHTTPCookie *)cookie {
353+ NSMutableString *cDesc = [[NSMutableString alloc ] init ];
354+ [cDesc appendFormat: @" %@ =%@ ;" ,
355+ [[cookie name ] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding],
356+ [[cookie value ] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
357+ if ([cookie.domain length ] > 0 )
358+ [cDesc appendFormat: @" domain=%@ ;" , [cookie domain ]];
359+ if ([cookie.path length ] > 0 )
360+ [cDesc appendFormat: @" path=%@ ;" , [cookie path ]];
361+ if (cookie.expiresDate != nil )
362+ [cDesc appendFormat: @" expiresDate=%@ ;" , [cookie expiresDate ]];
363+ if (cookie.HTTPOnly == YES )
364+ [cDesc appendString: @" HttpOnly;" ];
365+ if (cookie.secure == YES )
366+ [cDesc appendString: @" Secure;" ];
367+ return cDesc;
368+ }
369+ - (void ) copyCookies {
370+ NSHTTPCookieStorage * storage = [NSHTTPCookieStorage sharedHTTPCookieStorage ];
371+ NSArray * array = [storage cookies ];
372+ if (@available (ios 11 ,*)) {
373+ // The webView websiteDataStore only gets initialized, when needed. Setting cookies on the dataStore's
374+ // httpCookieStore doesn't seem to initialize it. That's why fetchDataRecordsOfTypes is called.
375+ // All the cookies of the sharedHttpCookieStorage, which is used in react-native-cookie,
376+ // are copied to the webSiteDataStore's httpCookieStore.
377+ // https://bugs.webkit.org/show_bug.cgi?id=185483
378+ [_webView.configuration.websiteDataStore fetchDataRecordsOfTypes: [NSSet <NSString *> setWithObject:WKWebsiteDataTypeCookies ] completionHandler: ^(NSArray <WKWebsiteDataRecord *> *records) {
379+ for (NSHTTPCookie * cookie in array) {
380+ [_webView.configuration.websiteDataStore.httpCookieStore setCookie: cookie completionHandler: nil ];
381+ }
382+ }];
383+ } else {
384+ // Create WKUserScript for each cookie
385+ // Cookies are injected with Javascript AtDocumentStart
386+ for (NSHTTPCookie * cookie in array){
387+ NSString * cookieSource = [NSString stringWithFormat: @" document.cookie = '%@ '" , [self cookieDescription: cookie]];
388+ WKUserScript * cookieScript = [[WKUserScript alloc ]
389+ initWithSource: cookieSource
390+ injectionTime: WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly: NO ];
391+ [_webView.configuration.userContentController addUserScript: cookieScript];
392+ }
393+ }
394+ }
395+
351396- (void )setSource : (NSDictionary *)source
352397{
353398 if (!_webView) {
@@ -358,6 +403,11 @@ - (void)setSource:(NSDictionary *)source
358403 if (![_source isEqualToDictionary: source]) {
359404 _source = [source copy ];
360405 _sendCookies = [source[@" sendCookies" ] boolValue ];
406+ _useWKCookieStore = [source[@" useWKCookieStore" ] boolValue ];
407+ if (_useWKCookieStore) {
408+ [self copyCookies ];
409+ }
410+
361411 if ([source[@" customUserAgent" ] length ] != 0 && [_webView respondsToSelector: @selector (setCustomUserAgent: )]) {
362412 [_webView setCustomUserAgent: source[@" customUserAgent" ]];
363413 }
@@ -512,6 +562,28 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
512562
513563#pragma mark - WKNavigationDelegate methods
514564
565+ - (void )webView : (WKWebView *)webView decidePolicyForNavigationResponse : (WKNavigationResponse *)navigationResponse decisionHandler : (void (^)(WKNavigationResponsePolicy ))decisionHandler {
566+ if (_sendCookies) {
567+ NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response ;
568+ NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields: [response allHeaderFields ] forURL: response.URL];
569+ for (NSHTTPCookie *cookie in cookies) {
570+ [[NSHTTPCookieStorage sharedHTTPCookieStorage ] setCookie: cookie];
571+ }
572+ }
573+ if (_onNavigationResponse) {
574+ NSDictionary *headers = ((NSHTTPURLResponse *)navigationResponse.response ).allHeaderFields ;
575+ NSInteger statusCode = ((NSHTTPURLResponse *)navigationResponse.response ).statusCode ;
576+ NSMutableDictionary <NSString *, id > *event = [self baseEvent ];
577+ [event addEntriesFromDictionary: @{
578+ @" headers" : headers,
579+ @" status" : [NSHTTPURLResponse localizedStringForStatusCode: statusCode],
580+ @" statusCode" : @(statusCode),
581+ }];
582+ _onNavigationResponse (event);
583+ }
584+ decisionHandler (WKNavigationResponsePolicyAllow );
585+ }
586+
515587#if DEBUG
516588- (void )webView : (WKWebView *)webView didReceiveAuthenticationChallenge : (NSURLAuthenticationChallenge *)challenge completionHandler : (void (^)(NSURLSessionAuthChallengeDisposition , NSURLCredential * _Nullable))completionHandler {
517589 NSURLCredential * credential = [[NSURLCredential alloc ] initWithTrust: [challenge protectionSpace ].serverTrust];
@@ -666,22 +738,4 @@ - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
666738 RCTLogWarn (@" Webview Process Terminated" );
667739}
668740
669- - (void )webView : (__unused WKWebView *)webView
670- decidePolicyForNavigationAction : (WKNavigationAction *)navigationAction
671- decisionHandler : (void (^)(WKNavigationActionPolicy ))decisionHandler
672- if (_onNavigationResponse) {
673- NSDictionary *headers = ((NSHTTPURLResponse *)navigationResponse.response ).allHeaderFields ;
674- NSInteger statusCode = ((NSHTTPURLResponse *)navigationResponse.response ).statusCode ;
675- NSMutableDictionary <NSString *, id > *event = [self baseEvent ];
676- [event addEntriesFromDictionary: @{
677- @" headers" : headers,
678- @" status" : [NSHTTPURLResponse localizedStringForStatusCode: statusCode],
679- @" statusCode" : @(statusCode),
680- }];
681- _onNavigationResponse (event);
682- }
683-
684- decisionHandler (WKNavigationResponsePolicyAllow );
685- }
686-
687741@end
0 commit comments