IOS ANE的坑爹之路(二)
来源:互联网 发布:java 高并发 抢购 编辑:程序博客网 时间:2024/06/06 07:40
上回说到了坑爹的微信ANE,这回继续~
上文解决的问题是比较简单的,只是从我们的app中发消息到微信中,跑通了整个ANE的流程。但是实际应用中还会遇到如下的一些问题:
- 发送完消息后,能够回到应用中
- 接收回调完成的消息,进行处理
- objc端与air端事件传递、消息同步
- objc端调试不方便
- 使用原生控件
下面就一一的解决一下吧~
1、通过URL调用应用
原生的iOS应用要解决这个问题很简单,在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”即可。
实际上,Xcode是在info.plist里面添加了一段XML:
<
key
>CFBundleURLTypes</
key
>
<
array
>
<
dict
>
<
key
>CFBundleURLName</
key
>
<
string
>weixin</
string
>
<
key
>CFBundleURLSchemes</
key
>
<
array
>
<
string
>wxappid</
string
>
</
array
>
</
dict
>
</
array
>
上面的示例注册了一个名为wxappid的 URI 方案,从而允许应用程序由wxappid://形式的 URL 进行调用。
而air的程序是用flash builder创建的,打包后的info.plist由flash builder生成。在项目中的app.xml里面有个<iphone>的标签,可在此配置info.plist的内容,因此只需将上面的xml复制到app.xml的<iphone>标签中即可。
更多的配置选项可以参考这里~
通过自定义 URI 调用应用程序时,air的NativeApplication 对象会调一个 invoke 事件,链接的 URL(包括查询参数)放在 InvokeEvent 对象的 arguments 数组中,我们可以在applicationCompleteHandler如下调用:
NativeApplication.nativeApplication
.addEventListener(InvokeEvent.INVOKE,
function
invokeHandler(event:InvokeEvent):void{
if
(event.arguments.length>0){
doSomething(event.arguments[0]);
}
});
2、处理微信的URL回调
微信的URL回调有两种:在微信中向应用请求消息、在应用发消息给微信后返回应用。
原生应用要触发这两个回调是在 application:openURL:sourceApplication:annotation: 方法中中调用WXApi handleOpenURL:delegate:,触发delegate的onReq或onResp方法。
然而air开发的应用无法调用此方法,因此可以利用上面的invoke事件通过ANE进行调用。
3、Objc与Air进行事件同步
delegate的onReq或onResp被触发后,往往是要让应用进行某些处理,因此还需要objc和air端进行消息同步,可调用air提供了的C语言接口FREDispatchStatusEventAsync进行处理:
//收到一个来自微信的请求,处理完后调用sendResp
-(
void
) onReq:(BaseReq*)req {
NSString * code = @
"onReq"
;
NSString * level = @
"someReqData"
;
FREDispatchStatusEventAsync(g_ctx,
(constuint8_t *)[code UTF8String],
(constuint8_t *)[level UTF8String]);
}
//发送一个sendReq后,收到微信的回应
-(
void
) onResp:(BaseResp*)resp {
NSString * code = @
"onResp"
;
NSString * level = @
"someRespData"
;
FREDispatchStatusEventAsync(g_ctx,
(constuint8_t *)[code UTF8String],
(constuint8_t *)[level UTF8String]);
}
上面两个方法是向air端发出事件,因此air端需要对事件进行监听,我们需要对之前的actionScript接口进行修改:
创建一个Weixin事件对象
public class WeixinApiEvent extends Event {
public static const onReq:String =
"onWXReq"
;
public static const onResp:String =
"onQXResp"
;
public
var
data:String =
null
;
public
function
WeixinApiEvent(type:String,
data:String,
bubbles:Boolean=
false
,
cancelable:Boolean=
false
) {
super
(type, bubbles, cancelable);
this
.data = data;
}
}
继承EventDispatcher,并监听StatusEvent
import flash.events.EventDispatcher;
import flash.events.StatusEvent;
public class WeixinApi extends EventDispatcher {
...
public
function
WeixinApi(appIdStr:String) {
super
();
this
.registerApp(appIdStr);
if
(isRegistered){
//监听StatusEvent
extContext.addEventListener(StatusEvent.STATUS,onStatus);
}
}
...
public
function
onStatus(e:StatusEvent):void {
//将事件封装并转发给应用
dispatchEvent(
new
WeixinApiEvent(e.code,e.level));
}
}
重新打包ANE后,即可在应用中对微信的回调事件进行监听了,如:
function
applicationCompleteHandler(event:FlexEvent):void {
...
wxApi =
new
WeixinApi(
"weixinApi"
);
wxApi.addEventListener(WeixinApiEvent.onReq,dosomething);
wxApi.addEventListener(WeixinApiEvent.onResp,dosomething);
...
}
4、原生控件调用及辅助调试
ANE的调试一直是很纠结的,代码分布在3个地方,并且air端不支持alert,安装到iOS设备上也看不到trace信息,出错了也不知错在哪,纠结~~~~ air端可以通过try/catch捕获错误信息,将debug信息输出到一个textField里面,但对于objc端就无能为力了。
好在可以通过ANE调用objc的原生控件,这样就可以将objc端的调试信息展示出来了。AIR应用是在一个标准的window对象里运行的,你可以通过下面的方法获得这个window对象:
[UIApplication sharedApplication].keyWindow
得到window对象后你可以给它添加subviews来显示原生的view对象。
UILabel* nativeLogLabel;
NSString * logInfo = @
"-- start loging --"
;
//air无法alert,那就直接调用原生的alert吧~
void
nativeAlert(NSString * title, NSString * message) {
UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@
"OK"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
//在界面中显示logArea
void
showLogArea(
float
x,
float
y,
float
width,
float
height) {
if
(!nativeLogLabel){
nativeLogLabel = [[UILabelalloc] initWithFrame:CGRectMake(x, y, width, height)];
nativeLogLabel.font = [UIFontsystemFontOfSize:11];
nativeLogLabel.lineBreakMode = UILineBreakModeWordWrap;
nativeLogLabel.numberOfLines = 0;
}
nativeLogLabel.frame = CGRectMake(x, y, width, height);
nativeLogLabel.text = logInfo;
[[[UIApplicationsharedApplication] keyWindow] addSubview:nativeLogLabel];
}
//添加log信息
void
addLogContent(NSString *
log
){
logInfo = [NSStringstringWithFormat:@
"%@\n%@"
,
log
,logInfo];
if
(nativeLogLabel){
nativeLogLabel.text = logInfo;
}
}
通过定义ANE_FUNCTION的方式将这三个方法暴露出去后,即可在air和objc端调用统一的调试信息输出接口,找bug总算容易多了~
5、其他经验
个人总结的一些经验:
- ANE的相关资料比较少,最好的办法就是多看Adobe提供的文档~ ;
- 使用(一)中提到的xcode模板,它帮你写好了各种方法定义、宏、配置、批处理文件,不然你的开发会成倍的复杂;
- 将FlashRuntimeExtensions.h中常用的方法进行封装,诸如从FREObject里面获取数据等;
- 用一个objc对象封装所有的业务逻辑,而不是将所有逻辑都写在ANE_FUNCTION里面;
比较常见的错误:
- air端try/catch捕获异常 argument error #3500 -- objc忘了将方法添加到functionsToSet 中;
- 调用ANE方法直接闪退 -- objc中有错误的内存引用,好好研究下什么retain、release的吧;
- 发布AIR应用的时候,指明需要引用的iOS SDK地址,不然有些时候会出错。在Flash Builder里,在“构建打包>本机扩展”面板中可以进行设置;
另外推荐一篇文章:《20条开发AIR Native Extension的建议》
- IOS ANE的坑爹之路(二)
- IOS ANE的坑爹之路二
- IOS ANE的坑爹之路(一)
- IOS ANE的坑爹之路一
- ane教程之IOS
- ane--->iOS
- 制作IOS ANE的基本流程
- ios/android代码生成FLASH可用的actionscript代码(*.ane)
- [AIR iOS] ANE 收集
- ANE原生代码的调试(安卓)++flex通过ANE调试原生安卓代码
- Adobe Air ANE之Admob开发需要的依赖库
- 腾讯移动游戏平台SDK(MSDK) ios版Ane扩展 过程中所遇到的问题
- AIR的ane开发
- ane的那些屁事
- Ane的开发总结
- flash ANE 调用ios方法
- 利用ios的hook机制实现adobe air ios ane下appdelegate的动态替换
- iOS 之 Block 的使用 (二)
- 主线程先循环20次,接着子线程循环10次,如此周而复始50次
- solr安装
- Use pssh to manage muti hosts
- http://blog.csdn.net/tonywangteng
- 程序员面试题精选100题(05)-查找最小的k个元素[算法]
- IOS ANE的坑爹之路(二)
- Spring MVC 的几个跳转方法中Attribute的区别
- 【discuzx2】在后台添加自定义DIY模块的方法
- R-list类型直接转data.frame()之后是factor类型,直接按行列位置取数会出错
- Android Paint类
- 跟这世界谈谈
- 【Unity-提高效率】我的白痴记录
- QT调用C#开发的ArcEngine的.net组件(1)
- Hibernate连接8种常见的数据库配置方式