objc_hacks
objc_hacks copied to clipboard
Method swizzling results in "method not found for originalSomeMethod"
Hi, I'm attempting to use the method swizzling in swizzle.py and I'm see that attempting to call the original method results in the following error (this happens with trying the test code in the main block as well as in my own test):
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 234, in 'calling callback function'
File "/private/var/mobile/Containers/Shared/AppGroup/74CC34ED-493E-431F-9C45-5BD2EF3B2AE0/Pythonista3/Documents/firebaseapp/swizzle.py", line 146, in saveData
File "/var/containers/Bundle/Application/71C9338F-1BD7-4D52-9DAD-EE24DDF5139E/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 796, in __call__
method_name, kwarg_order = resolve_instance_method(obj, self.name, args, kwargs)
File "/var/containers/Bundle/Application/71C9338F-1BD7-4D52-9DAD-EE24DDF5139E/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 403, in resolve_instance_method
raise AttributeError('No method found for %s' % (name,))
AttributeError: No method found for originalsaveData
Ok, in this case the problem is caused because we are actually swizzling NSKVONotifying_PA2UniversalTextEditorViewController, but when switching spps, what gets sent in is a PA2UniversalTextEditorViewController, which does not have that method.
The simplest fix for this specific use case is to swizzle the original class, not the subclass.
cls=ObjCInstance(ObjCClass('PA2UniversalTextEditorViewController').ptr)
swizzle(cls,'saveData',saveData)
A more generic fix might be to store the original imp somewhere, like attached to few_func, so that it could be called as saveData.original(_self,__sel).