I am creating an app that, in the end of one cycle, generates a QR Code and then creates a PDF file. After running the app several times (tested for almost 5 days) the app stopped doing its other required functionalities. I found out that every time the app generates QR and makes PDF, the memory graph grows higher and higher in successive cycles of app. Debug memory graph indicates 3 memory leaks: one at viewDidAppear event, another at createPDF method, and third at generateQrCode method. I am deleting the PDF file every time user starts a new cycle. I don't know how to handle these memory leaks. Can someone help? Here is the code:
let html = ""
override func viewDidAppear(_ animated: Bool) {
createPDF()
return
}
func createPDF() {
html = "<div style='display: flex; justify-content: center;'></div>"
generateQrCode(arg: true, completion: { (success) -> Void in
print("QR Code Generated")
let image1 = captureView()
let imageData1 = image1.pngData() ?? nil
let base64String1 = imageData1?.base64EncodedString() ?? ""
if success {
self.html += "<html><body><div style='text-align: center'><p><br></p><p><b><img width='50%' height='20%' src='data:image/png;base64,\(String(describing: base64String1))'/><p><br></p><p><b></b></p></div></body></html>"
weak var webView = WKWebView(frame: self.view.frame)
self.view.addSubview(webView!)
webView!.navigationDelegate = self
webView!.loadHTMLString(html, baseURL: nil)
webView!.isUserInteractionEnabled = false
} else {
print("false")
}
})
}
func generateQrCode(arg: Bool, completion: (Bool) -> ()){
let data = self.dataToQr.data(using: .ascii, allowLossyConversion: false)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(data, forKey: "inputMessage")
let img = UIImage(ciImage: (filter?.outputImage)!)
self.qrImageView.image = img
completion(true)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let render = UIPrintPageRenderer()
render.addPrintFormatter(webView.viewPrintFormatter(), startingAtPageAt: 0)
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
let printable = page.insetBy(dx: 0, dy: 0)
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
for i in 1...render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i - 1, in: bounds)
}
UIGraphicsEndPDFContext();
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
pdfData.write(toFile: "\(documentsPath)/\(UserDefaults.standard.string(forKey: "yourName")!)_\(UserDefaults.standard.string(forKey: "gameName")!)_Kapper.pdf", atomically: true)
print("\(documentsPath)/apper.pdf")
webView.removeFromSuperview()
}