【问题标题】:How to create an ANE that will natively display a Floating Window如何创建一个本机显示浮动窗口的 ANE
【发布时间】:2024-06-17 22:15:01
【问题描述】:

如何在 Xcode 中创建本机窗口并将其与 Mobile Flex 应用程序集成。本机窗口的行为应类似于 StageWebView 组件,其中本机内容浮动在 Flex 应用程序其余部分上方的矩形区域中。

【问题讨论】:

    标签: ios xcode apache-flex adobe air-native-extension


    【解决方案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];
      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;
      
      } // 上下文终结器()。 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;
      FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * 1);
      func[0].name = (const uint8_t*) "openFloatingWindow";
      func[0].functionData = NULL;
      func[0].function = &openFloatingWindow;
      
      *functionsToSet = func;
      
      } // ExtInitializer() void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet) { NSLog(@"ExtInitializer"); *extDataToSet = NULL; *ctxInitializerToSet = &ContextInitializer; *ctxFinalizerToSet = &ContextFinalizer; } // ExtFinalizer() void ExtFinalizer(void* extData) { NSLog(@"ExtFinalizer"); // 在这里进行清理。 返回; }
    • 将 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)
    • 转到项目构建设置并修改以下标志(未能这样做会导致分段错误。我花了一段时间才弄清楚。希望这是我更改的所有标志):
      1. 目标设备系列 = iPhone/iPad
      2. Mach-O 类型 = 静态库
      3. 其他链接器标志 = -OjbC –v
      4. 在 Info.plist 文件中展开构建设置 = 否
      5. 启用与共享库的链接 = 否
    • 构建 Xcode 静态库
    • 现在,转到 FlashBuilder 并创建一个 Flex 库项目。确保包含 Adob​​e 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 方库及其搜索路径:

      5.0平台>
    • 现在,在 FlashBuilder 中,创建一个示例测试应用程序项目。转到项目属性。在 Flex 构建路径中,确保添加了 ane。同样在 Flex Build Packaging -> Apple iOS -> Native extensions 下,ANE 被添加到那里并检查包。还要在本机扩展下添加 Apple iOS SDK 文件夹。最后,检查扩展名是否添加到 -app.xml 文件中。

    • 在 FlashBuilder 中,使用适当的打包设置在设备上创建调试配置。仔细检查本机扩展是否包含并打包。清理项目并调试。如果一切顺利,将弹出“等待调试连接”窗口。在 iPad 上安装并启动应用程序。

    希望对你有帮助

    C

    【讨论】:

    • 这真是太棒了……谢谢克里斯托。你救了我几个星期追逐自己的尾巴。这也适用于 Xcode 6。
    最近更新 更多