Swiftでバーコード読み取りを実装する12のステップ – Japanシーモア

Swiftでバーコード読み取りを実装する12のステップ

Swiftを使ったバーコード読み取り実装のサンプルコードと説明の画像Swift
この記事は約26分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

皆さん、バーコードをご存知ですよね。

商品のパッケージなどに印刷されている、縦の線の集まりのあれです。

あれをスマートフォンやPCのカメラで読み取り、情報を取得する技術があります。

今回は、iOSアプリ開発の言語「Swift」を用いて、バーコード読み取りの機能を実装する方法を、実際のコードとともに紹介していきます。

この記事を読めば、Swiftでバーコード読み取りを実装することができるようになります。

特にアプリ開発初心者の方や、バーコード読み取り機能を取り入れたいと考えている方に、ぜひ参考にしていただきたいと思います。

●Swiftとは

Swiftとは、Appleが2014年に公開した新しいプログラミング言語です。

Objective-Cに変わる新しいiOSアプリの開発言語として注目を集め、高速で安全性が高く、書きやすさを追求した言語として広く普及しています。

○Swiftの基本的な特徴

Swiftは次のような特徴を持っています。

  1. 安全性:Swiftは、エラーやバグを生む可能性が低いように設計されています。例えば、nilの値を持つことができない変数を宣言することができるため、ランタイムエラーを減少させることができます。
  2. 高速:C++と同等の、またはそれ以上の性能を持つと言われています。
  3. 直感的なシンタックス:Swiftの文法は直感的で、Pythonのような読みやすさがあります。そのため、コードの可読性が高く、初心者にも学びやすいとされています。
  4. モダン:Swiftは、最新のプログラミング言語設計思想を取り入れており、関数型プログラミングやジェネリクスなどの現代的な機能をサポートしています。
  5. Playground:Swiftには、コードの変更をリアルタイムで確認できるPlaygroundという機能があります。これにより、新しいコードを試したり、アルゴリズムをテストしたりするのが非常に便利です。

●バーコード読み取りとは

バーコードは、商品や書籍、チケットなど、さまざまなアイテムに貼られている縦線のパターンです。

この縦線のパターンには、数字や文字の情報がエンコードされており、専用の読み取り機やスマートフォンのカメラを使って情報をデコード(解読)することができます。

この技術を利用することで、商品の価格情報や在庫情報、書籍のISBN番号など、さまざまな情報を迅速に取得することができます。

特に小売業や物流業では、商品の管理や在庫の確認、出荷の際の情報確認など、効率的な業務遂行のためにバーコード読み取りが欠かせない技術となっています。

Swiftを使用して、アプリ内でこのバーコード読み取り機能を実装することで、ユーザーが手軽に情報を取得したり、特定の情報に基づいてアクションを起こすことができるようになります。

○バーコードの種類と構造

バーコードにはいくつかの種類があり、それぞれが特定の情報を持った線のパターンとして設計されています。

主なバーコードの種類には次のようなものがあります。

  1. EAN:書籍や商品に使用される国際標準のバーコード。EAN-13(13桁)とEAN-8(8桁)の2つの形式があります。
  2. UPC:北米を中心に使用される商品のバーコード。UPC-A(12桁)とUPC-E(8桁)の2つの形式があります。
  3. Code39:業界標準のバーコードとして広く使用されている種類。英数字をエンコードすることができます。
  4. QRコード:二次元のバーコードで、文字や数字だけでなく、URLや連絡先情報もエンコードすることができます。

これらのバーコードは、情報をエンコードするための独自のルールや構造を持っています。

例えば、EAN-13は、最初の2桁が国コード、次の5桁が企業コード、その次の5桁が商品コード、最後の1桁がチェックディジットという構造になっています。

●Swiftでのバーコード読み取りの準備

バーコード読み取りをSwiftで実装する際の第一歩は、適切なライブラリやフレームワークを導入することです。

多くの場合、iOSのアプリケーション開発で使用されるSwiftは、バーコード読み取りのための専用のライブラリを必要とします。

これにより、バーコードの種類や読み取り精度を柔軟に対応させることができます。

○必要なライブラリのインストール

