Seems like the printing doesn't appear to be worked correctly on iOS 16.
We've been getting a lot of crash reports related to printing since iOS 16 was released, for instance
Unfortunately, we are unable to reproduce those crashes.
This article says that SEGV_MAPERR
crash is due to an invalid memory fetch. For this reason, we decided to debug our app with the Address Sanitizer tool enabled in Xcode. As a result, we found out that almost every time the app accesses a freed heap region when the print UI is presented.
The were able to reproduce 2 cases in a separated project:
- Printing a docx file from
QLPreviewController
- Printing the same file from
UIActivityViewController
passingWKWebView.viewPrintFormatter
as an activity item.
In order to get the error, once you get to the print UI start scrolling the document preview. See the sample code bellow:
import UIKit
import WebKit
import QuickLook
final class PrintCrashViewController: UIViewController {
private let webView = WKWebView()
/* 27 page document from the app bundle */
private lazy var docFileURL = URL(fileURLWithPath: Bundle.main.path(forResource: "description", ofType: "docx")!)
override func loadView() {
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItems = [
UIBarButtonItem(title: "QL", style: .plain, target: self, action: #selector(openQLPreview)),
UIBarButtonItem(title: "Share", style: .plain, target: self, action: #selector(openActivityVC))
]
webView.loadFileURL(docFileURL, allowingReadAccessTo: docFileURL)
}
@objc private func openActivityVC() {
let items: [Any] = [docFileURL, webView.viewPrintFormatter()]
let activityVC = UIActivityViewController(activityItems: items, applicationActivities: nil)
present(activityVC, animated: true)
}
@objc private func openQLPreview() {
let qlPreviewVC = QLPreviewController()
qlPreviewVC.dataSource = self
present(qlPreviewVC, animated: true)
}
}
extension PrintCrashViewController: QLPreviewControllerDataSource {
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
docFileURL as NSURL
}
}
Both approaches have been in our app for years.