From 7a3a72e69c25a6997c8db3e527580ca0329953a7 Mon Sep 17 00:00:00 2001 From: bartszczepaniak Date: Wed, 21 Feb 2024 15:11:51 +0000 Subject: [PATCH 1/2] Save `json` files with `UIViewController` memory leak name Storing memory leak `UIViewController` name each time we encounter one. This can be extracted from `/tmp/presentation-memory-leaks/` directory. --- Presentation/MemoryUtils.swift | 79 ++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/Presentation/MemoryUtils.swift b/Presentation/MemoryUtils.swift index 15fe987..30afe65 100644 --- a/Presentation/MemoryUtils.swift +++ b/Presentation/MemoryUtils.swift @@ -34,6 +34,8 @@ public let enabledDisplayAlertOnMemoryLeaksKey = "enabledDisplayAlertOnMemoryLea func onLeak() { log(.didLeak(.init(vcPresentationDescription), from: .init(presentationDescription))) + let memoryLeak = UIVCMemoryLeak(name: self.presentationTitle) + UIVCMemoryLeakFileWriter().write(memoryLeak: memoryLeak) guard UserDefaults.standard.bool(forKey: enabledDisplayAlertOnMemoryLeaksKey) else { return } @@ -75,3 +77,80 @@ extension NSObjectProtocol { } private var memoryLeakTrackingEnabledKey = false + +private struct UIVCMemoryLeak { + + internal let name: String + + internal func jsonRepresentation() -> [String: Any] { + return [ + "name": self.name + ] + } +} + +private class UIVCMemoryLeakFileWriter { + + private let mlDirName = "presentation-memory-leaks" + private let tmpDir = "/tmp" + + internal func write(memoryLeak: UIVCMemoryLeak) { + let mlDirPath = self.tmpDir.appending("/\(self.mlDirName)") + self.createMemoryLeaksDir(pathToDir: mlDirPath) + let fileName = UUID().uuidString + ".json" + let filePath = mlDirPath.appending("/\(fileName)") + let fileURL = URL(fileURLWithPath: filePath) + let jsonWriter = JSONWriter(jsonPath: fileURL) + do { + try jsonWriter.writeJSON(memoryLeak.jsonRepresentation()) + } catch { + print("| Presentation >>> cannot write JSON file for memory leak ✗") + } + } + + private func createMemoryLeaksDir(pathToDir: String) { + do { + let mlDirURL = URL( + fileURLWithPath: pathToDir + ) + try FileManager.default.createDirectory( + at: mlDirURL, + withIntermediateDirectories: true + ) + } catch { + print("| Presentation >>> cannot create dir ✗ : \(self.mlDirName)") + print(error) + } + } +} + +private class JSONWriter { + + private var jsonPath: URL + + internal init(jsonPath: URL) { + self.jsonPath = jsonPath + } + + internal func writeJSON(_ json: [String: Any]) throws { + let fileName = self.jsonPath.lastPathComponent + let jsonData = try JSONSerialization.data( + withJSONObject: json, + options: [.prettyPrinted] + ) + guard let jsonString = String(data: jsonData, encoding: .utf8) else { + print("| Presentation >>> write ✗ : \(fileName)") + throw JSONWriterError.cannotWriteGivenFileAsJSON + } + try jsonString.write( + to: self.jsonPath, + atomically: true, + encoding: .utf8 + ) + print("| Presentation >>> write ✓ : \(fileName)") + } +} + +private enum JSONWriterError: Error { + case cannotWriteGivenFileAsJSON +} From b6da883ec36a406c623b164fb594e0347f024cab Mon Sep 17 00:00:00 2001 From: bartszczepaniak Date: Wed, 21 Feb 2024 15:14:18 +0000 Subject: [PATCH 2/2] Update `CHANGELOG.md` for release bump --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd53832..26f26de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.17.0 +- Save `json` files with `UIViewController` memory leak name + # 1.16.0 - Fix split view crash for iOS 17