Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
signalapp
GitHub Repository: signalapp/Signal-iOS
Path: blob/main/Signal/src/ViewControllers/AppSettings/DebugLogPreviewViewController.swift
1 views
//
// Copyright 2026 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import SignalServiceKit
import SignalUI

final class DebugLogPreviewViewController: OWSViewController {

    private let textView = UITextView()

    override func viewDidLoad() {
        super.viewDidLoad()

        loadLogs()

        title = OWSLocalizedString(
            "DEBUG_LOG_PREVIEW_TITLE",
            comment: "Title for the debug log preview screen",
        )

        view.backgroundColor = .Signal.groupedBackground

        navigationItem.rightBarButtonItem = .cancelButton(dismissingFrom: self)

        // UITableView does not have the text-rendering optimizations that
        // UITextView with scrolling enabled has, and the app freezes when
        // trying to load this much text, so fake the style with one
        // full-height "cell" instead.
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.spacing = 12
        stackView.isLayoutMarginsRelativeArrangement = true
        stackView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 12, leading: 20, bottom: 20, trailing: 20)
        view.addSubview(stackView)
        stackView.autoPinEdgesToSuperviewSafeArea()

        let headerLabel = UILabel()
        stackView.addArrangedSubview(headerLabel)
        stackView.setCustomSpacing(24, after: headerLabel)
        headerLabel.text = OWSLocalizedString(
            "DEBUG_LOG_PREVIEW_HEADER",
            comment: "Header text displayed above the debug log preview",
        )
        headerLabel.font = .dynamicTypeFootnote
        headerLabel.textColor = .Signal.secondaryLabel
        headerLabel.numberOfLines = 0
        headerLabel.autoPinWidthToSuperviewMargins(withInset: 24)

        let cellContainer = UIView()
        stackView.addArrangedSubview(cellContainer)
        cellContainer.autoPinWidthToSuperviewMargins()
        cellContainer.backgroundColor = .Signal.secondaryGroupedBackground
        cellContainer.layer.cornerRadius = OWSTableViewController2.cellRounding
        cellContainer.clipsToBounds = true
        cellContainer.addSubview(textView)
        textView.autoPinEdgesToSuperviewEdges()
        textView.isEditable = false
        textView.font = .monospacedSystemFont(ofSize: 15, weight: .regular)
        textView.backgroundColor = .clear
        textView.textColor = .Signal.secondaryLabel
        textView.textContainerInset = .init(margin: 20)
        textView.textContainer.lineFragmentPadding = 0
        textView.verticalScrollIndicatorInsets = .init(hMargin: 0, vMargin: OWSTableViewController2.cellRounding / 2)
    }

    private func loadLogs() {
        Logger.flush()

        self.textView.text = DebugLogger.shared.allLogFilePaths.reduce(
            into: "",
        ) { partialResult, logFilePath in
            do {
                let logData = try Data(contentsOf: URL(fileURLWithPath: logFilePath))
                let logText = String(data: logData, encoding: .utf8)

                guard let logText else {
                    Logger.warn("Could not decode log file")
                    return
                }

                partialResult += logText + "\n\n"
            } catch {
                Logger.warn("\(error)")
            }
        }
    }

}