beeware / Python-iOS-template

A cookiecutter template for creating an iOS project running Python code.
MIT License
303 stars 36 forks source link

Import error with the template #20

Open Cerise1 opened 8 years ago

Cerise1 commented 8 years ago

Hi,

Thank you for the devellopment of this tool, i come here cause i have some troubles with the template that i ve been unable to solve for 3 days !

i installed the python3.5 ios template did evrything that was required and it seems to work with simple script ! I needed to install Pynacl for my more complex script so i did it with pip install in the app_package folder ! but here the problem : when i run the application i got an import error : from nacl._sodium.cpython_35m_darwin.so import ffi, lib
ImportError: No module named 'nacl._sodium'

When i run the script from the terminal -Not from the app- it works !

Also I've looked if the file " nacl._sodium " was here or not and i found in the nacl folder this file : " _sodium.cpython_35m_darwin.so ".

Here i don't know what to think. I beleive it is the file that need to be imported and the "cpython_35m_darwin.so " is just a tag that is not important because this import works outside of the template !

But i don't have any idea why i am stuck with this problem inside of the iOS-template any help would be very appreciated :)

freakboy3742 commented 8 years ago

Binary modules (anything with a compiled component) is a difficulty, because iOS doesn't allow dynamic libraries. If you want to use a C module, you need to get the original sources, and add it to the XCode project so that they are linked into the final binary as a static library.

This is something that I'm hoping briefcase will one day be able to handle. In the meantime, unfortunately, I can't point you at a good set of instructions.

Cerise1 commented 8 years ago

Thank you for your answer !

Unfortunatly i see that i am again stuck on the same difficulty : i Did try one Time with the pythonista ios template ( wich doesnt support python3 so thats not good ) and someone told me the same thing about C librairies that i would need To compile and link in the Xcode project but without further explanations :,( .

I understand that it could be a complex task but i am completly ok To learn and work on it even if i need To spend hours. The problem Is i dont realy know what To learn when i search on google : "link librairies to an xcode project" or equivalent, i got nothing interesting !

Also you told me that ios doesnt allow dynamic librairies but i found in my iPad a .dylib in the repository of an app. The app was a jailbreak app though and maybe ios allows dylib in this case.

The point Is my application Target only jailbroken devices !!! So maybe there Is a workarround like a tweak i need To install before to allow my app To run C librairies in others app.

The best would be that it works directly on a jb device i only tested my app trough the iOS simulator wich obviously Is not Jailbroken. Do you recomend me To test on a physical jailbroken device or do you already see that its not the point ? Or do you any idea what i would need To learn in deep To be able To link the librairie in my xcode project ?

Thank you ;)

freakboy3742 commented 8 years ago

If you're doing this the traditional way, you're not going to be adding in a linked library - you'll be adding the .c source files directly to your project. That means they'll be included and compiled at the same time as the rest of your code. However, exactly how to compile them will depend on the compilation requirements of the C module itself.

It's entirely possible that jailbroken devices allow dynamic libraries - or, that very recent versions of iOS may have relaxed this requirement.

Unfortunately, I can't point you at a good example of how to do this. It's definitely something that we should document, though. I'm at PyCon Australia at the moment, and we have sprints on Monday and Tuesday; I'll see if I can convince someone to look into this problem.

Cerise1 commented 8 years ago

Well at least i am going To try To test the script on a physical jailbroken device by following the procedure with the provisioning profile etc... Yes this Is my first app :D and will see what happen..

I'm at Pycon Australia at the moment, and we have sprints on Monday and Tuesday; i'll se if i can convince. Someone To look into this problem.

That's very nice thank you :) and enjoy there 🌞☄

