Отправка созданного на лету QR-кода UIImage с помощью AirDrop не удалась

Я создаю QR-код на лету и сохраняю его как UIImage. Теперь я хочу иметь возможность отправить его с помощью UIActivityViewController, но почему-то это не удается:

func generateQRCode(from string: String) -> UIImage? {
    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")
        let transform = CGAffineTransform(scaleX: 3, y: 3)

        if let output = filter.outputImage?.applying(transform) {
            return UIImage(ciImage: output)
        }
    }

    return nil
}

Затем я вызываю функцию и сохраняю ее как UIImage:

let image = generateQRCode(from: "Create my Code")
imgQRCode.image = image

Кнопка экспорта использует следующее действие:

@IBAction func shareButtonClicked(sender: UIButton) {

        let objectsToShare = [imgQRCode.image!] as [AnyObject]
        let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

        activityVC.popoverPresentationController?.sourceView = sender
        self.present(activityVC, animated: true, completion: nil)

}

После выбора отправки через AirDrop на мой Mac приложение вылетает

2016-11-05 23:29:15.912242 Ordnung[3945:888442] CGContextScaleCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

5 ноября 23:29:15 Ordnung[3945] : CGContextScaleCTM: недопустимый контекст 0x0. Если вы хотите увидеть обратную трассировку, установите переменную среды CG_CONTEXT_SHOW_BACKTRACE.

2016-11-05 23:29:15.912396 Ordnung[3945:888442] CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Nov  5 23:29:15  Ordnung[3945] <Error>: CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-11-05 23:29:15.912584 Ordnung[3945:888442] CGContextConcatCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Nov  5 23:29:15  Ordnung[3945] <Error>: CGContextConcatCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-11-05 23:29:15.912692 Ordnung[3945:888442] CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Nov  5 23:29:15  Ordnung[3945] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2016-11-05 23:29:15.927580 Ordnung[3945:888442] [AirDrop] Sender kSFOperationEventErrorOccured {
    Error = "Error Domain=SFOperation Code=-5 \"Die \U00dcbertragung ist fehlgeschlagen, da du eine ung\U00fcltige Datei senden wolltest.\" UserInfo={NSLocalizedDescription=Die \U00dcbertragung ist fehlgeschlagen, da du eine ung\U00fcltige Datei senden wolltest.}";
    SessionID = 76FBE80074FC;
}

Кто-нибудь знает, как это сделать?

Ура Майк


person Barzille    schedule 05.11.2016    source источник


Ответы (1)


Кажется, мне нужно предоставить изображение немного по-другому, поэтому изменение генерации QR-кода таким образом решает проблему, создавая CGImage перед созданием UIImage:

func generateQRCode(from string: String) -> UIImage? {
    let ciContext = CIContext()
    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")
        let transform = CGAffineTransform(scaleX: 3, y: 3)
        let upScaledImage = filter.outputImage?.applying(transform)


        let cgImage = ciContext.createCGImage(upScaledImage!,
                                              from: upScaledImage!.extent)
        let qrcodeImage = UIImage(cgImage: cgImage!)
        return qrcodeImage
    }
    return nil
}

Для Swift 4.2

func generateQRCode(from string: String) -> UIImage? {
    let ciContext = CIContext()
    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CIQRCodeGenerator") {
        filter.setValue(data, forKey: "inputMessage")
        let transform = CGAffineTransform(scaleX: 3, y: 3)
        let upScaledImage = filter.outputImage?.transformed(by: transform)

        let cgImage = ciContext.createCGImage(upScaledImage!, from: upScaledImage!.extent)
        let qrcodeImage = UIImage(cgImage: cgImage!)
        return qrcodeImage
    }
    return nil
}

Кроме того, вы должны использовать изображение в формате png или jpg:

func share() {
    let png = UIImagePNGRepresentation(qrcodeImage)
    let vc = UIActivityViewController(activityItems: [png!], applicationActivities: [])
    present(vc, animated: true)
}
person Barzille    schedule 08.11.2016
comment
Вы спасли мой день! Спасибо! - person DeZigny; 22.04.2017
comment
После нескольких дней поиска это решение, которое, наконец, сработало для меня. Во всех других решениях вы можете видеть только сгенерированное изображение на экране, но не можете сохранить его в виде файла, что я и пытался сделать. - person zeeshan; 29.11.2018