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