如何在 Xcode 中创建本机窗口并将其与 Mobile Flex 应用程序集成。本机窗口的行为类似于 StageWebView 组件,其中本机内容浮动在 Flex 应用程序其余部分上方的矩形区域中。
1 回答
作为一名弹性程序员,这是一个乏味的过程,我花了数周时间才弄清楚。希望这将有助于其他一些 Xcode 新手。
首先,你必须对Objective-C和Xcode有基本的了解。您应该能够创建一个简单的 Hello World Xcode 程序。一旦您知道如何执行此操作,您将看到对于每个可视窗口,您通常都有一个 xib 文件、一个头文件和一个实现文件。我发现开始编写一个普通的 Xcode 应用程序更容易,然后一旦它工作并看起来应该,你手动将这 3 个文件(当然还有帮助文件)拉到你的 Xcode 静态库项目中。因此,继续前进,我将假设您已经完成了这一步。以下是有关如何使用 ANE 集成 Xcode 和 Flex mobile 的一些分步说明:
- 打开 XCode。创建新项目。iOS -> Cocoa Touch 静态库。我将我的项目称为 FWAne
删除 FWAne.h 文件。将 FWAne.m 文件的内容替换为以下内容:
'#import "FloatingWindow.h" '#import "FlashRuntimeExtensions.h" FREObject openFloatingWindow(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] ) { uint32_t parm0Length,parm1Length,parm2Length,parm3Length,parm4Length,parm5Length,parm6Length,parm7Length,parm8Length,parm9Length,parm10Length,parm11Length,parm12Length,parm13Length; 常量 uint8_t *uparm0,*uparm1,*uparm2,*uparm3,*uparm4,*uparm5,*uparm6,*uparm7,*uparm8,*uparm9,*uparm10,*uparm11,*uparm12,*uparm13; FREGetObjectAsUTF8(argv[0], &parm0Length, &uparm0); NSString* parm0 = [NSString stringWithUTF8String:(char*)uparm0]; // FREGetObjectAsUTF8(argv[1], &parm1Length, &uparm1); // NSString* parm1 = [NSString stringWithUTF8String:(char*)uparm1]; // FREGetObjectAsUTF8(argv[2], &parm2Length, &uparm2); // NSString* parm2 = [NSString stringWithUTF8String:(char*)uparm2]; // FREGetObjectAsUTF8(argv[3], &parm3Length, &uparm3); // NSString* parm3 = [NSString stringWithUTF8String:(char*)uparm3]; // FREGetObjectAsUTF8(argv[4], &parm4Length, &uparm4); // NSString* parm4 = [NSString stringWithUTF8String:(char*)uparm4]; // FREGetObjectAsUTF8(argv[5], &parm5Length, &uparm5); // NSString* parm5 = [NSString stringWithUTF8String:(char*)uparm5]; // FREGetObjectAsUTF8(argv[6], &parm6Length, &uparm6); // NSString* parm6 = [NSString stringWithUTF8String:(char*)uparm6]; // FREGetObjectAsUTF8(argv[7], &parm7Length, &uparm7); // NSString* parm7 = [NSString stringWithUTF8String:(char*)uparm7]; // FREGetObjectAsUTF8(argv[8], &parm8Length, &uparm8); // NSString* parm8 = [NSString stringWithUTF8String:(char*)uparm8]; // FREGetObjectAsUTF8(argv[9], &parm9Length, &uparm9); // NSString* parm9 = [NSString stringWithUTF8String:(char*)uparm9]; // FREGetObjectAsUTF8(argv[10], &parm10Length, &uparm10); // NSString* parm10 = [NSString stringWithUTF8String:(char*)uparm10]; // FREGetObjectAsUTF8(argv[11], &parm11Length, &uparm11); // NSString* parm11 = [NSString stringWithUTF8String:(char*)uparm11]; // FREGetObjectAsUTF8(argv[12], &parm12Length, &uparm12); // NSString* parm12 = [NSString stringWithUTF8String:(char*)uparm12]; // FREGetObjectAsUTF8(argv[13], &parm13Length, &uparm13); // NSString* parm13 = [NSString stringWithUTF8String:(char*)uparm13];
} // 上下文终结器()。 void ContextFinalizer(FREContext ctx) { NSLog(@"ContextFinalizer"); //这里清理。 返回; } // 上下文初始化器() void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) { NSLog(@"ContextInitializer"); *numFunctionsToTest = 1;NSLog(@"Initializing delegate and window"); id delegate = [[UIApplication sharedApplication] delegate]; UIWindow *window = [delegate window]; NSLog(@"Creating FloatingWindow"); FloatingWindow* fw = [[FloatingWindow alloc] initWithNibName:@"FloatingWindow" bundle:nil]; NSLog(@"Adding FloatingWindow"); [window addSubview:fw.view]; NSLog(@"Setting frame size"); fw.view.frame = CGRectMake(100, 100, 200, 200); NSLog(@"Done openFloatingWindow"); return NULL;
} // ExtInitializer() void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet) { NSLog(@"ExtInitializer"); *extDataToSet = NULL; *ctxInitializerToSet = &ContextInitializer; *ctxFinalizerToSet = &ContextFinalizer; } // ExtFinalizer() void ExtFinalizer(void* extData) { NSLog(@"ExtFinalizer"); // 在这里进行清理。 返回; }FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * 1); func[0].name = (const uint8_t*) "openFloatingWindow"; func[0].functionData = NULL; func[0].function = &openFloatingWindow; *functionsToSet = func;
将 FlashRuntimeExtensions.h 添加到您的 Xcode 项目中。此文件位于 /Applications/Adobe Flash Builder 4.6/sdks/4.6.0/include 文件夹下
- 将 FloatingWindow.h 和 FloatingWindow.m(或与您的 xib 所有者关联的任何文件)添加到您的 Xcode 项目中。
- 您可能还需要将 UIKit 框架添加到 xcode 项目(/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/UIKit.framework)
- 转到项目构建设置并修改以下标志(未能这样做会导致分段错误。我花了一段时间才弄清楚。希望这是我更改的所有标志):
- 目标设备系列 = iPhone/iPad
- Mach-O 类型 = 静态库
- 其他链接器标志 = -OjbC –v
- 展开 Info.plist 文件中的构建设置 = 否
- 启用与共享库的链接 = 否
- 构建 Xcode 静态库
- 现在,转到 FlashBuilder 并创建一个 Flex 库项目。确保包含 Adobe Air 库
创建将使用 ExtensionContext 将 Flex 代码连接到 Xcode 代码的类,如下所示:
软件包 fwane { 导入 flash.events.EventDispatcher; 导入 flash.events.StatusEvent; 导入 flash.external.ExtensionContext;
}public class FWAne { private static const EXTENSION_ID : String = "fwane.FWAne"; private var context : ExtensionContext; public function FWAne() { context = ExtensionContext.createExtensionContext( EXTENSION_ID, null ); if (context == null) { trace("WARNING: ExtensionContext cannot initialize"); } } public function openFloatingWeendow(fileName : String) : void { trace("Calling openFloatingWeendow"); context.addEventListener( StatusEvent.STATUS, onAneWinHander ); trace("Invoking native call"); context.call( "openFloatingWindow", fileName); trace("Returning from openFloatingWeendow"); } private function onAneWinHander( event : StatusEvent ) : void { trace(event.level); } }
构建 FWAne swc
接下来,您将需要一个构建脚本来编译您的 ANE。这是我的 build.sh 脚本:
导出 XLIB="/Users/christo.smal/Library/Developer/Xcode/DerivedData/wherever-lib.a" 出口 CERT="/wherever/if/you/want/to/sign/ane.p12" 导出 FLEXLIBPATH="../Path/of/flex/library/project" 导出 XIBPATH="/Path/of/where/xib/files/are" 导出 SWCFNAME="FWAne.swc" 出口 ANEFNAME="FWAne.ane" ls -la $XLIB echo 正在复制文件... rm -rf 调试/* cp $FLEXLIBPATH/src/extension.xml 。 cp $FLEXLIBPATH/bin/$SWCFNAME 。 cp $XLIB ./debug '#复制图片等资源文件到debug文件夹 cp /path/to/my/images/referenced/from/xcode/*.png ./debug echo 编译xib的 cp $XIBPATH/*.xib ./debug cp /wherever/FloatingWindow.xib ./debug /Developer/usr/bin/ibtool --errors --warnings --notices --output-format human-readable-text --compile debug/FloatingWindow.nib debug/FloatingWindow.xib --sdk /Developer/Platforms/iPhoneOS。平台/开发者/SDKs/iPhoneOS5.0.sdk rm -rf 调试/*.xib echo 提取 library.swc ... cp $SWCFNAME kak cd kak 解压 -xo $SWCFNAME cp -X library.swf ../debug 光盘.. echo 正在复制更多文件... rm -rf 调试/*.ane cp extension.xml 调试 回声大厦 ANE ... '# -package -target ane / extension.xml -swc -platform -C 。 /Applications/Adobe\ Flash\ Builder\ 4.6/sdks/4.6.0/bin/adt -package -target ane debug/unsigned.ane extension.xml -swc $SWCFNAME -platform iPhone-ARM -platformoptions ios-platformoptions.xml - C 调试。 echo 签名 ANE ... '#/Applications/Adobe\ Flash\ Builder\ 4.6/sdks/4.6.0/bin/adt -sign -storetype pkcs12 -keystore $CERT -storepass password -target ane debug/unsigned.ane $ANEFNAME cp debug/unsigned.ane $ANEFNAME 回声完成
关于我的构建脚本需要注意的重要一点:xib 被编译为 nib,然后这些 nib 与其他资源文件(例如图像)一起包含在 ANE 中。请记住,静态库不能包含资源文件。
您还需要一个 ios-platformoptions.xml 文件。这是包括您需要的所有框架。您还可以在此处包含任何其他 3rd 方库及其搜索路径:
<platform xmlns="http://ns.adobe.com/air/extension/3.1"> <sdkVersion>5.0</sdkVersion> <链接器选项> <option>-框架基础</option> <option>-framework UIKit</option> <option>-framework QuartzCore</option> <option>-framework CoreGraphics</option> <!--option>-lthirdparty</option> <option>-L/searhPath/for/thirdlibrary</option--> </linkerOptions> </平台>
现在,在 FlashBuilder 中,创建一个示例测试应用程序项目。转到项目属性。在 Flex 构建路径中,确保添加了 ane。同样在 Flex Build Packaging -> Apple iOS -> Native extensions 下,ANE 被添加到那里并检查包。还要在本机扩展下添加 Apple iOS SDK 文件夹。最后,检查扩展名是否已添加到 -app.xml 文件中。
- 在 FlashBuilder 中,使用适当的打包设置在设备上创建调试配置。仔细检查本机扩展是否包含并打包。清理项目并调试。如果一切顺利,将弹出“等待调试连接”窗口。在 iPad 上安装并启动应用程序。
希望这可以帮助
C