swiftvisionios16xcode14

VNDetectBarcodesRequest not working on iOS16


I am experiencing issues with VNDetectBarcodesRequest on iOS 16. My code works as intended on iOS 15 but on iOS 16 it doesn't find any bar codes in an image.

I've separated my code to a playground and am experiencing the same issue here. Running the code below on Xcode 13.4.1's playground, I get the result:

"Google link: Optional("https://www.google.com")"

Running the same code on Xcode 14, I get an nil result. Running this in an iOS15 simulator with Xcode 14 gives a positive result, only on iOS16 and playground it is not reading the QR code.

To add to it, no exceptions are thrown either.

Has anybody experienced the same and managed to fix this?

This is my playground code:

import UIKit
import Vision

extension UIImage {
    func qrCodeLink(completion: @escaping (String?) -> Void) {
        guard let ciImage = CIImage(image: self) else {
            completion(nil)
            return
        }
        let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage,
                                                        orientation: .up,
                                                        options: [:])       
        let request = VNDetectBarcodesRequest { (request,error) in
            guard error == nil else {
                completion(nil)
                return
            }
            
            guard let observations = request.results as? [VNDetectedObjectObservation] else {
                completion(nil)
                return
            }
            
            let result = (observations.first as? VNBarcodeObservation)?.payloadStringValue
            completion(result)
        }
        try? imageRequestHandler.perform([request])
    }
}

if let google = UIImage(named: "google") {
    google.qrCodeLink { link in
        debugPrint("Google link: \(link)")
    }
} else {
    debugPrint("No google image")
}

With the above code I am using this image, which is merely a link to https://www.google.com: Google


Solution

  • Elaborating on @Paul Peelen's solution, to ensure that the workaround is only used where needed (Xcode 14 + iOS 16 + Simulator), we used:

    #if targetEnvironment(simulator) && compiler(>=5.7)
    if #available(iOS 16, *) {
        request.revision = VNDetectBarcodesRequestRevision1
    }
    #endif