Swift 4:使用字典输入扫描QR码

时间:2017-07-20 06:34:34

标签: ios swift avfoundation

我正在尝试使用Adding Multiple Key-Value Pairs to QR Code作为指南扫描我生成的qr代码。我可以生成qr代码,但是当我尝试扫描它时,它会产生一个null的metadataObj.stringValue。

这是我读取元数据输出的代码:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    // Check if the metadataObjects array is not nil and it contains at least one object.
    if metadataObjects == [] || metadataObjects.count == 0 {
        qrCodeFrameView?.frame = CGRect.zero
        print("No QR code is detected")
        return
    }

    // Get the metadata object.
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

    if metadataObj.type == AVMetadataObject.ObjectType.qr {
        // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
        if let layer = previewLayer{
            let barCodeObject = layer.transformedMetadataObject(for: metadataObj)
            qrCodeFrameView?.frame = barCodeObject!.bounds
        }


        guard let inputData = metadataObj.stringValue?.data(using: String.Encoding.isoLatin1, allowLossyConversion: false),
            let dictionary = NSKeyedUnarchiver.unarchiveObject(with: inputData) as? [String: NSData] else { return }

        print(dictionary["firstName"] ?? "None")
    }
}

如果元数据对象输出的字符串值为null,如何取消归档数据?

2 个答案:

答案 0 :(得分:1)

我能够使用Codable protocol

将Swift字典编码为QR码,并从metadataObject输出中对其进行解码。

以下是将数据编码为QR码的思考过程:

  1. 使您的数据类型(可以是字典,可以是您自己的结构)符合Codable协议
  2. 通过JSON编码器将数据序列化为JSON
  3. 将序列化的数据放入生成QR码的Core Image过滤器中

这是我用来将快速词典转换为QR码的代码:

func generateQRCode(from dictionary: [String:String]) -> UIImage? {
    do {
        let data = try JSONEncoder().encode(dictionary)
        if let validData = String(data: data,encoding: .utf8){
            print(validData)
        }

        if let filter = CIFilter(name: "CIQRCodeGenerator"){
            filter.setValue(data, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 10, y: 10)
            if let output = filter.outputImage?.transformed(by: transform){
                return UIImage(ciImage: output)
            }
        }
    } catch {
        print(error.localizedDescription)
    }
    return nil
}

以下是通过QR码解码数据的思考过程:

  1. 检查以确保您的metadataObject确实是一个二维码
  2. 将您的metadataObject转换为具有utf-8编码的Data对象
  3. 使用JSON解码器解码数据对象并指定要解码的数据类型

这是我编写的用于使用QR委托函数metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)将QR码解码回Swift字典的代码。

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {


    if let metadataObject = metadataObjects.first{
        if metadataObject.type == .qr{
            let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject
            do {
                if let validData = readableObject?.stringValue?.data(using: .utf8){

                    let dict = try JSONDecoder().decode([String:String].self,from:validData)
                    //do stuff with dict                        
                    print(dict)
                    AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
                }
            } catch {
                print(error.localizedDescription)
            }

        }
    }
    navigationController?.popViewController(animated: true)
}

希望能帮助仍然停留在此问题上的人。对于将数据类型序列化为JSON,Codable非常方便,它非常适合IMO的QR码。

答案 1 :(得分:0)

您是否尝试迭代字典以仔细检查该值是否有效?

如果将lossyconversion设置为false,则该字符串将设置为nil。