Developers & agents
Generate a QR code in Swift
Apple platforms have a QR encoder built in: CIFilter.qrCodeGenerator() from CoreImage, available since iOS 7. Set message and correctionLevel, scale the tiny output with CGAffineTransform (never interpolated resizing), and wrap the CGImage for SwiftUI. No package needed; use the keyless API only for styled codes.
The generator is already on the device
The headline fact: you do not need a library. Every iPhone since iOS 7 and every Mac since
OS X 10.9 ships CIQRCodeGenerator inside CoreImage:
import CoreImage.CIFilterBuiltins
func qrImage(for text: String, scale: CGFloat = 12) -> CGImage? {
let filter = CIFilter.qrCodeGenerator()
filter.message = Data(text.utf8)
filter.correctionLevel = "M" // "L", "M", "Q" or "H"
guard let output = filter.outputImage else { return nil }
let scaled = output.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
return CIContext().createCGImage(scaled, from: scaled.extent)
}
correctionLevel accepts the four standard
error-correction levels as strings.
On-device generation is also the right call for privacy: a WiFi password or contact card
never needs to reach a server to become an image
(client-side vs server-side).
Scale without blur
The filter's raw output is one pixel per module, a few dozen pixels across. Resize that with normal image scaling and you get a grey, smeared code that scanners hate. Two rules:
- Scale with
CGAffineTransformbefore rasterising, as above, modules stay square and hard-edged at any size. - In SwiftUI, add
.interpolation(.none)so the framework never smooths it either.
struct QrView: View {
let value: String
var body: some View {
if let cg = qrImage(for: value) {
Image(decorative: cg, scale: 1)
.interpolation(.none)
.resizable()
.scaledToFit()
.frame(width: 220, height: 220)
.padding(12)
.background(.white) // keep the code light-on-white in dark mode
}
// always offer the underlying link as a tappable fallback
}
}
The white background matters: a code inheriting a dark-mode backdrop reads as inverted, which many scanners refuse.
Styled codes: the keyless API
CIQRCodeGenerator draws black-on-white squares, full stop. For brand colours, module
shapes or typed payloads with validation, fetch the
keyless API:
var comps = URLComponents(string: "https://useqr.app/api/v1/qr")!
comps.queryItems = [
.init(name: "data", value: "https://example.com/sale?src=poster"),
.init(name: "size", value: "1024"),
.init(name: "color", value: "6366f1"),
]
let (data, _) = try await URLSession.shared.data(from: comps.url!)
let image = UIImage(data: data)
URLComponents handles the percent-encoding, building the query by string concatenation
is how payloads containing & get silently truncated. In SwiftUI,
AsyncImage(url: comps.url) displays it with no manual fetch at all.
Verify styled output
Any code you recolour should be decoded back before it ships. On-device you can round-trip
with Vision's barcode detection; simpler is one call to GET /api/v1/verify, which
renders, rasterises and decodes server-side and returns scannable plus issues, the
decode-verify loop as a request.
The Android equivalent of this whole page is
generate a QR code in Kotlin.
FAQ
Does iOS have a built-in QR code generator?
Yes: CIQRCodeGenerator in CoreImage, present since iOS 7 and OS X 10.9. CIFilter.qrCodeGenerator() gives typed access; no third-party package is required.
Why is my Swift QR code blurry?
The filter outputs one pixel per module and it is being resized with interpolation. Scale the CIImage with CGAffineTransform first and set .interpolation(.none) in SwiftUI.
How do I set error correction with CIQRCodeGenerator?
Set correctionLevel to "L", "M", "Q" or "H". Use "H" when the code will carry a logo or face rough conditions; "M" is a sensible default.
Can CIQRCodeGenerator make coloured QR codes?
No, it emits black on white. Recolour with CoreImage filters carefully, or request styled output from the keyless API and verify that it still decodes.
Try it: free, no signup
Related
- A free QR code API with no key, UseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight…
- Generate a QR code in Kotlin, Kotlin and Android QR generation: ZXing's BarcodeEncoder to a Bitmap, display in Jetpack Compose, and the keyless API fetched with coroutines.
- Why you should verify that a QR code decodes, Rendering a QR code proves nothing about whether it scans. Styling, colour, logos and print all consume error-correction budget invisibly. The only…
- Client-side vs server-side QR generation, and why it matters, If a QR generator renders the image on its server, your data (including WiFi passwords, contact details and payment identifiers) is transmitted to and…