PAYATHON 2026

如何在 iOS 中使用 IDTECH sdk?

支付阿杰

结论

iOS 不能像 Android 引用 .jar 那样直接引用 .xcproj。首先要确认这个工程能够生成什么产物:

  • .framework 或 .xcframework
  • 静态库 .a 及配套头文件
  • 可作为依赖参与编译的源码库 Target
  • 仅用于演示 SDK 的示例工程

如果 IDTECH 提供官方 .xcframework,优先使用该文件。如果手中只有 .xcproj,可以把它加入 Workspace,再让自己的 Cocoa Touch Library Target 依赖其中的库 Target。

如果工程只能生成 App,它通常只是示例项目,不能直接作为 SDK 使用。此时需要向 IDTECH 获取正式的 iOS SDK 包和配套文档。

先检查 IDTECH 工程

使用 Xcode 打开 .xcproj,在项目的 Targets 中检查以下内容:

  1. Product Type 是 Framework、Static Library 还是 Application。
  2. Build Phases > Headers 中是否配置了 Public Headers。
  3. Products 下能否生成 .framework、.xcframework 或 .a。
  4. 工程是否包含 .bundle、配置文件、图片或其他运行时资源。
  5. 支持哪些平台和架构,例如 arm64 和 iOS Simulator。
  6. 是否依赖系统框架或第三方库。

如果 Product Type 是 Application,就不能直接链接它的 App Target。应先查找项目中真正的库 Target。如果项目内没有库 Target,应获取厂商发布的 SDK,不要自行从示例工程中拆取代码。

方式一:集成官方 XCFramework

.xcframework 更适合分发二进制 SDK,因为一个文件可以同时包含真机和模拟器版本。

将文件拖入自己的 Xcode 项目后:

  1. 勾选需要使用它的 Target。
  2. 在 General > Frameworks, Libraries, and Embedded Content 中添加该文件。
  3. 动态框架通常选择 Embed & Sign。
  4. 静态框架通常选择 Do Not Embed。
  5. 按照 SDK 文档添加所需的系统框架、资源文件和权限。

Objective-C 通常这样导入:

#import <IDTechSDK/IDTechSDK.h>

Swift 通常这样导入:

import IDTechSDK

其中的 IDTechSDK 只是模块名示例,必须替换为 Xcode 中显示的实际模块名。不要根据文件名猜测模块名或 API。

方式二:直接依赖 XCProject 中的库 Target

如果 .xcproj 确实包含可编译的 Framework 或 Static Library Target,可以把它和自己的项目放进同一个 Workspace。

创建 Workspace

在 Xcode 中创建或打开一个 .xcworkspace,然后加入以下项目:

  • 自己的 Cocoa Touch Library 项目
  • IDTECH 的 .xcproj

不能只把 .xcproj 文件复制到目录中,还要确保它出现在 Workspace 的项目导航器里。

添加 Target 依赖

选择自己的库 Target,进入:

Build Phases > Target Dependencies

添加 IDTECH 工程中的 Framework 或 Static Library Target。

然后在:

Build Phases > Link Binary With Libraries

添加该 Target 生成的产品,例如:

IDTechSDK.framework

或者:

libIDTechSDK.a

这样配置后,Xcode 会先构建 IDTECH 库,再构建自己的库。

配置头文件

如果 IDTECH Target 已正确声明 Public Headers,通常可以使用模块化导入:

#import <IDTechSDK/SomePublicHeader.h>

如果生成的是传统静态库,可能还要配置:

  • Header Search Paths
  • Library Search Paths
  • Other Linker Flags

如果 SDK 使用了 Objective-C Category,常见的链接参数是:

-ObjC

不要无条件添加 -all_load 或 -force_load,否则可能产生重复符号。只有 SDK 文档明确要求,或确实出现 Category 未加载问题时,才应使用这些参数。

方式三:集成静态库和头文件

如果厂商提供的是以下文件:

libIDTechSDK.a
Headers/
Resources/

需要将 .a 和公开头文件加入项目,并在自己的 Target 中链接该静态库。

Objective-C 示例:

#import "IDTechSDK.h"

@implementation PaymentReaderAdapter

- (void)configureReader
{
    // 在这里调用 IDTECH 文档中真实存在的初始化 API。
}

@end

这里没有填写具体的初始化方法,因为原始信息没有提供 IDTECH SDK 的版本和公开 API。不同产品线、读卡器型号和 SDK 版本可能采用不同的初始化流程,不能假定某个单例或方法一定存在。

如果自己的库需要向上层暴露 IDTECH 类型,可以在公开头文件中导入 SDK:

#import <Foundation/Foundation.h>
#import <IDTechSDK/IDTechSDK.h>

@interface PaymentReaderAdapter : NSObject
@end

这样会使 IDTECH SDK 成为调用方的公开依赖。更稳妥的做法是仅在 .m 文件或私有头文件中导入 SDK,再通过自己的接口进行封装:

// PaymentReaderAdapter.h
#import <Foundation/Foundation.h>

@interface PaymentReaderAdapter : NSObject

- (void)startWithCompletion:(void (^)(NSError *error))completion;

@end
// PaymentReaderAdapter.m
#import "PaymentReaderAdapter.h"
#import <IDTechSDK/IDTechSDK.h>

@implementation PaymentReaderAdapter

- (void)startWithCompletion:(void (^)(NSError *error))completion
{
    // 使用对应版本文档中的 IDTECH API 完成设备初始化。
}

@end

这种设计可以减少上层项目对特定 SDK API 的依赖。

Swift 调用 Objective-C SDK

如果 IDTECH SDK 使用 Objective-C 编写并支持 Clang Module,Swift 一般可以直接导入:

import IDTechSDK

final class PaymentReaderAdapter {
    func start() {
        // 调用该 SDK 版本公开的真实 API。
    }
}

如果 SDK 没有模块定义,App 项目可以通过 Bridging Header 导入:

#import "IDTechSDK.h"

Framework Target 不应依赖 App 的 Bridging Header。开发 Cocoa Touch Framework 时,应优先使用模块化头文件或 Module Map,也可以通过自己的 Objective-C 包装类调用 SDK,再将包装后的接口暴露给 Swift。

如果自己的库通过 CocoaPods 分发

需要在 .podspec 中声明 IDTECH SDK 的交付方式。对于允许随库一起分发的二进制 Framework,可以这样配置:

Pod::Spec.new do |s|
  s.name = 'PaymentReaderAdapter'
  s.version = '1.0.0'
  s.source_files = 'Sources/**/*.{h,m,swift}'
  s.vendored_frameworks = 'Vendor/IDTechSDK.xcframework'
end

如果使用静态库:

s.vendored_libraries = 'Vendor/libIDTechSDK.a'
s.public_header_files = 'Vendor/Headers/**/*.h'

能否把 IDTECH 二进制文件放入自己的 Pod,取决于厂商的许可协议。如果协议不允许重新分发,应要求集成方自行安装 SDK,并在文档中说明相关依赖,不能直接将厂商文件打包发布。

常见构建问题

file was built for ... which is not the architecture being linked

这个错误表示库中缺少当前构建目标所需的架构。常见情况是库只包含真机 arm64 版本,却被用于模拟器构建。

正确的处理方式是获取同时支持真机和模拟器的 .xcframework。不要通过删除架构或长期设置 EXCLUDED_ARCHS 来掩盖问题。

Undefined symbols for architecture arm64

常见原因包括:

  • SDK 二进制没有加入 Link Binary With Libraries
  • 缺少 SDK 依赖的系统框架
  • 静态库的链接顺序或链接参数有误
  • 头文件版本与二进制版本不一致
  • Objective-C Category 没有通过 -ObjC 加载

可以根据未定义符号所属的类或框架逐项检查。

No such module 'IDTechSDK'

这个错误通常表示 SDK 不是模块化 Framework,或者当前 Target 没有正确链接它。需要检查:

  • Framework 是否已加入当前 Target
  • Framework Search Paths 是否正确
  • 模块名是否拼写正确
  • Defines Module 是否为 YES
  • Public Headers 是否配置完整

真机正常、模拟器失败

这种情况通常与业务代码无关,而是 SDK 没有提供模拟器所需的 Slice。硬件读卡器 SDK 也可能只支持真机运行,具体限制要以相应版本的 IDTECH 文档为准。

还要检查权限和运行时资源

支付终端或读卡器 SDK 可能会使用 Bluetooth、USB、音频接口或网络,具体要求取决于设备型号。只有官方文档明确要求时,才应在 Info.plist 中添加相应的权限说明,例如蓝牙权限。

还要确认以下内容是否需要随 App 一起打包:

  • 资源 .bundle
  • 配置文件
  • 固件文件
  • 设备协议声明
  • Keychain 或网络安全配置

即使 SDK 已封装进自己的动态 Framework,最终 App 仍须链接并嵌入它的运行时依赖。中间库能够编译通过,不代表最终 App 已完成正确打包。

推荐的处理顺序

先在 IDTECH 提供的示例工程中确认 SDK 可以正常构建,再找出实际的库产物和公开头文件。之后优先获取官方 .xcframework,将其链接到自己的 Cocoa Touch Library,并通过一层包装类隔离厂商 API。

如果现有 .xcproj 中只有示例 App,没有 Framework 或 Static Library Target,它就不能代替正式 SDK。此时应向 IDTECH 索取与设备型号、目标 iOS 版本和 Xcode 版本相匹配的 SDK、集成指南及示例代码。

备注:内容仅供参考。