Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Catalyst][RxCocoa] RxSearchBarDelegateProxy unrecognized selector #2161

Closed
5 of 17 tasks
taher-mosbah opened this issue Apr 1, 2020 · 14 comments
Closed
5 of 17 tasks

Comments

@taher-mosbah
Copy link

Short description of the issue:

RxSearchBarDelegateProxy not working on Catalyst.

2020-04-01 09:52:07.545777+0200 App[3676:38433] -[RxCocoa.RxSearchBarDelegateProxy searchBarTextDidBeginEditing:]: unrecognized selector sent to instance 0x6000026eb4e0
2020-04-01 09:52:07.546230+0200 App[3676:38433] [General] -[RxCocoa.RxSearchBarDelegateProxy searchBarTextDidBeginEditing:]: unrecognized selector sent to instance 0x6000026eb4e0
2020-04-01 09:52:07.557947+0200 App[3676:38433] [General] (
	0   CoreFoundation                      0x00007fff35f61d07 __exceptionPreprocess + 250
	1   libobjc.A.dylib                     0x00007fff6ec865bf objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff35fe0c97 -[NSObject(NSObject) __retain_OA] + 0
	3   CoreFoundation                      0x00007fff35ec657b ___forwarding___ + 1427
	4   CoreFoundation                      0x00007fff35ec5f58 _CF_forwarding_prep_0 + 120
	5   UIKitCore                           0x00007fff76bdf411 -[UISearchBar(UISearchBarStatic) _searchFieldBeginEditing] + 80
	6   UIKit                               0x00007fff7017142c -[UISearchBarAccessibility _searchFieldBeginEditing] + 46
	7   UIKitCore                           0x00007fff76a8e3df -[UIApplication sendAction:to:from:forEvent:] + 83
	8   UIKitCore                           0x00007fff76a96f01 -[UIControl sendAction:to:forEvent:] + 241
	9   UIKitCore                           0x00007fff76a94fb1 -[UIControl _sendActionsForEvents:withEvent:] + 410
	10  UIKitCore                           0x00007fff775071e9 -[UITextField _attachFieldEditor] + 668
	11  UIKitCore                           0x00007fff774fee46 -[UITextField _becomeFirstResponder] + 174
	12  UIKitCore                           0x00007fff76be1bb6 -[UISearchTextField _becomeFirstResponder] + 50
	13  UIKitCore                           0x00007fff774fed85 -[UITextField __resumeBecomeFirstResponder] + 27
	14  UIKitCore                           0x00007fff76be1e94 __42-[UISearchTextField _becomeFirstResponder]_block_invoke + 308
	15  UIKitCore                           0x00007fff76be1d5e -[UISearchTextField _becomeFirstResponder] + 474
	16  UIKitCore                           0x00007fff768bfd29 -[UIResponder becomeFirstResponder] + 703
	17  UIKit                               0x00007fff700e25d6 -[UITextInputUIResponderAccessibility becomeFirstResponder] + 44
	18  UIKitCore                           0x00007fff768f7116 -[UIView(Hierarchy) becomeFirstResponder] + 84
	19  UIKitCore                           0x00007fff774fdfbc -[UITextField becomeFirstResponder] + 188
	20  UIKitCore                           0x00007fff76bdfaa2 -[UISearchBar(UISearchBarStatic) becomeFirstResponder] + 48
	21  UIKitCore                           0x00007fff76a599da -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 44
	22  UIKitCore                           0x00007fff76a5985b _UIGestureRecognizerSendTargetActions + 109
	23  UIKitCore                           0x00007fff76a595aa _UIGestureRecognizerSendActions + 329
	24  UIKitCore                           0x00007fff76fa050b -[UIGestureRecognizer _updateGestureForActiveEvents] + 735
	25  UIKitCore                           0x00007fff7678ce6e _UIGestureEnvironmentUpdate + 2788
	26  UIKitCore                           0x00007fff76a52da8 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 467
	27  UIKitCore                           0x00007fff76a5267c -[UIGestureEnvironment _updateForEvent:window:] + 200
	28  UIKitCore                           0x00007fff76a52226 -[UIWindow sendEvent:] + 4417
	29  UIKitCore                           0x00007fff76a5053f -[UIApplication sendEvent:] + 364
	30  UIKit                               0x00007fff70106941 -[UIApplicationAccessibility sendEvent:] + 85
	31  UIKitCore                           0x00007fff76a4e8f4 __dispatchPreprocessedEventFromEventQueue + 7416
	32  UIKitCore                           0x00007fff76922975 __handleEventQueueInternal + 6306
	33  UIKitCore                           0x00007fff76920aa1 __handleHIDEventFetcherDrain + 130
	34  CoreFoundation                      0x00007fff35ee5f12 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	35  CoreFoundation                      0x00007fff35ee5eb1 __CFRunLoopDoSource0 + 103
	36  CoreFoundation                      0x00007fff35ee5ccb __CFRunLoopDoSources0 + 209
	37  CoreFoundation                      0x00007fff35ee49fa __CFRunLoopRun + 927
	38  CoreFoundation                      0x00007fff35ee3ffe CFRunLoopRunSpecific + 462
	39  HIToolbox                           0x00007fff34b17abd RunCurrentEventLoopInMode + 292
	40  HIToolbox                           0x00007fff34b176f4 ReceiveNextEventCommon + 359
	41  HIToolbox                           0x00007fff34b17579 _BlockUntilNextEventMatchingListInModeWithFilter + 64
	42  AppKit                              0x00007fff33162c99 _DPSNextEvent + 883
	43  AppKit                              0x00007fff331614e0 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
	44  AppKit                              0x00007fff331531ee -[NSApplication run] + 658
	45  AppKit                              0x00007fff33124ff6 NSApplicationMain + 777
	46  AppKit                              0x00007fff33446a85 _NSApplicationMainWithInfoDictionary + 16
	47  UIKitMacHelper                      0x00007fff67090e00 UINSApplicationMain + 322
	48  UIKitCore                           0x00007fff767776ff UIApplicationMain + 2130
	49  App                                 0x000000010001ee44 main + 372
	50  libdyld.dylib                       0x00007fff6fe2dcc9 start + 1

Expected outcome:
Delegate methods should work like on iOS as it is marked as available on Catalyst on Apple documentation.

What actually happens:

The app crashs with unrecognized selector sent to instance

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

RxSwift 5.5.1

Platform/Environment

  • iOS
  • macOS
  • tvOS
  • watchOS
  • playgrounds

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • easy, 100% repro
  • sometimes, 10%-100%
  • hard, 2% - 10%
  • extremely hard, %0 - 2%

Xcode version:

11.3.1

Installation method:

  • CocoaPods
  • Carthage
  • Git submodules

I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)

  • yes (which ones)
  • no

Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)

  • just starting
  • I have a small code base
  • I have a significant code base