Swiftでのバーコード読み取りをスムーズに実装するためには、「AVFoundation」というフレームワークを使用します。

このフレームワークは、iOSデバイスのカメラやマイクなどのAV関連の機能を利用するためのAPIを提供しています。

まず、新しいSwiftプロジェクトを開始するか、既存のプロジェクトに「AVFoundation」フレームワークを追加する必要があります。

ここでは、CocoaPodsを使用してAVFoundationをプロジェクトに追加するための手順を紹介します。

  1. Terminalを開き、プロジェクトのルートディレクトリに移動します。
  2. pod init コマンドを実行してPodfileを生成します。
  3. Podfileをエディタで開き、次のように「AVFoundation」を追加します。
// Podfileの内容
platform :ios, '14.0'
use_frameworks!

target 'YourProjectName' do
    pod 'AVFoundation'
end
  1. Terminalで pod install コマンドを実行して、ライブラリをプロジェクトに追加します。

このコードでは、「AVFoundation」フレームワークをCocoaPodsを使用してプロジェクトに追加する手順を表しています。

この手順を完了すると、Swiftのプロジェクトに必要なライブラリが追加され、バーコード読み取りの実装を始めることができます。

しかし、実際には「AVFoundation」はiOSの標準フレームワークの一部であり、追加のインストールは不要です。

上記の手順は、外部のライブラリやフレームワークを追加する際の一般的な手順を表しています。

これにより、バーコード読み取りの実装に特有のライブラリやフレームワークが必要な場合、同様の手順で追加することができます。

●Swiftでのバーコード読み取りの基本

バーコード読み取りを実現するためには、Swiftの環境設定だけでなく、具体的な実装ステップも重要です。

ここでは、Swiftを使用してバーコード読み取りを実装する際の基本的なステップを取り上げます。

○サンプルコード1:バーコード読み取りの基本設定

まず、バーコード読み取りの基本的な設定を行います。

これには、先ほど導入した「AVFoundation」フレームワークを使用します。

import AVFoundation

class BarcodeScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    var captureSession: AVCaptureSession!
    var previewLayer: AVCaptureVideoPreviewLayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        // カメラのセッションの設定
        captureSession = AVCaptureSession()

        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
        let videoInput: AVCaptureDeviceInput

        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            return
        }

        if captureSession.canAddInput(videoInput) {
            captureSession.addInput(videoInput)
        } else {
            return
        }

        let metadataOutput = AVCaptureMetadataOutput()

        if captureSession.canAddOutput(metadataOutput) {
            captureSession.addOutput(metadataOutput)
            metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            metadataOutput.metadataObjectTypes = [.qr, .ean13, .ean8, .code128]
        } else {
            return
        }

        // 画面表示の設定
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        view.layer.addSublayer(previewLayer)

        // セッションの開始
        captureSession.startRunning()
    }
}

このコードでは、AVFoundationを使用してカメラを起動し、バーコード読み取りのための設定を行っています。

具体的には、カメラのセッションを開始し、バーコードを読み取ることができるようにメタデータの出力を設定しています。

さらに、画面にカメラの映像を表示するためのレイヤーも設定しています。

○サンプルコード2:カメラの設定とバーコードの認識

次に、カメラからの映像にバーコードが映し出されたときに、その情報を認識して取得する方法を設定します。

extension BarcodeScannerController {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        captureSession.stopRunning()

        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            guard let stringValue = readableObject.stringValue else { return }
            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            foundBarcode(stringValue)
        }

        dismiss(animated: true)
    }

    func foundBarcode(_ code: String) {
        print("バーコードが認識されました:\(code)")
    }
}

この例で、metadataOutput関数はカメラがバーコードを認識した際に呼び出されます。

認識されたバーコードの文字列情報を取得し、それをfoundBarcode関数で処理しています。

このサンプルでは、認識されたバーコードの情報をコンソールに表示するだけですが、この情報を用いて様々な処理を追加することができます。

●バーコード読み取りの応用例

バーコード読み取りは、基本的な機能だけでなく、さまざまな応用的な利用方法が考えられます。

ここでは、バーコードの読み取り結果を利用して、実際のアプリケーションでどのような機能を実装できるか、いくつかの具体的な例を紹介します。

