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 路径(如果需要)
- 修改 CLang 的路径,找到下面这句:
- 现在添加我们要编译的 iOS 框架(以 HealthKit 为例)
- 进入命令行, 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
- 移除掉已经定义的引用
- 修正未识别的类型
- 编译并运行你的程序吧。