Create QR Code in SwiftUI

Create QR Code in SwiftUI

A Quick Response code or QR Code is a type of two-dimensional barcode invented by the Japanese automotive company Denso Wave in 1994. A QR code consists of black squares arranged in a square grid on a white background. This article shows how to create QR codes in SwiftUI using the CoreImage framework.

QR codes became popular outside the automotive industry because of fast readability and greater storage capacity compared to standard UPC barcodes. QR codes often contain data for a locator, identifier, or tracker that points to a website or application. They are easily recognised by a smart phone camera and allow customers to quickly perform an action such as navigating to a website or sending an email.



Create a QR Code

Core Image is a very powerful framework for modifying and enhancing images and provides hundreds of built-in filters. Filters are set up with a key-value pair for the filter’s input parameters. CIQRCodeGenerator Core Image filter that has two possible key parameters. One of these is inputMessage, which takes the data to be encoded as a QR code. The value for inputMessage has to be in the form of an NSData object. The second parameter is inputCorrectionLevel, which controls the amount of additional data encoded in the output image to provide error correction. This has a default level of "M" corresponding to a 15% resilience level.

To create the QR Code, the text string is first converted to a Data object. Set the inputMessage of the CIQRCodeGenerator filter to the data. The output image of the filter will be an QR Code image with the width and height of each square dot of the code one point.

 1struct QrCodeImage {
 2    let context = CIContext()
 3
 4    func generateQRCode(from text: String) -> UIImage {
 5        var qrImage = UIImage(systemName: "xmark.circle") ?? UIImage()
 6        let data = Data(text.utf8)
 7        let filter = CIFilter.qrCodeGenerator()
 8        filter.setValue(data, forKey: "inputMessage")
 9
10        if let outputImage = filter.outputImage {
11            if let image = context.createCGImage(
12                outputImage,
13                from: outputImage.extent) {
14                qrImage = UIImage(cgImage: image)
15            }
16        }
17        return qrImage
18    }
19}
 1struct ContentView: View {
 2    @State private var text = "swdevnotes.com"
 3    var qrCodeImage = QrCodeImage()
 4
 5    var body: some View {
 6        VStack {
 7            Form {
 8                Section(header: Text("Text to encode in QRCode")) {
 9                    TextField("Text", text: $text)
10                }
11            }
12            .frame(width: .infinity, height: 130, alignment: .center)
13            .padding()
14
15            Image(uiImage: qrCodeImage.generateQRCode(from: text))
16            Spacer()
17        }
18    }
19}

The resulting QR Code works, but it is very small.

Initial QR Code for specified text



Increase Size of QR Code in SwiftUI View

The default image generated by the CIQRCodeGenerator Core Image filter is very small. The first attempt to increase the size of the image is to make the image resizable use a fram modifier to set the size of the image. This increases the size of the QR Code, but the resulting image is blurry.

 1struct ContentView: View {
 2    @State private var text = "swdevnotes.com"
 3    var qrCodeImage = QrCodeImage()
 4
 5    var body: some View {
 6        VStack {
 7            Form {
 8                Section(header: Text("Text to encode in QRCode")) {
 9                    TextField("Text", text: $text)
10                }
11            }
12            .frame(width: .infinity, height: 130, alignment: .center)
13            .padding()
14
15            Image(uiImage: qrCodeImage.generateQRCode(from: text))
16                .resizable()
17                .scaledToFit()
18                .frame(width: 200, height: 200)
19
20            Spacer()
21        }
22    }
23}

Resize QRCode using swift Image resizable



Increase Size of QR Code

The default output image of CIQRCodeGenerator filter is a QR Code image with the width and height of each square dot of the code being one point. A transform can be applied to scale this Core Graphics image, which results in the image being scaled up to create a clear larger QR Code image.

 1struct QrCodeImage {
 2    let context = CIContext()
 3
 4    func generateQRCode(from text: String) -> UIImage {
 5        var qrImage = UIImage(systemName: "xmark.circle") ?? UIImage()
 6        let data = Data(text.utf8)
 7        let filter = CIFilter.qrCodeGenerator()
 8        filter.setValue(data, forKey: "inputMessage")
 9
10        let transform = CGAffineTransform(scaleX: 20, y: 20)
11        if let outputImage = filter.outputImage?.transformed(by: transform) {
12            if let image = context.createCGImage(
13                outputImage,
14                from: outputImage.extent) {
15                qrImage = UIImage(cgImage: image)
16            }
17        }
18        return qrImage
19    }
20}

Resize the image with Affine Transform matrix




Conclusion

Core Image framework is a powerful framework for manipulating images with hundreds of predefined filters. The CIQRCodeGenerator Core Image filter generates a QR Code image from input data such as a string. The default image is small and can be resized using a Core Graphics transformation before being converted to an UIImage for display in a Swift Application.