Closed LeoNatan closed 3 years ago
Ok, I will split the relevant code.
I have moved the network to it's own class, so we are not confused with the app delegate. Here is a method description of the network delegate without flipper:
(lldb) po [self _methodDescription]
<LNNetworkDelegateAndInitiator(__detox_sync_URLSessionDelegateProxy): 0x600001128900>:
in LNNetworkDelegateAndInitiator(__detox_sync_URLSessionDelegateProxy):
Instance Methods:
- (void) __dtx_canaryInTheCoalMine___detox_sync_URLSessionDelegateProxy; (0x105b270a8)
- (void) URLSession:(id)arg1 dataTask:(id)arg2 didReceiveResponse:(id)arg3 completionHandler:(^block)arg4; (0x101fbdb00)
- (void) URLSession:(id)arg1 task:(id)arg2 didCompleteWithError:(id)arg3; (0x101fbdf10)
in LNNetworkDelegateAndInitiator:
Properties:
@property (readonly) unsigned long hash;
@property (readonly) Class superclass;
@property (readonly, copy) NSString* description;
@property (readonly, copy) NSString* debugDescription;
Instance Methods:
- (id) init; (0x101fc02d0)
- (void) .cxx_destruct; (0x101fc06f0)
- (void) start; (0x101fc03d0)
- (void) URLSession:(id)arg1 task:(id)arg2 didCompleteWithError:(id)arg3; (0x101fc0630)
- (void) URLSession:(id)arg1 dataTask:(id)arg2 didReceiveResponse:(id)arg3 completionHandler:(^block)arg4; (0x101fc0470)
- (void) URLSession:(id)arg1 dataTask:(id)arg2 didReceiveData:(id)arg3; (0x101fc0570)
in NSObject:
...
As you can see, the object implements - (void) URLSession:(id)arg1 dataTask:(id)arg2 didReceiveData:(id)arg3; (0x101fc0570)
. However, if I enable flipper, that method is no longer called.
Here is the new project: IsolatedSwizzles.zip
Check out DetoxSwizzling.m
for the swizzles.
As you can see from the method description, all the Detox swizzles do is to dynamically create the LNNetworkDelegateAndInitiator(__detox_sync_URLSessionDelegateProxy)
class, which is a subclass of LNNetworkDelegateAndInitiator
, and add three functions. The original class remains intact, no method of that class is actually swizzled, and yet, the didReceiveData:
method is not called correctly with flipper.
I suspect that flipper is failing to support dynamic classes, and thus is unable to figure out that the object responds to that method. Now that you have fixed _methodDescription
on your end, try looking at what flipper/Flex sees.
@LeoNatan , I have updated the PR which fixes all the issue. You can try out the changes and confirm if it works. Copy paste the change in your xcworkspace. Let me know if it fixes.
Guys, should I close the issue? Or you can, as it is now solved in the PR. Thanks
🐛 Bug Report
The iOS network observer has thoroughly broken swizzling; when it calls the original delegate method, it sends the incorrect selector, causing errors
_cmd
here is incorrect. It should beURLSession:dataTask:didReceiveResponse:completionHandler:
, but as you see, it's something else. This is broken behavior, and breaks code that use the well known pattern[proxyObj respondsToSelector:_cmd]
.To Reproduce
Put a breakpoint in any
NSURLSession
delegate method. Print_cmd
.Environment
iOS 13.5 and iOS 14.2