1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#import "EXVersionedNetworkInterceptor.h" 4 5#import <React/RCTHTTPRequestHandler.h> 6#import <React/RCTInspector.h> 7#import <React/RCTInspectorPackagerConnection.h> 8#import <SocketRocket/SRWebSocket.h> 9 10#import "ExpoModulesCore-Swift.h" 11 12#pragma mark - RCTInspectorPackagerConnection category interface 13 14@interface RCTInspectorPackagerConnection(sendWrappedEventToAllPages) 15 16- (BOOL)isReadyToSend; 17- (void)sendWrappedEventToAllPages:(NSString *)event; 18 19@end 20 21#pragma mark - 22 23@interface EXVersionedNetworkInterceptor () <EXRequestCdpInterceptorDelegate> 24 25@property (nonatomic, strong) RCTInspectorPackagerConnection *inspectorPackgerConnection; 26 27@end 28 29@implementation EXVersionedNetworkInterceptor 30 31- (instancetype)initWithRCTInspectorPackagerConnection:(RCTInspectorPackagerConnection *)inspectorPackgerConnection 32{ 33 if (self = [super init]) { 34 self.inspectorPackgerConnection = inspectorPackgerConnection; 35 [EXRequestCdpInterceptor.shared setDelegate:self]; 36 37 Class requestInterceptorClass = [EXRequestInterceptorProtocol class]; 38 RCTSetCustomNSURLSessionConfigurationProvider(^{ 39 NSURLSessionConfiguration *urlSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 40 NSMutableArray<Class> *protocolClasses = [urlSessionConfiguration.protocolClasses mutableCopy]; 41 if (![protocolClasses containsObject:requestInterceptorClass]) { 42 [protocolClasses insertObject:requestInterceptorClass atIndex:0]; 43 } 44 urlSessionConfiguration.protocolClasses = protocolClasses; 45 46 [urlSessionConfiguration setHTTPShouldSetCookies:YES]; 47 [urlSessionConfiguration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; 48 [urlSessionConfiguration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; 49 return urlSessionConfiguration; 50 }); 51 } 52 return self; 53} 54 55- (void)dealloc 56{ 57 [EXRequestCdpInterceptor.shared setDelegate:nil]; 58} 59 60#pragma mark - EXRequestCdpInterceptorDelegate implementations 61 62- (void)dispatch:(NSString * _Nonnull)event { 63 [self.inspectorPackgerConnection sendWrappedEventToAllPages:event]; 64} 65 66@end 67 68#pragma mark - RCTInspectorPackagerConnection category 69 70@interface RCTInspectorPackagerConnection(sendWrappedEventToAllPages) 71 72- (BOOL)isReadyToSend; 73- (void)sendWrappedEventToAllPages:(NSString *)event; 74 75@end 76 77#pragma mark - RCTInspectorPackagerConnection category implementation 78 79@implementation RCTInspectorPackagerConnection(sendWrappedEventToAllPages) 80 81- (BOOL)isReadyToSend 82{ 83 if ([self isConnected]) { 84 return YES; 85 } 86 87 SRWebSocket *websocket = [self valueForKey:@"_webSocket"]; 88 return websocket.readyState == SR_OPEN; 89} 90 91- (void)sendWrappedEventToAllPages:(NSString *)event 92{ 93 if (![self isReadyToSend]) { 94 return; 95 } 96 97 SEL selector = NSSelectorFromString(@"sendWrappedEvent:message:"); 98 if ([self respondsToSelector:selector]) { 99 IMP sendWrappedEventIMP = [self methodForSelector:selector]; 100 void (*functor)(id, SEL, NSString *, NSString *) = (void *)sendWrappedEventIMP; 101 for (RCTInspectorPage* page in RCTInspector.pages) { 102 if (![page.title containsString:@"Reanimated"]) { 103 functor(self, selector, [@(page.id) stringValue], event); 104 } 105 } 106 } 107} 108 109@end 110