打包制作 ANE
一、打包ANE
1.ios
准备文件:
- anePackager.bat
- aneswc.swc
- extension.xml
- flashAne.ane
- ioslib.a
- library.swf
- platformoptions.xml(可选,用于标记.a文件需要的framework、lib)
.a文件:
FlashRuntimeExtensions.h:在AIR_SDK根目录下的include文件夹下
IapAne.h:
#ifndef __IAP_ANE_H__ #define __IAP_ANE_H__ #import <Foundation/Foundation.h> #import "FlashRuntimeExtensions.h" #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) } /**************************************************/ NSString * getStringFromFREObject(FREObject obj); FREObject createFREString(NSString * string); double getDoubleFromFREObject(FREObject obj); FREObject createFREDouble(double value); int getIntFromFREObject(FREObject obj); FREObject createFREInt(int value); BOOL getBoolFromFREObject(FREObject obj); FREObject createFREBool(BOOL value); /**************************************************/ /***********************event dispatcher***************************/ FREContext context; void dispatchStatusEventAsync(NSString * code, NSString * level); /**************************************************/ void ExtensionInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet); void ExtensionFinalizer(void* extData); void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet); void ContextFinalizer(FREContext ctx); ANE_FUNCTION(initialize); //ANE_FUNCTION(setTesting); #endif
IapAne.m:
#import "IapAne.h" /* * utils function */ /*--------------------------------string------------------------------------*/ NSString * getStringFromFREObject(FREObject obj) { uint32_t length; const uint8_t *value; FREGetObjectAsUTF8(obj, &length, &value); return [NSString stringWithUTF8String:(const char *)value]; } FREObject createFREString(NSString * string) { const char *str = [string UTF8String]; FREObject obj; FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t*)str, &obj); return obj; } /*-------------------------------double-----------------------------------*/ double getDoubleFromFREObject(FREObject obj) { double number; FREGetObjectAsDouble(obj, &number); return number; } FREObject createFREDouble(double value) { FREObject obj = nil; FRENewObjectFromDouble(value, &obj); return obj; } /*---------------------------------int---------------------------------*/ int getIntFromFREObject(FREObject obj) { int32_t number; FREGetObjectAsInt32(obj, &number); return number; } FREObject createFREInt(int value) { FREObject obj = nil; FRENewObjectFromInt32(value, &obj); return obj; } /*------------------------------bool----------------------------------------*/ BOOL getBoolFromFREObject(FREObject obj) { uint32_t boolean; FREGetObjectAsBool(obj, &boolean); return boolean; } FREObject createFREBool(BOOL value) { FREObject obj = nil; FRENewObjectFromBool(value, &obj); return obj; } /*--------------------------------------------------------------------------*/ /***********************event dispatcher***************************/ void dispatchStatusEventAsync(NSString * code, NSString * level){ if(context!= nil){ FREDispatchStatusEventAsync(context, (const uint8_t *) [code UTF8String], (const uint8_t *) [level UTF8String]); }else{ NSLog(@"===dispatchStatusEventAsync error FREContext is null"); } } /**************************************************/ void ExtensionInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet) { NSLog(@"===Entering ExtensionInitializer()"); *extDataToSet = NULL; *ctxInitializerToSet = &ContextInitializer; //传入Context初始化方法 *ctxFinalizerToSet = &ContextFinalizer; //传入Context结束方法 NSLog(@"===Exiting ExtensionInitializer()");} void ExtensionFinalizer(void* extData) { NSLog(@"===Entering ExtensionFinalizer()"); // 可以做清理工作. NSLog(@"===Exiting ExtensionFinalizer()"); } void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet) { static FRENamedFunction func[] = { MAP_FUNCTION(initialize, NULL)/*, MAP_FUNCTION(setTesting, NULL)*/ }; *numFunctionsToSet = sizeof(func) / sizeof(FRENamedFunction); *functionsToSet = func; } void ContextFinalizer(FREContext ctx) { NSLog(@"===Entering ContextFinalizer()"); // 可以做清理工作 NSLog(@"===Exiting ContextFinalizer()"); } ANE_FUNCTION(initialize){ context=ctx; dispatchStatusEventAsync(@"initialized",@"by kingBook"); return NULL; } /*ANE_FUNCTION(setTesting){ isTesting=getBoolFromFREObject(argv[0]); return NULL; }*/
打包.a文件的方法:
使用Xcode新建Cocoa Touch Static Library项目。
把所有的.h和.m文件都添加到项目,添加需要的framework,添加需要的lib,
在设置里搜BitCode关闭它。
Product-Scheme-Edit Scheme-Build Configuration里设置为Release
Product-Build发布后,在Products文件下可以看到.a文件本来是红色字的变成了黑色字则打包成功(发布时可以从源文件夹中删除它,这时它又变红色,方便查看是否打包成功)
swc文件:用flashBuilder4.7,flashDevelop会出错,
flashBuilder4.7: 链接:http://pan.baidu.com/s/1eRBbzwQ 密码:0xco
打开flashBuilder4.7,文件-新建-Flex库项目,填项目名,配置里只发布手机版则选:手机库
右键src文件夹,新建actionScript文件,如:
package com.qywl.iap{//可以不写包名,如果写包名要放在相应的包下 import flash.events.EventDispatcher; import flash.events.StatusEvent; import flash.external.ExtensionContext; public class IapAne extends EventDispatcher{ public static const EXTENSION_ID:String = "com.qywl.IapAne";//需要与extension.xml中的id一样 private static var _instance:IapAne; private var _extensionContext:ExtensionContext; public var logFun:Function; public static function getInstance():IapAne{ return _instance||=new IapAne(); } public function IapAne(){ _extensionContext=ExtensionContext.createExtensionContext(EXTENSION_ID,null); if(_extensionContext) _extensionContext.addEventListener(StatusEvent.STATUS,onStatus); else throw new Error("===创建ExtensionContext出错,请检查extension ID是否正确"); } private function onStatus(e:StatusEvent):void{ dispatchEvent(e); logFun("===onStatus e.code:",e.code); } public function initialize():void{ _extensionContext.call("initialize"); logFun("===call ios initialize"); } //传参数函数 /*public function setTesting(value:Boolean):void{ _extensionContext.call("setTesting",value); }*/ }; }
注意:
项目属性中的Flex库编译器,附加编译器参数:
-locale en_US -swf-version 14
版本号与extension.xml和platformoptions.xml(可选)中的是对应的关系如下:
Compatible AIR application version | ANE SWF version | Extension namespace |
3.0+ | 10-13 | ns.adobe.com/air/extension/2.5 |
3.1+ | 14 | ns.adobe.com/air/extension/3.1 |
3.2+ | 15 | ns.adobe.com/air/extension/3.2 |
3.3+ | 16 | ns.adobe.com/air/extension/3.3 |
3.4+ | 17 | ns.adobe.com/air/extension/3.4 |
3.5+ | 18 | ns.adobe.com/air/extension/3.5 |
3.6+ | 19 | ns.adobe.com/air/extension/3.6 |
3.7+ | 20 | ns.adobe.com/air/extension/3.7 |
参考:http://help.adobe.com/en_US/air/extensions/WS99209310cacd98cc2d13931c1300f2c84c7-8000.html
写完保存后不需要发布,会自动更新bin文件夹下的.swc文件,复制出来即可
library.swf:只要把swc后缀改成zip打开即可看到
anePackager.bat:
::需要先将flex_sdk_4.6\bin目录添加到Path系统环境变量才可以运行 adt -package -target ane flashane.ane extension.xml -swc aneswc.swc -platform iPhone-ARM library.swf ioslib.a
添加framework配置(platformoptions.xml):
::需要先将flex_sdk_4.6\bin目录添加到Path系统环境变量才可以运行 adt -package -target ane flashane.ane extension.xml -swc aneswc.swc -platform iPhone-ARM library.swf ioslib.a -platformoptions platformoptions.xml
extension.xml:
<extension xmlns="http://ns.adobe.com/air/extension/3.1"> <id>com.qywl.IapAne</id><!--与swc的as类中的EXTENSION_ID对应--> <versionNumber>1</versionNumber> <platforms> <platform name="iPhone-ARM"> <applicationDeployment> <nativeLibrary>ioslib.a</nativeLibrary> <initializer>ExtensionInitializer</initializer> <finalizer>ExtensionFinalizer</finalizer> </applicationDeployment> </platform> </platforms> </extension>
注意:
"<initializer>ExtensionInitializer</initializer>"与.a文件的源文件是对应的
"<finalizer>ExtensionFinalizer</finalizer>"与.a文件的源文件是对应的
platformoptions.xml:
<platform xmlns="http://ns.adobe.com/air/extension/3.1"> <linkerOptions> <option>-framework Storekit</option> </linkerOptions> </platform>
extension.xml与 platformoptions.xml的配置说明参考以下:
http://blog.csdn.net/justxuemin/article/details/50132723
http://help.adobe.com/zh_CN/air/extensions/air_extensions.pdf 39页
打包ANE测试:
把flex_sdk_4.6\bin目录添加到Path系统环境变量,运行anePackager.bat就无出错就可以打包出来flashane.ane
新建AIR for iOS项目,添加.ane到Library Path
编写主文档类Main.as如下:
package { import flash.display.MovieClip; import flash.events.StatusEvent; import flash.events.Event; import flash.text.TextField; public class Main extends MovieClip { private var _txt:TextField; private var _iapAne:IapAne; private function log(...params):void{ var str:String=""; for(var i:int=0;i<params.length;i++){ str+=params[i].toString()+" "; } _txt.appendText(str+"\n"); trace(str); } public function Main() { if(stage)init(); else addEventListener(Event.ADDED_TO_STAGE,init); } private function init(e:Event=null):void{ if(e)removeEventListener(Event.ADDED_TO_STAGE,init); _txt=this.getChildByName("txt") as TextField; // _iapAne=new IapAne(); _iapAne.logFun=log; _iapAne.addEventListener(StatusEvent.STATUS,onStatus); _iapAne.initialize(); log("Main::init();"); } private function onStatus(e:StatusEvent):void{ var str:String="code:"+e.code+","+"level:"+e.level; log(str); } } }
在AIR for iOS Settings中:
设置Certificatey就是.p12文件,填写密码
设置Provisioning profile
填写App ID
最后发布得到.ipa文件,到真机测试即可
完整的iapAneDomo例子:链接:http://pan.baidu.com/s/1dF5TUBR 密码:deqk