○サンプルコード3:読み取ったバーコード情報の表示

読み取ったバーコードの情報を、アプリケーション内で直接表示する方法を紹介します。

ここでは、読み取った情報をシンプルにテキストとして表示します。

func foundBarcode(_ code: String) {
    let alert = UIAlertController(title: "バーコード情報", message: "読み取られたバーコード:\(code)", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default))
    present(alert, animated: true)
}

このコードでは、読み取られたバーコードの情報をアラートダイアログとして表示します。

そうすると、ユーザーは、アプリケーションを使用してバーコードをスキャンすると、読み取った情報が直接スクリーンに表示されます。

○サンプルコード4:バーコード読み取りのカスタマイズ例

バーコード読み取りの処理をカスタマイズして、特定のバーコード形式だけを読み取るように設定する例を紹介します。

let metadataOutput = AVCaptureMetadataOutput()
if captureSession.canAddOutput(metadataOutput) {
    captureSession.addOutput(metadataOutput)
    metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    // EAN13形式のバーコードのみを読み取るように設定
    metadataOutput.metadataObjectTypes = [.ean13]
}

このコードでは、読み取りを受け付けるバーコードの形式をEAN13のみに限定しています。

これにより、EAN13以外のバーコードがスキャンされた場合、アプリケーションはそれを無視します。

○サンプルコード5:読み取った情報のデータベース保存

バーコードから読み取った情報を、データベースに保存する方法を紹介します。

まず、シンプルなデータベースを使用するために、Realmを導入します。

import RealmSwift

class BarcodeData: Object {
    @objc dynamic var barcode: String = ""
}

そして、読み取ったバーコードの情報をデータベースに保存する関数を追加します。

func saveToDatabase(_ code: String) {
    let realm = try! Realm()
    let barcodeData = BarcodeData()
    barcodeData.barcode = code
    try! realm.write {
        realm.add(barcodeData)
    }
    print("バーコード情報がデータベースに保存されました。")
}

このコードを使用すると、読み取ったバーコードの情報がデータベースに保存されます。

これにより、後からアプリケーション内でこの情報を参照したり、他の処理で使用することが可能となります。

●注意点と対処法

Swiftを使用してバーコード読み取りを実装する際には、多くの開発者が直面する可能性があるいくつかの一般的な問題点やその対処方法について、詳細に説明します。

○バーコードの読み取りエラーとその対処法

バーコード読み取り中に遭遇する最も一般的な問題は、読み取りエラーです。

このエラーは、さまざまな原因で発生する可能性があります。

□カメラのフォーカス問題

バーコードがぼやけていたり、クリアでない場合、正確に読み取ることができません。

対処法として、ここでは、カメラの自動フォーカスを有効にし、バーコードがクリアに映るように調整します。

let captureDevice = AVCaptureDevice.default(for: .video)
if captureDevice.isFocusModeSupported(.continuousAutoFocus) {
    try! captureDevice.lockForConfiguration()
    captureDevice.focusMode = .continuousAutoFocus
    captureDevice.unlockForConfiguration()
}

このコードでは、カメラのフォーカスモードを連続的な自動フォーカスに設定しています。

□光の問題

暗い環境や逆光の場合、バーコードの読み取りに失敗する可能性があります。

対処法として、ここでは、カメラのフラッシュやトーチを使用して、十分な照明を確保します。

if captureDevice.hasTorch {
    try! captureDevice.lockForConfiguration()
    captureDevice.torchMode = .on
    captureDevice.unlockForConfiguration()
}

このコードを使用すると、カメラのトーチが点灯し、読み取りの精度が向上します。

○バーコード読み取りの際のユーザビリティ向上のためのアドバイス

バーコードの読み取りは技術的な側面だけでなく、ユーザの使い勝手にも配慮する必要があります。

ここでは、ユーザビリティを向上させるためのいくつかのアドバイスをしていきます。

□視覚的なガイドの提供

ユーザがスキャンを正しく行うための参照となる視覚的なガイドや枠を提供することで、ユーザの操作をサポートします。

対処法として、アプリケーションのUIに読み取りエリアを示す枠やガイドを表示してください。

□フィードバックの提供

