原文链接:http://rolfzhang.com/articles/1108.html

最近由于项目需要,用到了些ANE(Air Native Extension)的东西,让Flash可以在iOS调用一些东西,实在太坑爹了,让我忍不住拿出来分享一下 (天呀,我同时再弄js、php、c++、objective-c、flash的东西,崩溃呀)。

ANE,顾名思义,也就是Flash Air的本地扩展。Air虽然可以实现跨平台,但是当需要调用一些平台特性的时候,必然还是会遇到瓶颈的,例如在iOS上无法直接调用音频、图像、支付等接口,这时候就需要ANE出场了。iOS平台的ANE可以用c/c++/oc开发,向Air端提供相应的接口。

现在很多iOS本身的特性都有官方的ANE支持了,但是很多时候开发者还是会需要一些特定的ANE,例如什么摄像、录音、文件处理等,本地接口的效率还是会比Air要高出很多的。本文就以Air调用现在iOS上非常火的微信的API为例,说说ANE的坑爹之路吧。

第一步:定义好ActionScript的接口

首先,打开你的flash builder,创建一个Flex库项目,开始定义你的ActionScript接口吧。我们调用微信API要干嘛呢?当然是发消息给朋友啦,不过发消息前要向微信注册我们的应用ID,因此这里要实现两个接口,代码见下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.rolfzhang.ane
{
  import flash.events.Event;
  import flash.external.ExtensionContext;
  public class WeixinApi
  {
    private static varextContext:ExtensionContext = null;
    public static varisRegistered:Boolean = false;
    public static varWXSceneSession:int = 0;
    public static varWXSceneTimeline:int = 1;
    //构造函数
    publicfunctionWeixinApi(appIdStr:String){
      initExtension();     
      this.registerApp(appIdStr);
    }
    private static functioninitExtension():void{
      if(!extContext) {
        //这里通过一个自定义的id去获取相应的Extension,
        //必须和objc端的配置文件一致
        extContext = ExtensionContext.createExtensionContext("com.rolfzhang.ane.Weixin",null);
      }
    }
    privatefunctionregisterApp(appIdStr:String):Boolean {
      if(extContext && !isRegistered){
        //注册微信API,所有Extension方法都是通过call来调用
        isRegistered = extContext.call("initWXApi",appIdStr);
      }
    }
    publicfunctionsendTextMessage(msg:String, scene:int):Boolean {
      if(!isRegistered)returnfalse;
      //发送消息啦,scene为0表示发送给朋友,1发到朋友圈
      returnextContext.call("sendTextMessage",msg,scene) as Boolean;
    }
  }
}

这一步不是很复杂,extContext调用的接口也就是objc要实现的方法,先定义接口在开发是比较好的实践。

把这段代码编译好,生成swc文件,后面会用到。

第二步:用objc去调用微信API

这一步网上说的一般都比较复杂,除了写objc,还要解压swc文件,又要用命令行打包神马的,烦死了……咱们还是用些先进点的工具来解决好了。我在Github上找到了一个ANE的XCode模板,把很多东西都做好了,我们只需要老老实实的写objc代码,而不用管那些繁琐的打包工作(安装方法请自行阅读README.md)。

接下来,创建XCode的ANE项目:

红线部分必须和ActionScript接口里面定义的是一样的 ,当然这个也可以在extension.xml配置文件里面修改。

然后我们需要到Air SDK的文件夹里面找一个FlashRuntimeExtensions.h文件,放入我们的项目中,这个是Adobe提供的iOS与Air交互的接口。

创建好的项目中主有以下一些文件:

  • objc代码:Weixin.h、Weixin.m
  • 配置文件:extension.xml、platformoptions.xml
  • 打包脚本:generateANE.sh

Weixin.h中模板帮我们定义好了两个宏,这样写代码的时候会方便很多:

1
2
#define ANE_FUNCTION(f) FREObject (f)(FREContext ctx, void *data, uint32_t argc, FREObject argv[])
#define MAP_FUNCTION(f, data) { (const uint8_t*)(#f), (data), &(f) }

并且已经定义好了4个接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//as端首次调用createExtensionContext时进行初始化
//必须和extension.xml里面配置一致
voidWeixinExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet);
//extension被最终释放时调用,做一些clean up的工作
voidWeixinExtFinalizer(void* extData);
//ExtensionContext初始化,
//接口配置,获取全局context,对象初始化
voidContextInitializer(void* extData, constuint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToTest, constFRENamedFunction** functionsToSet);
//context被释放,做一些clean up的工作
voidContextFinalizer(FREContext ctx);
//我们要实现的方法
ANE_FUNCTION(initWXApi);
ANE_FUNCTION(sendTextMessage);

