简体   繁体   中英

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 : 谷歌

I think I've found the issue. When running the request on Xcode 14 and iOS 16, the request revision runs on VNDetectBarcodesRequestRevision3 (which issn't documented yet on VNDetectBarcodesRequest page). However, using VNDetectBarcodesRequestRevision1 or VNDetectBarcodesRequestRevision2 works.

Adding the following before the perform task worked for me:

request.revision = VNDetectBarcodesRequestRevision1

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

When compiling for either iOS 15 or 16, I found a difference in VNDetectedBarcodesRequest behavior when scanning a barcode WITH, or a barcode WITHOUT, a border. That border seems to trigger the scanning code when to start.

WITH a border: it scans both black-background image and white-background image correctly.

WITHOUT a border: it scans the barcode image on the monitor with a black background correctly, but it fails when that image is printed on white paper and scanned. No border = no barcode.

NEW ISSUE: it returned an array of 17 identical barcode observations when it scanned that single bordered barcode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM