はじめに (対象読者・この記事でわかること)

この記事は、まだObjective-Cで稼働しているレガシーなiOSアプリをメンテナンスしている開発者、あるいはSwiftで書かれた便利なライブラリをObjective-Cから使いたいと考えている方を対象としています。
具体的には、Swift製のQRScannerライブラリをObjective-Cプロジェクトに組み込み、QRコードの読み取り機能を安全に追加する方法を解説します。読み終えると、橋渡しヘッダ(Bridging-Header)の設定からSwiftクラスの呼び出し、ビルドエラーの回避まで、一連の手順が確実に実行できるようになります。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 - Objective-Cの基本的な文法とXcodeプロジェクトの構成 - CocoaPodsまたはSwift Package Managerでのライブラリ追加経験 - iOSアプリでカメラ使用許可(Info.plist)を設定した経験

Swift製ライブラリをObjective-Cで使う必然性

Swiftが登場して10年が経ち、ほとんどの新規開発はSwiftで行われています。しかし、App Storeにリリース済みの大規模Objective-Cアプリを完全にSwiftに置き換えるには、リスクとコストがかかりすぎます。
そんな中、QRコード読み取り機能を追加したい要件が発生した場合、GitHubで検索すると「QRScanner」や「CodeScanner」など、Swiftで書かれた軽量で活発にメンテされているライブラリが目立ちます。Objective-C用のレガシーライブラリを探すより、Swift製をそのまま流用できる仕組みを作る方が、長期的にも安全です。本記事では、その橋渡しのノウハウを余すことなく共有します。

Swift製QRScannerライブラリをObjective-Cに組み込む実装手順

ステップ1:ライブラリをプロジェクトに追加する

今回はCocoaPodsで導入する例を示します。Podfileに以下を追記し、pod installを実行してください。

Ruby
pod 'QRScanner', '~> 5.0'

インストール後、.xcworkspaceを開き、Build SettingsでDefines ModuleYESに設定します。これが橋渡しヘッダを生成する第一歩です。

ステップ2:橋渡しヘッダ(Bridging-Header)を設定する

Xcodeの「New File」からHeader Fileを作成し、プロジェクト名-Swift-bridging-header.hという名前で保存します。中身は最小限に留め、Swiftのフレームワークだけをimportしておきます。

Objective-c
// MyApp-Swift-bridging-header.h #import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h>

次に、Build Settingsの「Swift Compiler - General」セクションで
Objective-C Bridging Headerに先ほどのファイルパスを記載します。

ステップ3:SwiftクラスをObjective-Cから呼び出す

QRScannerライブラリのSwiftクラスをObjective-Cで使うため、継承ラッパーを書きます。プロジェクトに新しいSwiftファイルQRScannerWrapper.swiftを追加するとXcodeがMyApp-Bridging-Header.hを生成するので、そこに継承ラッパーを記述します。

Swift
import QRScanner @objc(QRScannerWrapper) public class QRScannerWrapper: NSObject { @objc public static func scan(on viewController: UIViewController, completion: @escaping (String?) -> Void) { let scanner = QRScannerController() scanner.onResult = { result in completion(result) } viewController.present(scanner, animated: true) } }

@objc属性を付けることで、Objective-CからQRScannerWrapperクラスが見えるようになります。

ハマった点やエラー解決

エラー1:「Use of undeclared identifier 'QRScannerWrapper'」

多くの場合、Build SettingsのDefines ModuleNOになっているか、モジュール名が異なっています。Product Module Nameを確認し、import文で#import <MyApp-Swift.h>とした際のモジュール名と一致させてください。

エラー2:カメラプライバシー表示でクラッシュ

iOS 17以降、Info.plistにNSCameraUsageDescriptionがないとクラッシュします。以下を追加してください。

Xml
<key>NSCameraUsageDescription</key> <string>QRコードを読み取るためにカメラを使用します。</string>

エラー3:Swift標準ライブラリが見つからない

レガシーなObjective-CプロジェクトにSwiftファイルを初めて追加すると、Swift標準ライブラリがリンクされないことがあります。Build Phasesの「Link Binary With Libraries」にlibswiftCore.tbdを明示的に追加すると解消します。

解決策

上記3つのエラーに対して、以下の対応をまとめて行うと確実です。

  1. Build Settingsで「Always Embed Swift Standard Libraries」をYESにする
  2. モジュール名を統一し、Clean → Buildする
  3. Info.plistにプライバシー説明文を追加し、実機でテストする

これらを守るだけで、Objective-CからSwift製QRScannerライブラリをシームレスに利用できます。

まとめ

本記事では、Objective-CのレガシープロジェクトにSwift製QRScannerライブラリを組み込む方法を解説しました。

  • 橋渡しヘッダの設定と@objc属性を使ったラッパー作成
  • CocoaPods導入後に起きやすいビルドエラーの回避法
  • iOS 17以降のプライバシー設定とSwift標準ライブラリの埋め込み

この記事を通して、Objective-Cコードを大幅に書き換えることなく、最新のSwiftライブラリを安全に活用できることが伝われば幸いです。
次回は、SwiftUIで書かれたUIコンポーネントをObjective-CのViewControllerに組み込む方法を取り上げる予定です。

参考資料