LoginSignup
0

CIQRCodeGeneratorを使ってQRコードを作成する

Last updated at Posted at 2023-03-24

概要

iOSではiOS 13から、CIQRCodeGenerator というAPIが用意されており、これを用いることでQRコードの画像を簡単に生成することが可能になりました。
公式のドキュメントは以下になります。

この、CIQRCodeGeneratorを使ってのQRコード画像を生成してみたいと思います。

CIQRCodeGeneratorを生成する

CIQRCodeGeneratorはprotocolであり、実際はCIQRCodeGeneratorに適合したCIFilterを作成する形になります。
CIFilterには QRCodeGenerator というそのものズバリのクラスメソッドが用意されているので、そちらを使ってCIFilterを生成し、messageにQRコード化したいデータ、correctionLevelにはドキュメントにも記載のある通り、L, M, Q, Hから誤り訂正レベルを文字列で指定することになります。

以下はQITQrCodeGeneratorというクラスに生成処理を設けたコード例です。

QITQrCodeGenerator.h
#import <Foundation/Foundation.h>
#import <CoreImage/CIFilterBuiltins.h>


NS_ASSUME_NONNULL_BEGIN

@interface QITQrCodeGenerator : NSObject

+ (CIFilter<CIQRCodeGenerator>*)generator:(NSData* )data
                          correctionLevel:(NSString* )correctionLevel;

@end

NS_ASSUME_NONNULL_END
QITQrCodeGenerator.m
#import "QITQrCodeGenerator.h"

@implementation QITQrCodeGenerator

+ (CIFilter<CIQRCodeGenerator>*)generator:(NSData* )data
                          correctionLevel:(NSString* )correctionLevel
{
    CIFilter<CIQRCodeGenerator>* filter = [CIFilter QRCodeGenerator];
    filter.message = data;
    filter.correctionLevel = correctionLevel;
    return filter;
}
@end

Swiftから使う

上記のコード例からわかる通り、iOS 13から追加されたCIQRCodeGeneratorは、Objective-Cでしか使えません。

なので上記クラスをブリッジしてSwiftで使うことになります。
サンプルとしてSwiftUIからQRコードを表示するためのコードを例示します。

ポイントとして、CIQRCodeGeneratorから生成されるCIImageは、そのままUIImageにあるinitで変換しようとしてもSwiftUI上で表示されないのと、SwiftUIはマルチプラットフォームなのでSwiftUI.Imageに変換するのが望ましいと考えたので、CIImage→CGImage→Imageの変換を行なっています。

struct ContentView: View {
    @StateObject private var model = DataModel()

    var body: some View {
        VStack {
            if let qrImage = model.qrImage {
                qrImage
            } else {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundColor(.accentColor)
            }
            Text("Hello, world!")
        }
        .task {
            model.showQr(text: "適当な文字列")
        }
        .padding()
    }
}

final class DataModel: ObservableObject {
    @Published var qrImage: Image?
        
    func showQr(text: String) {
        let urlData: Data = text.data(using: .utf8)!
        let qrFilter = OADQrCodeGenerator.generator(urlData, correctionLevel: "H")
        
        // QRコードの拡大処理
        let qrOutputImage = qrFilter.outputImage!.transformed(by: .init(scaleX: 5, y: 5))
        let context = CIContext()
        let qrCgImage: CGImage = context.createCGImage(qrOutputImage, from: qrOutputImage.extent)!
        qrImage = .init(qrCgImage, scale: 1.0, label: Text(text))
    }
}

Simulator Screen Shot - iPhone 14 Pro - 2023-03-24 at 18.21.42.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0