我们接下来的工作主要就是写实现各个ANE_FUNCTION,然后在ContextInitializer里面配置上去。在此之前,当然还要把微信的SDK给放进来啦,具体步骤我就不详诉了,请参考微信官方文档。上代码啦:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
voidContextInitializer(void* extData, constuint8_t* ctxType, FREContext ctx,
        uint32_t* numFunctionsToTest, constFRENamedFunction** functionsToSet)
{
  staticFRENamedFunction func[] =
  {//这里配置as能调用的方法
    MAP_FUNCTION(initWXApi, NULL),
    MAP_FUNCTION(sendTextMessage, NULL)
  };
  *numFunctionsToTest = sizeof(func) / sizeof(FRENamedFunction);
  *functionsToSet = func;
}
ANE_FUNCTION(initWXApi)
{
  //argv是as端传过来的参数,
  //类型是FREObject,需要一些转换才能被调用
  NSString * apiId = getStringFromFREObject(argv[0]);
  //向微信注册AppID
  BOOLsuccess = [WXApi registerApp:appId];
  //返回参数需要是FREObject类型
  returncreateFREBool(success);
}
ANE_FUNCTION(sendTextMessage)
{
  //获取参数
  NSString * msg = getStringFromFREObject(argv[0]);
  int32_t scene;
  FREGetObjectAsInt32(argv[1], &scene);
  //发消息
  SendMessageToWXReq* req = [[[SendMessageToWXReq alloc] init]autorelease];
  req.bText = YES;
  req.text = msg;
  req.scene = scene;
  BOOLsuccess = [WXApi sendReq:req];
  returncreateFREBool(success);
}
//将FREObject转成NSString
NSString * getStringFromFREObject(FREObject obj)
{
  uint32_t length;
  constuint8_t *value;
  FREGetObjectAsUTF8(obj, &length, &value);
  return[NSString stringWithUTF8String:(constchar *)value];
}
//将BOOL转成FREObject
FREObject createFREBool(BOOLvalue)
{
  FREObject fo;
  FRENewObjectFromBool(value, &fo);
  returnfo;
}

OK,写好代码只好当然是编译,然后ANE打包啦。什么,你要用终端写命令行?有了XCode的模板就不用这么麻烦了,选择Weixin.ane那个target,Command+B~ 一个微信的ANE就被build出来了。

第三步:调用ANE

这里就只是简单的测试ANE啦,不过比较纠结的是,目前无法在桌面端的模拟器里面进行测试,必须要打包成ipa传到iOS设备中运行。目前Flash Builder无法像XCode那样断点调试,而且代码分布在三个地方(as接口/objc/项目代码),真是错在哪都不知道,写错个字母也够你找几个小时了,很多的时间都浪费在些小问题上了。据说flash builder 4.7会支持联机调试,那样应该就会好很多。

ANE的调用很简单啦,创建一个Flex手机项目,选择iOS平台,然后在“项目属性>构建路径>本机扩展”里面添加ANE文件(XCode生成的ANE,XCode里面 右键>show in Finder 就找到了)。最后,还要检查下“构建打包”里面,这个ANE后面有没打上勾,没打上就勾上去。然后就import那个as库,调用相应的代码就行了。

iOS应用打包还需要提供证书和配置文件,怎么取得这个就自行研究吧。

以上的代码只是示例而已,源码不便提供,有什么问题请留言。接下来还会写一下ANE的应用回调、事件处理及一些经验和注意事项,敬请期待。

========

老实说这种混合体还是挺恶心的,Air基本只能做界面和交互功能,感觉还没有js+phonegap强大……