EDIT : So i tested on my jailbroken iphone and exactly same problem :(

When you talk about the .c source file do you talk of .cpython file ? cause it is the .cpython file that cant be imported !! and the module is not not fully written in C i see a lot of .py file.

Also i thought xcode would compile objC code maybe C# but will he compile C code easily ? And You say it need to be compile at the same time of the app itself by xcode so how would i respect the compilation requirements of the C module if xcode compile it automaticly with the normal process when it build the app ? I think i missed something !

Cerise1 commented 8 years ago

Hello freakboy,

Do you have some News ON this problem to include C librairies In our ios project ?

freakboy3742 commented 8 years ago

Unfortunately not. What you're asking is a fairly complicated task, especially if you want it to be as simple as the normal CPython development process. Ultimately, I want it to reach a point of easy usability, but in the meantime, it's going to require some dirty fingernails and bruised elbows.

Cerise1 commented 8 years ago

I just have a new idea tell me if its not possible at all or if there Is something interesting :

I need To use some libsodium features in my Python app, and i know there Is a native libsodium-ios that i can add in the xcode project with cocoapod ! So would it be possible To pass some obj C object To the python interpreter : when i need it in my python script the app doese the work with libsodium in obj C langage and passes the object To python So that the script can continue ?

I dont know maybe its even more difficult than just link pynacl into the project :D maybe not !

freakboy3742 commented 8 years ago

Not at all - Rubicon is a bridging library that provides transparent access to Objective C objects from within Python. So, if libsodium-ios already exists, and the interface is provided in Objective C, accessing that library from within Python will be relatively trivial.

Cerise1 commented 8 years ago

Thank you for this suggestion i tried using rubicon to solve my problem but i ve been stuck for 2 days and maybe you could give me a few hints :)

I am very unfamiliar with ctypes and with Obj-c ( thats why i am trying to use this template ) I try to explain my problem :

In my python script i use PyNacl to instanciate some object. Let's say for example i instanciate a PrivateKey object ( from nacl.public ). I would like to be able to do the same in obj-c and bring it to python with Rubicon but i dont see any class documentation for libsodium-ios !

I ve installed libsodium-ios via CocoaPod and rubicon in the app_package folder !

my python script start with : from ctypes import cdll from ctypes import util from rubicon.objc import ObjCClass, objc_method

then i need to import the framwork i am not really sure if i need to replace 'Fondation' at this line : >>> cdll.LoadLibrary(util.find_library('Foundation')) Then when i try : sk= ObjCClass("PrivateKey") Obvioulsy it doesn't work cause privateKey is not recocnize as an Obj-c class !

Also i would like to use some method from libsodium-ios for example i use the scalar multiplication method wich is here i can see it in the header files but i can't if i dont have any object to apply the method !

Well i'am sure you can see that i am a bit confused i essentialy know how does python work but here i think i missed something ! Any hints would be apreciated :)

Thanks

freakboy3742 commented 8 years ago

I don't know the NaCl/libsodium library myself, so it's difficult for me to provide specific help. However: Yes, you need to replace "Foundation" with the name of the NaCl library - I'm guessing it's "sodium" or "nacl"; capitalisation may also be required. Once you've done that, ObjCClass("PrivateKey") will give you a working wrapper around the Objective C PrivateKey object, on which you can invoke any documented ObjectiveC API.

The name of the ObjectiveC method maps directly to the Python name, replacing the ":" in descriptors with an underscore - so you can construct an object by calling PrivateKey.alloc().init() (the mapping of [[PrivateKey alloc] init]); the ObjectiveC message: [pk doStuff:"stuff" withThings:42] would be accessed as pk.doStuff_withThings_("stuff", 42) in Python.

Cerise1 commented 8 years ago

I tryed replacing "Fondation" with sodium, Sodium, nacl; Nacl, libsodium, Libsodium, libsodium-ios, Libsodium-ios, liblibsodium-ios but the line sk=ObjCClass("PrivateKey") always give me this error : builtins.NameError: ObjC Class 'PrivateKey' couldn't be found. So i d'ont know what to do and the author of lib sodium-ios is afk :( Do you have something to test that the librairie did load ? Cause i am sure the LoadLibrairie command do not load anything that's why PrivateKey can't be find ..

freakboy3742 commented 8 years ago

As I said, I don't know anything about libsodium, so you're going to need to do some exploration here.

This isn't something where you stumble around hoping to find the right name - it's the name of the Framework that you've added to the project. If you use the cdll.LoadLibary method, and it doesn't return a non-null, then it hasn't worked, and either the name is wrong, or you haven't linked the framework in correctly.

Cerise1 commented 7 years ago

I post this to know If by any chance The problem to add C module In The project has been solved or is under developpement :)

freakboy3742 commented 7 years ago

No - it hasn't been fixed, and it's not under active development at the moment, either.

If you have a pressing need for this, I'm available for contracting work to accelerate the development of specific priorities in the BeeWare project.