kivy/pyobjus

How to Load Custom Classes for iOS (besides bridge.m)?

evbo opened this issue · 1 comments

evbo commented

According to the documentation for iOS, it is currently possible to:

...add additional bridge methods to your pyobjus iOS app by changing the content of the bridge.m/.h files, or by adding completely new files and classes to your xcode project

I am able to successfully edit the bridge.m file and get expected results. However, when I add a new class (per this documentation demo) in my XCode project (right next to bridge.m and bridge.h), I am not able to load it:

from pyobjus.dylib_manager import load_framework, make_dylib, load_dylib, INCLUDE

make_dylib('objc_lib.m', out='objc_lib.dylib', frameworks=['Foundation'])
load_dylib('objc_lib.dylib') # I also tested just running autoclass without dylib methods before hand
ObjcClass = autoclass('objc_lib')
ObjcClass.alloc().init().printFromObjectiveC()

The error I get when trying to load any other class besides bridge.m is:

YourApp/main.py", line 20, in <module>
   File "/Users/me/kivy-ios/build/pyobjus/i386/pyobjus-master/iosbuild/lib/python2.7/site-packages/pyobjus/dylib_manager.py", line 56, in make_dylib
   File "/Users/me/kivy-ios/dist/root/python/lib/python2.7/subprocess.py", line 486, in call
   File "/Users/me/kivy-ios/dist/root/python/lib/python2.7/subprocess.py", line 672, in __init__
   File "/Users/me/kivy-ios/dist/root/python/lib/python2.7/subprocess.py", line 1112, in _execute_child
 OSError: [Errno 1] Operation not permitted
2016-06-18 14:28:40.577 theApp[3280:1386652] Application quit abnormally!
2016-06-18 14:28:40.628 theApp[3280:1386652] Leaving

Why can I edit and load bridge.m but not any other class? How can I load custom classes besides bridge.m for iOS through pyobjus?

evbo commented

My mistake, the reason this failed for me is quite simple. When performing autoclass you need to invoke it with the name of the class - not the filename. Furthermore, as the iOS documentation says, make_dylib and load_dylib are not necessary. Just ensure the custom class header and .m are located in the same directory as bridge.m ("Classes" folder in Xcode).

In my case, all that was necessary was:

ObjcClass = autoclass('ObjcClass')
ObjcClass.alloc().init().printFromObjectiveC()

as per the docs mentioned above for the following objective-c library:

#import <Foundation/Foundation.h>

@interface ObjcClass : NSObject {
}

  • (void) printFromObjectiveC;
    @EnD

@implementation ObjcClass

  • (void) printFromObjectiveC {
    printf("Hello from Objective C\n");
    }

@EnD