Running DJango on IOS

Keywords: Python Django iOS SSL

Django is python's web framework, which can be used to build websites or as a backstage for web applications. Usually Django is started from the command line. Using DJango in ios needs to start from the program through code. In addition, DJango needs a certain time to start. After starting, it needs to notify the interface thread.

1. Install Django in desktop python, create ios project, and then add Django module to ios application project.

Adding python and cle-related libraries, django uses hashlib and needs to add ssl-related libraries, libssl and libcrypto.

 

Set the search path of the project's environment variables, header files or libraries:

   

Add django on the desktop and mysite created to the project

 

2. Modify manager.py and runserver.py

  To notify the calling process after initialization is complete, you need to modify runserver.py (in the core management commands directory)

   

def inner_run(self, *args, **options):
    …
    try:
            import starglobal
            starglobal.MainActivity.OnDJangoInitFinish()  # notify host
            handler = self.get_handler(*args, **options)
            run(self.addr, int(self.port), handler,
                ipv6=self.use_ipv6, threading=threading)

starglobal is an empty module that manages global variables. To notify the calling thread, MainActivity.OnDJangoInitFinish is called before run ning. MainActivity is a shared object set by the calling thread and accessed in python.

manager.py is usually loaded from the command line, so if it is loaded from the code, some modifications are needed. After modification, the code is as follows:

#!/usr/bin/env python
import os
import sys
import traceback 
import thread
import time

def doit(val):
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        # The above import may fail for some other reason. Ensure that the
        # issue is really that Django is missing to avoid masking other
        # exceptions on Python 2.
        try:
            import django
        except ImportError:
            traceback.print_exc()
            raise ImportError(
                "Couldn't import Django. Are you sure it's installed and "
                "available on your PYTHONPATH environment variable? Did you "
                "forget to activate a virtual environment?"
            )
        raise
    execute_from_command_line(['manage.py', 'runserver','--noreload'])
        
if __name__ == "__main__":
    try:
        print(MainActivityClass)
        import starglobal
        starglobal.MainActivity = MainActivityClass()
        print(starglobal.MainActivity)
        thread.start_new_thread(doit,(0,))
        while True :
            while libstarpy._SRPDispatch(False) == True :
                pass
            libstarpy._SRPUnLock()
            time.sleep(0.01) 
            libstarpy._SRPLock()        
        
    except Exception :
        traceback.print_exc()

MainActivityClass is an object-c class passed to Python by calling threads. Because there are bug s in the current version of cle, it can only pass object-c class to python. In python, create an instance of this class and set it as a global variable

3. Initialize python, set MainActivityClass, and load manager.py.

When initializing cle s and python s, the hashlib libraries need to be loaded, as follows:
  
        extern "C" void init_hashlib(void);

        NSString *respaths = [[NSBundle mainBundle] resourcePath];
        const VS_CHAR *res_cpath = [respaths UTF8String];
        VS_CHAR python_path[512];
        VS_CHAR python_home[512];
        sprintf(python_home,"%s/python",res_cpath);
        sprintf(python_path,"%s/python2.7.zip",res_cpath);
        
        VSImportPythonCModuleDef CModuleDef[]={{"_hashlib",(void*)init_hashlib},{NULL,NULL}};
        VSCoreLib_InitPython((VS_CHAR*)python_home,(VS_CHAR *)python_path,CModuleDef);
Set python's search path, global variable MainActivityClass, load manager.py

        void *python = SRPInterface ->ImportRawContext((VS_CHAR*)"python",(VS_CHAR*)"",false,NULL);
        
        void *pythonsys = (void *)SRPInterface->ScriptGetObject(python, "sys", NULL);
        void *pythonpath = (void*)SRPInterface->ScriptGetObject(pythonsys, "path", NULL);
        
        SRPInterface->ScriptCall(pythonpath, NULL, "insert", "(is)",0,res_cpath);
        sprintf(python_path,"%s/mysite",res_cpath);
        SRPInterface->ScriptCall(pythonpath, NULL, "insert", "(is)",0,python_path);
        
        Star_ObjectCBridge_Init(SRPInterface,NULL,NULL);
        /*---need include --#import <objc/runtime.h>-*/
        /*--there is a bug of cle 2.5.1 for set object to cle, which will be solved at 2.5.2-*/
        /*SRPInterface -> ScriptSetObject(python,"MainActivity",VSTYPE_OBJPTR,(VS_UWORD)_FromObjectC(self));*/
        SRPInterface -> ScriptSetObject(python,"MainActivityClass",VSTYPE_OBJPTR,(VS_UWORD)_FromObjectC(objc_getClass("MainActivityClass")));
        
        sprintf(python_path,"%s/mysite/manage.py",res_cpath);
        SRPInterface->DoFile("python", python_path, NULL, NULL, VS_TRUE);
   
    MainActivityClass:
   
@interface MainActivityClass : NSObject
-(void)OnDJangoInitFinish;
@end

@implementation MainActivityClass

-(void)OnDJangoInitFinish
{
    dispatch_async(dispatch_get_main_queue(),^{
        [Control.MyBrowser  loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1:8000"]]];
    });
}

@end

4. Running results and code download

Compiling code requires cle. Download address Unzip and place it in the same directory
 
The results are as follows:
  
   Sample code download











Posted by allyse on Thu, 11 Apr 2019 17:18:31 -0700