6

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

4

1 回答 1

12

作为一名弹性程序员,这是一个乏味的过程,我花了数周时间才弄清楚。希望这将有助于其他一些 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 方库及其搜索路径:

    <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

于 2012-01-23T16:20:23.540 回答