CoreImage is a feature rich framework with many high efficiency capabilities hidden inside. One such feature is the ability to generate QR code on demand with the help of CIQRCodeGenerator Core Image Filter.
In this article, we will use CIQRCodeGenerator to generate QR code in SwiftUI.
Let’s create a view first. We will have a VStack with a TextField and an Image View. TextField will take the user’s input and Image View will display the generated QR Code.
import SwiftUIstruct QRGenerator: View {
@State private var text = ""
var body: some View {
NavigationStack {
VStack {
TextField("Enter code", text: $text)
.textFieldStyle(.roundedBorder)
.padding()
Image("")
.resizable()
.frame(width: 200, height: 200)
}
.navigationTitle("DevTechie.com")
}
}
}
Next we will import the CoreImage framework.
import CoreImage
Let’s also import CoreImage’s type-safe API to access all the CoreImage filters.
import CoreImage.CIFilterBuiltins
Next, we will create our filter inside a function called generateQR which will take text string as an input and will return optional Data.
func generateQR(text: String) -> Data?
We will create filter variable and because we have imported CIFilterBuiltins we can initialize filter with easy one liner:
let filter = CIFilter.qrCodeGenerator()
We will convert our text string into data using ascii encoding:
guard let data = text.data(using: .ascii, allowLossyConversion: false) else { return nil }
CIFilter for QR code takes message parameter, which is a Data type so we will pass our converted textual ascii data into that.
filter.message = data
Our filter is ready to spit out an image and we can do that by calling outputImage on the filter variable. Since this value can be nil, we will safely unwrap it using the guard statement.
guard let ciimage = filter.outputImage else { return nil }
Generated QR code image is very small so we will have to scale it. Let’s apply CGAffineTransform to scale it 10x.
let transform = CGAffineTransform(scaleX: 10, y: 10)
let scaledCIImage = ciimage.transformed(by: transform)
Lastly, we will return a PNG representation of the CIImage by converting it first into UIImage.
let uiimage = UIImage(ciImage: scaledCIImage)
return uiimage.pngData()!
Our complete function will look like this:
func generateQR(text: String) -> Data? {
let filter = CIFilter.qrCodeGenerator()
guard let data = text.data(using: .ascii, allowLossyConversion: false) else { return nil }
filter.message = data
guard let ciimage = filter.outputImage else { return nil }
let transform = CGAffineTransform(scaleX: 10, y: 10)
let scaledCIImage = ciimage.transformed(by: transform)
let uiimage = UIImage(ciImage: scaledCIImage)
return uiimage.pngData()!
}
Next, we will update our view to use this newly created function to render the generated QR code.
Complete code:
import CoreImage
import CoreImage.CIFilterBuiltins
import SwiftUIstruct QRGenerator: View {
@State private var text = ""
var body: some View {
NavigationStack {
VStack {
TextField("Enter code", text: $text)
.textFieldStyle(.roundedBorder)
.padding()
Image(uiImage: UIImage(data: generateQR(text: text)!)!)
.resizable()
.frame(width: 200, height: 200)
}
.navigationTitle("DevTechie.com")
}
}
func generateQR(text: String) -> Data? {
let filter = CIFilter.qrCodeGenerator()
guard let data = text.data(using: .ascii, allowLossyConversion: false) else { return nil }
filter.message = data
guard let ciimage = filter.outputImage else { return nil }
let transform = CGAffineTransform(scaleX: 10, y: 10)
let scaledCIImage = ciimage.transformed(by: transform)
let uiimage = UIImage(ciImage: scaledCIImage)
return uiimage.pngData()!
}
}
Build and run
Try the QR code out with your iPhone’s camera app and while you are at it, checkout DevTechie.com 😄
With that we have reached the end of this article. Thank you once again for reading. Don’t forget to subscribe our newsletter at https://www.devtechie.com