IOS ANE的坑爹之路一相关推荐

  1. IOS ANE的坑爹之路二

    上回说到了坑爹的微信ANE,这回继续~ 上文解决的问题是比较简单的,只是从我们的app中发消息到微信中,跑通了整个ANE的流程.但是实际应用中还会遇到如下的一些问题: 发送完消息后,能够回到应用中 接 ...

  2. 精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路

    「架构都是演变出来的,没有最好的架构,只有最合适的架构!」最近,滴滴出行平台产品中心 iOS 技术负责人李贤辉接受了 infoQ 的采访,阐述了滴滴的 iOS 客户端架构模式与演变过程.李贤辉也是移动 ...

  3. AppStore编年史 iOS游戏开发者的变迁路

    http://ipad.66u.com/yxzb/20140627_29184.html 智能机游戏市场发展不过三四年,其间的形态与格局变化,却已沧海桑田.AppStore编年史带大家走进iOS游戏开 ...

  4. 门市之星,进销存,坑爹之路

    门市之星,进销存,坑爹之路 起因:客户销售电机产品,也许是年纪较大的缘故,速达,管家婆,都不喜欢用,唯独喜欢上了"门市之星"进销存-- "门市之星"用了1年多, ...

  5. H5嵌入原生开发小结----兼容安卓与ios的填坑之路

    一开始听说开发H5,以为就是做适配现代浏览器的移动网页,心想不用管IE了,欧也.到今天,发现当初too young too simple,兼容IE和兼容安卓与IOS,后者让你更抓狂.接下来数一下踩过的 ...

  6. iOS开发的跳槽之路的心路历程分享(iOS进阶路线路)

    序言 我相信很多人都在说,iOS行业不好了,iOS现在行情越来越难了,失业的人比找工作的人还要多.这是事实,物竞天择,优胜劣汰,我们一样适用于丛林法则.所以我们要不断学习,提升自己的技能,不仅仅专业方 ...

  7. IOS停机卡免流线路下载更新

    无为最开始只做校园网免认证的,所以用户下载中心只有校园网线路,后来增加了停机卡免流,一直没有增加下载通道,特意跟新停机卡免流线路下载通道 登录用户中心网站tj.wifipo.vip:51/user/  ...

  8. 滴滴android架构演进,滴滴出行iOS客户端架构演进之路

    自从蘑菇街的李忠老师在移动前线群里做了一次关于iOS组件化的分享之后,大家对于iOS客户端的架构非常感兴趣,展开了热烈的讨论.我很认同一句话,架构都是演变出来的,没有最好的架构,只有最合适的架构,刚好 ...

  9. iOS项目技术还债之路《一》后台下载趟坑

    前言 去年底我在公司开始接手几个迭代了五六年的iOS老项目的技术优化工作.互联网公司的闭源N手业务老代码,经过了若干年和若干波人的轮番洗礼,再加上若干个deadline的赶工加持,已经是千疮百孔,改点 ...

最新文章

  1. 安卓下拉刷新、上拉加载数据显示
  2. Zoom 袁征码农逆袭:8 次申请美国签证被拒,独闯硅谷成亿万富翁
  3. docker部署openvas
  4. 一文看懂软件测试方法和规范
  5. Yii2 Pjax的简单使用
  6. Laravel大型项目系列教程(二)之用户管理
  7. android qq红包,Android实现QQ抢红包插件
  8. VScode 格式化代码快捷键、修改快捷键
  9. 如何在linux系统写程序文件,Linux应用程序使用写文件调试程序的方法
  10. 【krpano】多分类缩略图及多分类地图案例
  11. 集合之HashSet
  12. Ubuntu下载Linux源码 编译Linux源码
  13. 100道MySQL数据库经典面试题解析(收藏版)
  14. 武汉知名 IT 公司大盘点
  15. java里如何表示黑桃方片_扑克牌中(黑桃,方片,红心,梅花)各代表什么意思?据我所知红心是代表爱。...
  16. Python-scrapy爬虫
  17. 什么是动态评分及规则
  18. Powershell攻击指南1——PowerSploit
  19. 备了安的网站换服务器,tipask网站更换服务器后 问答系统重新安装注意要点 - 小俊学习网...
  20. Twitter 下载遇到的问题

热门文章

  1. 川师大计算机专业好就业吗,四川师范大学好就业吗?附四川师范大学就业率最高的专业名单...
  2. IDEA 插件的设置和引用,以及插件库
  3. Java中代码点与代码单元(转)
  4. switch case 穿透
  5. 【存储器专题】ROM和RAM
  6. Staubli HCB08.7202/IC/JS3
  7. for example: not eligible for auto-proxying问题解决
  8. Jackson:Cannot construct instance of **** (although at least one Creator exists):
  9. 西南交通大学2017年计算机复试笔试题(数据库)
  10. 退休当月要干到月底吗_法律规定退休人员上班到退休当日还是当月