[杂谈] SDKTransform 试用笔记

SDKTransform 是 RadStudio 10 Berlin (后面称Berlin)里带的转换工具,可以将 iOS 或 OSX SDK 里的头文件转换为 Delphi 的接口文件。它是一个命令行工具,所以,需要你手动去在命令行下运行。

要使用它,你需要:

  • 到 CLang 的官方去自行下载 CLang,然后安装,并记录下目录。
  • 从 App Store 中安装 xcode。
  • 在 OSX 上安装并启动 PAServer,具体步骤参考[译]RAD Studio 移动开发(西雅图版)-在Mac(iOS)上配置你的开发环境
  • 配置你的 IDE 连接到 OSX 上的 PAServer,具体步骤参考:[译]RAD Studio 移动开发(西雅图版)- 配置你 Windows PC上的开发环境(iOS)
  • 到安装目录的 bin 目录下,找到 SDKTransformRun.bat,然后用记事本修改其中的部分内容:
    • 修改 CLang 的路径,找到下面这句:
      set CLANG=c:\clang3.5\llvm\tools\clang
      改成你自己的路径。实际上它用到的是 CLANG 里的头文件,我们可以直接就将它调整为 CLang 的头文件路径。这块我是改成了:
      set CLANG=C:\LLVM\lib\clang\3.8.0\include
      所以,后面的:
      “%CLANG%”\lib\Headers\
      让我改成了:
      “%CLANG%”
    • 修改 iOS SDK 的本地缓存路径,默认它位于 %userprofile%\Documents\Embarcadero\Studio\SDKs 下面,如我的就是:
      C:\Users\[我的用户名]\Documents\Embarcadero\Studio\SDKs\iPhoneOS9.3.sdk
      所以,找到:
      set SDK_ROOT=c:\SDKs\iPhoneOS8.3.sdk
      修改为:
      set SDK_ROOT=C:\Users\rad10.1\Documents\Embarcadero\Studio\SDKs\iPhoneOS9.3.sdk
    • 同样,修改 OSX 的 SDK 路径(如果需要)
  • 现在添加我们要编译的 iOS 框架(以 HealthKit 为例)
    • 进入 Tools -> Options ->Environment Options->SDKManager;
    • 找到我们的 iOS 配置:
      iosaddframe
    • 点击右侧的新建图标:
      iosnewframe
    • 在弹出的对话框中加入要转换的框架代码,如下图所示:
      addhealthkit
      【注意】Path type 不能选中任何一项。你可以先随意选择一个 Frameworks 下的框架,然后再选择新建按钮。
    • 选择 OK 完成添加。
    • 选择 Options 对话框中的 Update Local File Cache ,更新本地缓存。
  • 进入命令行, SDKTransform IOS –out:[pas 文件输出目录] 来生成接口文档,如:
    SdkTransformRun.bat IOS –out:c:\Temp
  • 等待转换结束,你会发现它生成了一堆Pas 接口文件,这里我们只需要 iOSapi.HealthKit.pas。
  • 新建一个FMX 空白工程,目标平台设置为iOS。
  • 将 iOSapi.HealthKit.pas  复制到工程目录。
  • 在 Unit1.pas 中的 uses 里,加入iOSapi.HealthKit.pas。
  • Ctrl+F9 编译工程,编译器会告诉你一堆错误,不要害怕,现在需要人工干预的时刻到了。
    • 移除到Macapi.*的引用;
    • 加入Macapi.ObjectiveC 的引用,最终的 uses 部分如下:
      uses
        Macapi.ObjectiveC,
        iOSapi.CocoaTypes,
        iOSapi.Foundation;
    • 移除 NSInteger = int; 这一行,NSInteger 在前面引用的单元已经定义;
    • 同样移除 NSUInteger = unsigned int; 这一行
    • 修改 instancetype = id; 为 instancetype = Pointer;
    • 修改 BOOL = signed char; 为 BOOL = BYTE;
    • 修改:
      THealthKitWithBlock = procedure(param1: HKStatistics; param2: signed char * ) of object;
      为:
      THealthKitWithBlock = procedure(param1: HKStatistics;param2: MarshaledAString) of object;
    • 修改:
      function predicateForObjectsWithMetadataKeyOperatorTypeValue(key: NSString; operatorType: NSPredicateOperatorType; value: id): NSPredicate; cdecl;
      为:
      function predicateForObjectsWithMetadataKeyOperatorTypeValue(key: NSString; operatorType: NSPredicateOperatorType; value: Pointer): NSPredicate; cdecl;
    • 修改:
      procedure setDelegate(delegate: id); cdecl;
      function delegate: id; cdecl;
      中的 id 为 Pointer。

OK,现在就可以正常编译和使用 iOSapi.HealthKit 单元了。

简单总结下步骤:

  • 添加要转换的 Framework;
  • 运行 SDKTranformRun 来转换生成接口文件;
  • 手动修正接口文件中的错误;
    • instancetype 类型转换为 Pointer
    • id 类型转换为 Pointer
    • 移除掉已经定义的引用
    • 修正未识别的类型
  • 编译并运行你的程序吧。
分享到: