Skip to content

构建一个功能完整的 PDF 阅读器(UI Extensions)

本文介绍如何基于 UI Extensions Component 快速构建一个功能完整的 PDF 阅读器(包含内置工具栏与常用功能模块 UI)。

说明

如需仅展示 PDF(不含内置 UI),请参考:构建一个功能基础的 PDF 阅读器(PDFViewCtrl)

前置条件

  1. 完成 集成福昕 PDF SDK(含工程创建、SDK 集成与授权初始化)。
  2. 确认已添加 uiextensionsDynamic.framework(参考:启用 UI Extensions)。

步骤 1:接入 UI Extensions,构建"完整阅读器"

核心思路是:

  1. 创建 FSPDFViewCtrl 作为渲染与交互容器。
  2. 创建 UIExtensionsManager 并绑定到 FSPDFViewCtrl
  3. 通过 FSPDFViewCtrl.openDoc 打开文档。

Objective-C

objc
#import <FoxitRDK/FSPDFViewControl.h>
#import <FoxitRDK/FSPDFObjC.h>
#import <uiextensionsDynamic/UIExtensionsManager.h>

@interface ViewController () <IDocEventListener>
@property (nonatomic, strong) FSPDFViewCtrl *pdfViewCtrl;
@property (nonatomic, strong) UIExtensionsManager *extensionsMgr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 初始化 FSPDFViewCtrl
    self.pdfViewCtrl = [[FSPDFViewCtrl alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.pdfViewCtrl];

    // 使用 JSON 配置文件初始化 UIExtensionsManager(可选)
    NSString *configPath = [[NSBundle mainBundle] pathForResource:@"uiextensions_config" ofType:@"json"];
    NSData *configData = [NSData dataWithContentsOfFile:configPath];
    self.extensionsMgr = [[UIExtensionsManager alloc] initWithPDFViewControl:self.pdfViewCtrl
                                                              configuration:configData];
    self.pdfViewCtrl.extensionsManager = self.extensionsMgr;

    // 注册文档事件监听
    [self.pdfViewCtrl registerDocEventListener:self];

    // 打开 PDF 文档
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"pdf"];
    [self.pdfViewCtrl openDoc:path password:nil completion:^(FSErrorCode error) {
        if (error != FSErrSuccess) {
            NSLog(@"打开文档失败,错误码: %d", (int)error);
        }
    }];
}

@end

Swift

swift
import FoxitRDK
import uiextensionsDynamic

class ViewController: UIViewController, IDocEventListener {

    var pdfViewCtrl: FSPDFViewCtrl!
    var extensionsMgr: UIExtensionsManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 初始化 FSPDFViewCtrl
        pdfViewCtrl = FSPDFViewCtrl(frame: view.bounds)
        view.addSubview(pdfViewCtrl)

        // 使用 JSON 配置文件初始化 UIExtensionsManager(可选)
        let configPath = Bundle.main.path(forResource: "uiextensions_config", ofType: "json")
        let configData = configPath.flatMap { try? Data(contentsOf: URL(fileURLWithPath: $0)) }
        extensionsMgr = UIExtensionsManager(pdfViewControl: pdfViewCtrl, configuration: configData)
        pdfViewCtrl.extensionsManager = extensionsMgr

        // 注册文档事件监听
        pdfViewCtrl.register(self as IDocEventListener)

        // 打开 PDF 文档
        if let path = Bundle.main.path(forResource: "Sample", ofType: "pdf") {
            pdfViewCtrl.openDoc(path, password: nil) { error in
                if error != .errSuccess {
                    print("打开文档失败,错误码: \(error.rawValue)")
                }
            }
        }
    }
}

说明

UIExtensionsManager 支持两种初始化方式:

  • initWithPDFViewControl: — 使用默认配置。
  • initWithPDFViewControl:configuration: — 通过 JSON 配置文件自定义启用的模块与 UI 设置。

JSON 配置详情请参考 通过配置文件自定义 UI

步骤 2:配置 RMS 支持(可选)

如果您的应用需要打开 RMS 保护的文档,需要配置 Microsoft Azure 应用注册信息:

objc
[self.pdfViewCtrl setRMSAppClientId:@"YOUR_CLIENT_ID" redirectURI:@"YOUR_REDIRECT_URI"];

对于使用 iOS 13+ 多窗口(Scenes)的应用,还需要在 SceneDelegate 中转发 MSAL 回调:

objc
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    UIOpenURLContext *context = URLContexts.anyObject;
    [FSPDFViewCtrl handleMSALResponse:context.URL sourceApplication:context.options.sourceApplication];
}

步骤 3:运行与验证

  1. 将测试文件(例如 Sample.pdf)添加到 Xcode 工程的 Bundle Resources 中。
  2. 选择模拟器或真机设备,点击 Product → Run 运行应用。

运行成功后,应用将展示带有完整工具栏的 PDF 阅读器,支持注释、搜索、书签、表单等内置功能。