在IOS上运行DJango

    Djangopythonweb框架,可以用于搭建网站或者作为web应用的后台。通常Django是从命令行启动。在ios中使用DJango,需要从程序中通过代码启动,另外DJango启动需要一定的时间,启动完成之后需要通知界面线程。

1.在桌面python中安装Django,创建ios工程,然后将Django模块添加到ios应用工程中。

  添加pythoncle相关的库,django中使用了hashlib,需要增加ssl相关的库,libssllibcrypto

 

  设置工程的环境变量,头文件或者库的搜索路径:

   

  将桌面的django和创建的站点mysite添加到工程中

 

2.修改manager.pyrunserver.py

  为了在初始化完成之后通知调用进程,需要修改runserver.py(core\management\commands目录下)

   

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是一个空的模块,主要用于管理全局变量,为了通知调用线程,在执行run之前,调用MainActivity.OnDJangoInitFinishMainActivity是一个共享对象,由调用线程设置,在python中访问.

  通常manager.py从命令行加载,因此如果从代码中加载,需要进行一定的修改,修改后代码如下:

#!/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 为调用线程传递给 python 的object-c类,由于目前 cle 版本有 bug ,只能传递object-c类给 python 。在 python 中,创建该类的一个实例,设置为全局变量

3. 初始化python,设置MainActivityClass,加载manager.py

  初始化 cle python 时,需要加载 hashlib 库,如下:
  
        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);
   设置 python 的搜索路径,全局变量MainActivityClass,加载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. 运行结果和代码下载

  编译代码需要 cle 下载地址 ,解压后放在同一个目录
 
   运行结果如下:
  











  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值