生成二维码并邮件附件发送失败: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
相关产品推荐
相关产品推荐

