objc_hacks icon indicating copy to clipboard operation
objc_hacks copied to clipboard

Method swizzling results in "method not found for originalSomeMethod"

Open silverjam opened this issue 7 years ago • 1 comments

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

silverjam avatar Aug 24 '17 02:08 silverjam

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).

jsbain avatar Aug 24 '17 17:08 jsbain