From 4514fe1c2c23757eb8418dbf55cbda4f14b91ffb Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Fri, 8 Dec 2023 18:15:48 -0600 Subject: [PATCH] Displays detailed error log in-app with Quick Look --- .../Error Log/ErrorLogViewController.swift | 74 +++++++++++-------- AltStoreCore/Extensions/Logger+AltStore.swift | 2 +- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/AltStore/Settings/Error Log/ErrorLogViewController.swift b/AltStore/Settings/Error Log/ErrorLogViewController.swift index 29bc814a..0e29c9e8 100644 --- a/AltStore/Settings/Error Log/ErrorLogViewController.swift +++ b/AltStore/Settings/Error Log/ErrorLogViewController.swift @@ -8,6 +8,7 @@ import UIKit import SafariServices +import QuickLook import AltStoreCore import Roxas @@ -37,6 +38,8 @@ final class ErrorLogViewController: UITableViewController @IBOutlet private var exportLogButton: UIBarButtonItem! @IBOutlet private var clearLogButton: UIBarButtonItem! + private var _exportedLogURL: URL? + override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } @@ -286,10 +289,10 @@ private extension ErrorLogViewController // All logs since the app launched. let position = store.position(timeIntervalSinceLatestBoot: 0) + let predicate = NSPredicate(format: "subsystem == %@", Logger.altstoreSubsystem) - let entries = try store.getEntries(at: position) + let entries = try store.getEntries(at: position, matching: predicate) .compactMap { $0 as? OSLogEntryLog } - .filter { $0.subsystem.contains(Logger.altstoreSubsystem) } .map { "[\($0.date.formatted())] [\($0.category)] [\($0.level.localizedName)] \($0.composedMessage)" } let outputText = entries.joined(separator: "\n") @@ -297,35 +300,17 @@ private extension ErrorLogViewController let outputDirectory = FileManager.default.uniqueTemporaryURL() try FileManager.default.createDirectory(at: outputDirectory, withIntermediateDirectories: true) - defer { - do - { - try FileManager.default.removeItem(at: outputDirectory) - } - catch - { - Logger.main.error("Failed to remove temporary log directory \(outputDirectory.lastPathComponent, privacy: .public). \(error.localizedDescription, privacy: .public)") - } - } - - let outputURL = outputDirectory.appendingPathComponent("altlog.txt") + let outputURL = outputDirectory.appendingPathComponent("altstore.log") try outputText.write(to: outputURL, atomically: true, encoding: .utf8) - try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in - Task { @MainActor in - let activityViewController = UIActivityViewController(activityItems: [outputURL], applicationActivities: nil) - activityViewController.completionWithItemsHandler = { (activityType, completed, _, error) in - if let error - { - continuation.resume(throwing: error) - } - else - { - continuation.resume() - } - } - self.present(activityViewController, animated: true) - } + await MainActor.run { + self._exportedLogURL = outputURL + + let previewController = QLPreviewController() + previewController.delegate = self + previewController.dataSource = self + previewController.view.tintColor = .altPrimary + self.present(previewController, animated: true) } } catch @@ -448,3 +433,34 @@ extension ErrorLogViewController } } } + +extension ErrorLogViewController: QLPreviewControllerDataSource, QLPreviewControllerDelegate +{ + func numberOfPreviewItems(in controller: QLPreviewController) -> Int + { + return 1 + } + + func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem + { + return (_exportedLogURL as? NSURL) ?? NSURL() + } + + func previewControllerDidDismiss(_ controller: QLPreviewController) + { + guard let exportedLogURL = _exportedLogURL else { return } + + let parentDirectory = exportedLogURL.deletingLastPathComponent() + + do + { + try FileManager.default.removeItem(at: parentDirectory) + } + catch + { + Logger.main.error("Failed to remove temporary log directory \(parentDirectory.lastPathComponent, privacy: .public). \(error.localizedDescription, privacy: .public)") + } + + _exportedLogURL = nil + } +} diff --git a/AltStoreCore/Extensions/Logger+AltStore.swift b/AltStoreCore/Extensions/Logger+AltStore.swift index 4e02169a..13430e6b 100644 --- a/AltStoreCore/Extensions/Logger+AltStore.swift +++ b/AltStoreCore/Extensions/Logger+AltStore.swift @@ -10,7 +10,7 @@ public extension Logger { - static let altstoreSubsystem = Bundle.main.bundleIdentifier! + static let altstoreSubsystem = "com.rileytestut.AltStore" // Hardcoded because Bundle.main.bundleIdentifier is different for every user static let main = Logger(subsystem: altstoreSubsystem, category: "Main") static let sideload = Logger(subsystem: altstoreSubsystem, category: "Sideload")