You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成二维码并邮件附件发送失败:UIImagePNGRepresentation返回nil

解决UIImagePNGRepresentation返回nil导致的崩溃问题

我来帮你分析下问题的根源:你生成的qrImage是通过UIImage(ciImage:)初始化的——这种方式创建的UIImage只是CIImage的一个包装对象,并没有实际的位图像素数据,所以UIImagePNGRepresentation(现在更推荐用iOS 11+的UIImage.pngData()方法)无法从中提取出有效的PNG数据,自然返回nil,而你后续的强制解包imgData!就直接导致了崩溃。

下面是具体的修复方案:

1. 修复二维码生成逻辑,生成带位图数据的UIImage

把基于CIImage的UIImage转换成包含实际像素数据的版本,需要借助CIContext渲染CIImage为CGImage,再用CGImage创建UIImage。修改你generatePressed方法里的二维码生成代码:

@IBAction func generatePressed(_ sender: UIButton) {
    if let text = dataField.text {
        let data = text.data(using: .ascii, allowLossyConversion: false)
        filter = CIFilter(name: "CIQRCodeGenerator")
        filter.setValue(data, forKey: "inputMessage")
        let transform = CGAffineTransform(scaleX: 10, y: 10)
        
        // 替换原有的qrImage生成代码
        if let outputImage = filter.outputImage?.transformed(by: transform) {
            let context = CIContext(options: [.useSoftwareRenderer: false])
            if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                qrImage = UIImage(cgImage: cgImage)
            } else {
                // 处理CGImage创建失败的情况
                print("Failed to create CGImage from CIImage")
                return
            }
        } else {
            // 处理CIImage转换失败的情况
            print("Failed to transform QR code image")
            return
        }
        
        displayCodeView.image = qrImage
        let mailComposeViewController = configureMailController(imageToEmail: qrImage)
        if MFMailComposeViewController.canSendMail() {
            self.present(mailComposeViewController, animated: true, completion: nil)
        } else {
            showMailError()
        }
    }
}

2. 替换废弃API并增加安全判断

UIImagePNGRepresentation已经被废弃,改用pngData(),同时避免强制解包,增加错误处理逻辑:

func configureMailController(imageToEmail: UIImage) -> MFMailComposeViewController {
    let mailComposerVC = MFMailComposeViewController()
    mailComposerVC.mailComposeDelegate = self
    mailComposerVC.setToRecipients(["jc@project44laight.com"])
    mailComposerVC.setSubject("QRCode")
    
    // 替换原有的imgData处理逻辑
    guard let imgData = imageToEmail.pngData() else {
        print("Failed to convert QR image to PNG data")
        let errorAlert = UIAlertController(title: "Attachment Error", message: "Could not prepare QR code for email attachment", preferredStyle: .alert)
        errorAlert.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(errorAlert, animated: true)
        return mailComposerVC
    }
    mailComposerVC.addAttachmentData(imgData, mimeType: "image/png", fileName: "qrCode.png")
    
    let emailBody = "<html><body><p>QR code is attached in image </p></body></html>"
    mailComposerVC.setMessageBody(emailBody, isHTML:true)
    return mailComposerVC
}

额外建议

尽量避免代码中的强制解包(比如你原来的filter.outputImage!),用可选绑定和错误处理来提升代码的健壮性,减少意外崩溃的可能。

内容的提问来源于stack exchange,提问作者user9832689

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:32:41