バーコードが正しく読み取れたか、エラーが発生した場合に、ユーザにフィードバックを提供することで、操作の確認やエラーの認識が容易になります。

対処法として、読み取り成功時には音やバイブレーション、エラー時にはアラートなどのフィードバックを提供してください。

●カスタマイズ方法

Swiftを用いたバーコード読み取りの実装には、デザインや動作速度、特定のバーコード形式の認識など、様々なカスタマイズの方法があります。

ここでは、それぞれのカスタマイズ方法をサンプルコードを交えて説明します。

○サンプルコード6:デザインのカスタマイズ方法

アプリのデザインやUIはユーザーの使い勝手や印象に大きく影響します。

例として、バーコード読み取りエリアの枠をカスタマイズする方法を紹介します。

import UIKit
import AVFoundation

class BarcodeScannerViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // バーコード読み取りエリアの枠の設定
        let barcodeAreaFrame = UIView()
        barcodeAreaFrame.layer.borderColor = UIColor.green.cgColor
        barcodeAreaFrame.layer.borderWidth = 2.0
        barcodeAreaFrame.frame = CGRect(x: 60, y: 200, width: 200, height: 200)
        view.addSubview(barcodeAreaFrame)
    }
}

このコードでは、中央に200×200の緑色の枠を表示しています。

これにより、ユーザーはどの部分をスキャンするべきかが直感的にわかるようになります。

○サンプルコード7:バーコード読み取りの動作速度の調整

読み取り速度は、バーコードの読み取り精度やアプリケーションのパフォーマンスに影響を与えるため、適切な速度に調整することが重要です。

ここでは、読み取り速度を調整するサンプルコードを紹介します。

import AVFoundation

let captureSession = AVCaptureSession()
captureSession.sessionPreset = .medium // 読み取り速度の調整

このコードでは、sessionPresetを.mediumに設定して読み取り速度を中速に調整しています。

他にも、.low、.highなど、異なるプリセットを用いることで読み取り速度を変更することができます。

○サンプルコード8:特定のバーコード形式だけを読み取る設定

特定のバーコード形式だけを対象として読み取る場合の設定方法を解説します。

例えば、QRコードのみを読み取るように設定する方法は次のとおりです。

import AVFoundation

let captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.default(for: .video)
let videoInput: AVCaptureDeviceInput

do {
    videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice!)
    if captureSession.canAddInput(videoInput) {
        captureSession.addInput(videoInput)
    } else {
        return
    }

    let metadataOutput = AVCaptureMetadataOutput()
    if captureSession.canAddOutput(metadataOutput) {
        captureSession.addOutput(metadataOutput)

        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [.qr] // QRコードのみ読み取り対象とする
    } else {
        return
    }

    captureSession.startRunning()
} catch {
    return
}

このコードでは、metadataObjectTypesプロパティを利用して、読み取り対象とするバーコード形式をQRコードのみに制限しています。

●Swiftでのバーコード読み取りの応用

バーコード読み取りの技術は、単なる情報の取得以上の多様な応用が考えられます。

Swiftを使ったバーコード読み取りの実装には、商品情報の取得や在庫管理など、さまざまな応用例が存在します。

○サンプルコード9:商品の価格や詳細を表示する

ここでは、バーコードを読み取った後、関連する商品情報をユーザーに表示する実装例を紹介します。

import AVFoundation

// バーコード読み取り後のコールバック関数
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    if let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
        if let barcodeString = metadataObject.stringValue {
            // 例: 商品情報のデータベースから商品情報を取得
            let productInfo = getProductInfo(by: barcodeString)

            DispatchQueue.main.async {
                // UIに商品情報を表示
                self.productNameLabel.text = productInfo.name
                self.productPriceLabel.text = "\(productInfo.price)円"
            }
        }
    }
}

// デモ用の商品情報取得関数
func getProductInfo(by barcode: String) -> (name: String, price: Int) {
    // 本実装では仮の商品情報を返す
    return ("サンプル商品", 1000)
}

このコードでは、バーコードを読み取った後、そのバーコードに関連する商品の名前と価格を表示しています。

○サンプルコード10:読み取ったバーコードを元に在庫管理