@EricAppel
Copy link

EricAppel commented May 14, 2020

Here's a sample project using Swift Package Manager and RxSwift 5.1.1 that demonstrates the bug. We are not receiving values when subscribing to UISearchBar.rx.value and are experiencing a crash when providing our own delegate for text changes.

CatalystSearch.zip

@freak4pc
Copy link
Member

@EricAppel Thanks for the repro. For now i'd use text instead of value. I'll see if I can debug this.

@freak4pc
Copy link
Member

I actually just ran your project and it works fine for me. That's really strange:

image

@dimitris-c
Copy link

I had a look at this one and it seems to be within the _RXDelegateProxy when collecting void selectors (collectVoidSelectorsForProtocol). While running on iOS the selectors for UISearchBarDelegate were showing up but not when running on Mac Catalyst. And with no call to forwardInvocation on _RXDelegateProxy means sentMessage and methodInvoked will never be called.

I've also run a few other delegate methods like this UITabBarController().rx.delegate.methodInvoked(...).debug().subscribe() to trigger the initialisation of _RXDelegateProxy and it seems the UISearchBar is the only one that's not cooperating...

So maybe this is a Mac Catalyst issue?! not sure...

@tsabend
Copy link

tsabend commented May 15, 2020

@freak4pc did u run for catalyst? that screenshot looks like iOS and the bug only appears on catalyst.

@taher-mosbah
Copy link
Author

@dimitris-c did you see any workarounds maybe ?

@freak4pc
Copy link
Member

Sorry about the confusion. This definitely seems like an issue in Catalyst worth reporting, but I'm not sure where it stems from.

Even the raw version of this doesnt work:

searchBar.rx
    .delegate
    .methodInvoked(#selector(UISearchBarDelegate.searchBar(_:textDidChange:)))

@freak4pc
Copy link
Member

Also, this is specific to UISearchBar, because even when trying other DelegateProxy-using constructs (like NSTextViewStorage, e.g. UITextView) it seems to work just fine even in Catalylst.

@dimitris-c
Copy link

@freak4pc this seems to be an issue with Catalyst, you can read my previous answer to see my findings.

@tsabend
Copy link

tsabend commented May 20, 2020

I'm happy to write or help promote a radar, but I'm not quite sure what the Catalyst issue is.

@dimitris-c
Copy link

Created a small snippet that can be used to see the issue. On Catalyst the objc runtime doesn't seem to pick up the search bar delegate method, changing the UISearchBarDelegate to another delegate prints its declared methods.

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CatalystIssueOnUISearchBar : NSObject
@end

NS_ASSUME_NONNULL_END

CatalystIssueOnUISearchBar.m class

#import "CatalystIssueOnUISearchBar.h"
#import <objc/runtime.h>
#import <UIKit/UIKit.h>

@interface Delegate : NSObject<UISearchBarDelegate>

@end

@implementation Delegate

@end

@implementation CatalystIssueOnUISearchBar

- (instancetype)init
{
    self = [super init];
    if (self) {
        Class targetClass = Delegate.class;
        unsigned int count;
        Protocol *__unsafe_unretained *protocols = class_copyProtocolList(targetClass, &count);
        
        for (unsigned int i = 0; i < count; i++) {
        
            unsigned int protocolMethodCount = 0;
            struct objc_method_description *pMethods = protocol_copyMethodDescriptionList(protocols[i], NO, YES, &protocolMethodCount);
            
            for (unsigned int i = 0; i < protocolMethodCount; ++i) {
                struct objc_method_description method = pMethods[i];
                
                NSLog(@"%@", NSStringFromSelector(method.name));
            }
            
            free(pMethods);
            
        }
        
        free(protocols);
    }
    return self;
}

@end

@tsabend
Copy link

tsabend commented May 22, 2020

Thanks for that @dimitris-c. I made a little swift project that replicates based on that snippet
CatalystProtcolBug.zip

and filed a radar with apple: FB7710557

@freak4pc
Copy link
Member

@tsabend thank you so much ! Would it be worth to also file on bugs.swift.org ?

@freak4pc
Copy link
Member

I'm going to close this one or now.
Even though it's a good reference, unfortunately there's nothing we can do to fix it without Apple's help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants