Skip to content

Commit 83608f2

Browse files
Merge pull request #98 from iZettle/experiment-saving-vc-memory-leaks-into-json-files
Save `json` files with `UIViewController` memory leak name
2 parents 0ef9f76 + b6da883 commit 83608f2

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

Diff for: CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 1.17.0
2+
- Save `json` files with `UIViewController` memory leak name
3+
14
# 1.16.0
25
- Fix split view crash for iOS 17
36

Diff for: Presentation/MemoryUtils.swift

+79
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public let enabledDisplayAlertOnMemoryLeaksKey = "enabledDisplayAlertOnMemoryLea
3434

3535
func onLeak() {
3636
log(.didLeak(.init(vcPresentationDescription), from: .init(presentationDescription)))
37+
let memoryLeak = UIVCMemoryLeak(name: self.presentationTitle)
38+
UIVCMemoryLeakFileWriter().write(memoryLeak: memoryLeak)
3739

3840
guard UserDefaults.standard.bool(forKey: enabledDisplayAlertOnMemoryLeaksKey) else { return }
3941

@@ -75,3 +77,80 @@ extension NSObjectProtocol {
7577
}
7678

7779
private var memoryLeakTrackingEnabledKey = false
80+
81+
private struct UIVCMemoryLeak {
82+
83+
internal let name: String
84+
85+
internal func jsonRepresentation() -> [String: Any] {
86+
return [
87+
"name": self.name
88+
]
89+
}
90+
}
91+
92+
private class UIVCMemoryLeakFileWriter {
93+
94+
private let mlDirName = "presentation-memory-leaks"
95+
private let tmpDir = "/tmp"
96+
97+
internal func write(memoryLeak: UIVCMemoryLeak) {
98+
let mlDirPath = self.tmpDir.appending("/\(self.mlDirName)")
99+
self.createMemoryLeaksDir(pathToDir: mlDirPath)
100+
let fileName = UUID().uuidString + ".json"
101+
let filePath = mlDirPath.appending("/\(fileName)")
102+
let fileURL = URL(fileURLWithPath: filePath)
103+
let jsonWriter = JSONWriter(jsonPath: fileURL)
104+
do {
105+
try jsonWriter.writeJSON(memoryLeak.jsonRepresentation())
106+
} catch {
107+
print("| Presentation >>> cannot write JSON file for memory leak ✗")
108+
}
109+
}
110+
111+
private func createMemoryLeaksDir(pathToDir: String) {
112+
do {
113+
let mlDirURL = URL(
114+
fileURLWithPath: pathToDir
115+
)
116+
try FileManager.default.createDirectory(
117+
at: mlDirURL,
118+
withIntermediateDirectories: true
119+
)
120+
} catch {
121+
print("| Presentation >>> cannot create dir ✗ : \(self.mlDirName)")
122+
print(error)
123+
}
124+
}
125+
}
126+
127+
private class JSONWriter {
128+
129+
private var jsonPath: URL
130+
131+
internal init(jsonPath: URL) {
132+
self.jsonPath = jsonPath
133+
}
134+
135+
internal func writeJSON(_ json: [String: Any]) throws {
136+
let fileName = self.jsonPath.lastPathComponent
137+
let jsonData = try JSONSerialization.data(
138+
withJSONObject: json,
139+
options: [.prettyPrinted]
140+
)
141+
guard let jsonString = String(data: jsonData, encoding: .utf8) else {
142+
print("| Presentation >>> write ✗ : \(fileName)")
143+
throw JSONWriterError.cannotWriteGivenFileAsJSON
144+
}
145+
try jsonString.write(
146+
to: self.jsonPath,
147+
atomically: true,
148+
encoding: .utf8
149+
)
150+
print("| Presentation >>> write ✓ : \(fileName)")
151+
}
152+
}
153+
154+
private enum JSONWriterError: Error {
155+
case cannotWriteGivenFileAsJSON
156+
}

0 commit comments

Comments
 (0)