IOS ANE的坑爹之路一
原文链接: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 var extContext:ExtensionContext = null ;
public static var isRegistered:Boolean = false ;
public static var WXSceneSession:int = 0;
public static var WXSceneTimeline:int = 1;
//构造函数
public function WeixinApi(appIdStr:String){
initExtension();
this .registerApp(appIdStr);
}
private static function initExtension():void{
if (!extContext) {
//这里通过一个自定义的id去获取相应的Extension,
//必须和objc端的配置文件一致
extContext = ExtensionContext.createExtensionContext( "com.rolfzhang.ane.Weixin" , null );
}
}
private function registerApp(appIdStr:String):Boolean {
if (extContext && !isRegistered){
//注册微信API,所有Extension方法都是通过call来调用
isRegistered = extContext.call( "initWXApi" ,appIdStr);
}
}
public function sendTextMessage(msg:String, scene:int):Boolean {
if (!isRegistered) return false ;
//发送消息啦,scene为0表示发送给朋友,1发到朋友圈
return extContext.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里面配置一致
void WeixinExtInitializer( void ** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet);
//extension被最终释放时调用,做一些clean up的工作
void WeixinExtFinalizer( void * extData);
//ExtensionContext初始化,
//接口配置,获取全局context,对象初始化
void ContextInitializer( void * extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet);
//context被释放,做一些clean up的工作
void ContextFinalizer(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
|
void ContextInitializer( void * extData, const uint8_t* ctxType, FREContext ctx,
uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet)
{
static FRENamedFunction 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
BOOL success = [WXApi registerApp:appId];
//返回参数需要是FREObject类型
return createFREBool(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;
BOOL success = [WXApi sendReq:req];
return createFREBool(success);
}
//将FREObject转成NSString
NSString * getStringFromFREObject(FREObject obj)
{
uint32_t length;
const uint8_t *value;
FREGetObjectAsUTF8(obj, &length, &value);
return [NSString stringWithUTF8String:( const char *)value];
}
//将BOOL转成FREObject
FREObject createFREBool( BOOL value)
{
FREObject fo;
FRENewObjectFromBool(value, &fo);
return fo;
}
|
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的坑爹之路一相关推荐
- IOS ANE的坑爹之路二
上回说到了坑爹的微信ANE,这回继续~ 上文解决的问题是比较简单的,只是从我们的app中发消息到微信中,跑通了整个ANE的流程.但是实际应用中还会遇到如下的一些问题: 发送完消息后,能够回到应用中 接 ...
- 精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路
「架构都是演变出来的,没有最好的架构,只有最合适的架构!」最近,滴滴出行平台产品中心 iOS 技术负责人李贤辉接受了 infoQ 的采访,阐述了滴滴的 iOS 客户端架构模式与演变过程.李贤辉也是移动 ...
- AppStore编年史 iOS游戏开发者的变迁路
http://ipad.66u.com/yxzb/20140627_29184.html 智能机游戏市场发展不过三四年,其间的形态与格局变化,却已沧海桑田.AppStore编年史带大家走进iOS游戏开 ...
- 门市之星,进销存,坑爹之路
门市之星,进销存,坑爹之路 起因:客户销售电机产品,也许是年纪较大的缘故,速达,管家婆,都不喜欢用,唯独喜欢上了"门市之星"进销存-- "门市之星"用了1年多, ...
- H5嵌入原生开发小结----兼容安卓与ios的填坑之路
一开始听说开发H5,以为就是做适配现代浏览器的移动网页,心想不用管IE了,欧也.到今天,发现当初too young too simple,兼容IE和兼容安卓与IOS,后者让你更抓狂.接下来数一下踩过的 ...
- iOS开发的跳槽之路的心路历程分享(iOS进阶路线路)
序言 我相信很多人都在说,iOS行业不好了,iOS现在行情越来越难了,失业的人比找工作的人还要多.这是事实,物竞天择,优胜劣汰,我们一样适用于丛林法则.所以我们要不断学习,提升自己的技能,不仅仅专业方 ...
- IOS停机卡免流线路下载更新
无为最开始只做校园网免认证的,所以用户下载中心只有校园网线路,后来增加了停机卡免流,一直没有增加下载通道,特意跟新停机卡免流线路下载通道 登录用户中心网站tj.wifipo.vip:51/user/ ...
- 滴滴android架构演进,滴滴出行iOS客户端架构演进之路
自从蘑菇街的李忠老师在移动前线群里做了一次关于iOS组件化的分享之后,大家对于iOS客户端的架构非常感兴趣,展开了热烈的讨论.我很认同一句话,架构都是演变出来的,没有最好的架构,只有最合适的架构,刚好 ...
- iOS项目技术还债之路《一》后台下载趟坑
前言 去年底我在公司开始接手几个迭代了五六年的iOS老项目的技术优化工作.互联网公司的闭源N手业务老代码,经过了若干年和若干波人的轮番洗礼,再加上若干个deadline的赶工加持,已经是千疮百孔,改点 ...
最新文章
- 安卓下拉刷新、上拉加载数据显示
- Zoom 袁征码农逆袭:8 次申请美国签证被拒,独闯硅谷成亿万富翁
- docker部署openvas
- 一文看懂软件测试方法和规范
- Yii2 Pjax的简单使用
- Laravel大型项目系列教程(二)之用户管理
- android qq红包,Android实现QQ抢红包插件
- VScode 格式化代码快捷键、修改快捷键
- 如何在linux系统写程序文件,Linux应用程序使用写文件调试程序的方法
- 【krpano】多分类缩略图及多分类地图案例
- 集合之HashSet
- Ubuntu下载Linux源码 编译Linux源码
- 100道MySQL数据库经典面试题解析(收藏版)
- 武汉知名 IT 公司大盘点
- java里如何表示黑桃方片_扑克牌中(黑桃,方片,红心,梅花)各代表什么意思?据我所知红心是代表爱。...
- Python-scrapy爬虫
- 什么是动态评分及规则
- Powershell攻击指南1——PowerSploit
- 备了安的网站换服务器,tipask网站更换服务器后 问答系统重新安装注意要点 - 小俊学习网...
- Twitter 下载遇到的问题
热门文章
- 川师大计算机专业好就业吗,四川师范大学好就业吗?附四川师范大学就业率最高的专业名单...
- IDEA 插件的设置和引用,以及插件库
- Java中代码点与代码单元(转)
- switch case 穿透
- 【存储器专题】ROM和RAM
- Staubli HCB08.7202/IC/JS3
- for example: not eligible for auto-proxying问题解决
- Jackson:Cannot construct instance of **** (although at least one Creator exists):
- 西南交通大学2017年计算机复试笔试题(数据库)
- 退休当月要干到月底吗_法律规定退休人员上班到退休当日还是当月