ここでは、バーコードを利用して在庫管理を行うシステムの一部を紹介します。

import AVFoundation

// バーコード読み取り後のコールバック関数
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    if let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
        if let barcodeString = metadataObject.stringValue {
            // 在庫管理システムにバーコード情報を送信
            updateInventory(barcode: barcodeString)
        }
    }
}

// デモ用の在庫管理更新関数
func updateInventory(barcode: String) {
    // 本実装では仮の処理を行う
    print("在庫更新: \(barcode)")
}

このコードでは、読み取ったバーコード情報を在庫管理システムに送信して、在庫の更新を行っています。

○サンプルコード11:バーコードを用いた顧客管理の例

バーコード技術を活用して、特定の商品やサービスの購入履歴に基づいた顧客のプロファイル管理を行うことができます。

ここでは、顧客のバーコードカードをスキャンして、関連する顧客情報を取得するSwiftによる実装例を紹介します。

import AVFoundation

class CustomerManagementViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    // バーコード読み取り後のコールバック関数
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
            if let customerBarcode = metadataObject.stringValue {
                // 顧客情報をデータベースから取得
                let customerInfo = getCustomerInfo(by: customerBarcode)

                DispatchQueue.main.async {
                    // UIに顧客情報を表示
                    self.customerNameLabel.text = customerInfo.name
                    self.customerPurchaseHistoryLabel.text = customerInfo.purchaseHistory
                }
            }
        }
    }

    // デモ用の顧客情報取得関数
    func getCustomerInfo(by barcode: String) -> (name: String, purchaseHistory: String) {
        // 本実装では仮の顧客情報を返す
        return ("田中 太郎", "最近の購入:iPhone 13")
    }
}

このコードでは、顧客のバーコードカードを読み取ることで、データベースから関連する顧客の名前や購入履歴などの情報を取得して表示しています。

○サンプルコード12:バーコード読み取りを組み込んだゲームの実装例

バーコード読み取りをゲームに組み込むことで、リアルワールドとデジタルワールドを繋げる新しい体験を提供することができます。

ここでは、Swiftで実装された、バーコードを読み取ってゲーム内のキャラクターやアイテムを取得する例を紹介します。

import AVFoundation

class BarcodeGameViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    // バーコード読み取り後のコールバック関数
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
            if let gameBarcode = metadataObject.stringValue {
                // ゲーム内のアイテムやキャラクター情報を取得
                let gameItem = getGameItem(by: gameBarcode)

                DispatchQueue.main.async {
                    // ゲームUIにアイテムやキャラクター情報を表示
                    self.gameItemLabel.text = gameItem.name
                    self.gameItemImageView.image = UIImage(named: gameItem.imageName)
                }
            }
        }
    }

    // デモ用のゲームアイテム取得関数
    func getGameItem(by barcode: String) -> (name: String, imageName: String) {
        // 本実装では仮のゲームアイテム情報を返す
        return ("伝説の剣", "legendary_sword")
    }
}

このコードでは、特定のバーコードを読み取ることでゲーム内のアイテムやキャラクターを取得しています。

例えば、リアルな商品のバーコードを読み取って、ゲーム内の特定のアイテムを獲得するという使い方が考えられます。

まとめ

Swiftを用いて、バーコードの読み取り機能の実装は、さまざまなアプリケーションに応用が可能であることを本記事を通して解説しました。

バーコード技術を活用することで、商業的な用途からエンターテインメントまで、ユーザーエクスペリエンスの向上やビジネスプロセスの効率化が期待できます。

本記事では、Swiftの基本的な特徴からバーコードの読み取りの基本的な流れ、さらに応用例やカスタマイズの方法、そして実際のゲームや顧客管理などの具体的な実装例に至るまで、詳細に解説してきました。

サンプルコードを交えながらの説明を通じて、読者の皆さんがSwiftを使ったバーコード読み取りの実装に対する理解を深める手助けができたと考えています。

Swiftでのバーコード読み取り実装は、独自のアイディアやニーズに合わせてカスタマイズすることができます。

今後のアプリ開発やプロジェクトにおいて、この技術を有効に活用して、ユーザーに新しい価値を提供していくことが期待されます。