admaDIC App Development & IT Solutions

QR Code Generation with CIFilter and Custom Deep Link

by Annett Schwarze | 2026-05-22

While adding the class-join feature to our Music Theory Learning app, I extended the Core Image approach described in "SwiftUI QR Code Generation" to generate QR codes for deep linking. No extra library required, just a `CIFilter` and a few lines of Swift.

Creating a scannable QR code in SwiftUI takes only a few lines using `CIFilter.qrCodeGenerator()`. Combined with a custom URL scheme (`musicnotes://join?code=...`), students can scan the code and join a class with a single tap; all without a third-party dependency.

The sample code also includes an example of handling the incoming deep link in `SceneDelegate`.

        
struct QRCodeView: View {
    let url: String
    private let context = CIContext()
    private let filter = CIFilter.qrCodeGenerator()

    func generateQRCode(from string: String) -> UIImage {
        filter.message = Data(string.utf8)
        filter.setValue("H", forKey: "inputCorrectionLevel") // High error correction

        if let outputImage = filter.outputImage {
            let transform = CGAffineTransform(scaleX: 10, y: 10)
            let scaledImage = outputImage.transformed(by: transform)
            if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) {
                return UIImage(cgImage: cgImage)
            }
        }
        return UIImage(systemName: "xmark.circle") ?? UIImage()
    }

    var body: some View {
        Image(uiImage: generateQRCode(from: url))
            .interpolation(.none) // crucial – keeps pixels crisp
            .resizable()
            .scaledToFit()
    }
}
// Deep link target: musicnotes://join?code=MUSIC-A3B7K2

// Receiving the link
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set< UIOpenURLContext >) {
        if let ctx = URLContexts.first(where: { $0.url.scheme == "musicnotes" }) {
            let url = ctx.url
            if url.host == "join" || url.path.hasPrefix("/join") {
            // Handle join class URLs: musicnotes://join?code=MUSIC-A3B7K2
            handleJoinClassURL(url)
            }
        }
    }

    private func handleJoinClassURL(_ url: URL) {
        // Parse the class code from URL parameters
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
              let codeParam = components.queryItems?.first(where: { $0.name == "code" }),
              let classCode = codeParam.value else {
            logger.debug("\(#function): Invalid join URL: missing code parameter")
            return
        }

        // Handle the class code in the app
        // ...
    }
}
    
QR Code Screen

 

www.admadic.de | webmaster@admadic.de | Legal Notice and Trademarks | Privacy
© 2005-2007 - admaDIC | All Rights Reserved
All other trademarks and/or registered trademarks are the property of their respective owners
Last Change: Fri May 22 09:03:51 2026 GMT