This commit is contained in:
DDIsFriend
2023-08-23 09:24:40 +08:00
parent 6bd037c5dd
commit 63ca919ed5
494 changed files with 35308 additions and 6623 deletions

View File

@@ -0,0 +1,37 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import Foundation
import UIKit
class AboutViewController: UITableViewController {
@IBOutlet weak var versionLabel: UILabel!
@IBOutlet weak var naviItem: UINavigationItem!
var naviItemTitleLabel: UILabel?
//MARK: - init
override func viewDidLoad() {
super.viewDidLoad()
naviItemTitleLabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: 80, height: 40))
naviItemTitleLabel?.textAlignment = .center
naviItemTitleLabel?.textColor = Color.mainGreen
naviItemTitleLabel?.font = .boldSystemFont(ofSize: 20)
naviItemTitleLabel?.text = "About"
naviItem.titleView = naviItemTitleLabel
// let version = "1.7.2"
//
// self.versionLabel.text = "CocoaDebug Version ".appending(version)
tableView.tableFooterView = UIView()
}
}

View File

@@ -0,0 +1,217 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
class AppInfoViewController: UITableViewController {
@IBOutlet weak var labelVersionNumber: UILabel!
@IBOutlet weak var labelBuildNumber: UILabel!
@IBOutlet weak var labelBundleName: UILabel!
@IBOutlet weak var labelScreenResolution: UILabel!
@IBOutlet weak var labelDeviceModel: UILabel!
@IBOutlet weak var labelCrashCount: UILabel!
@IBOutlet weak var labelBundleID: UILabel!
@IBOutlet weak var labelserverURL: UILabel!
@IBOutlet weak var labelIOSVersion: UILabel!
@IBOutlet weak var labelHtml: UILabel!
@IBOutlet weak var crashSwitch: UISwitch!
@IBOutlet weak var logSwitch: UISwitch!
@IBOutlet weak var networkSwitch: UISwitch!
@IBOutlet weak var webViewSwitch: UISwitch!
@IBOutlet weak var slowAnimationsSwitch: UISwitch!
@IBOutlet weak var naviItem: UINavigationItem!
@IBOutlet weak var rnSwitch: UISwitch!
@IBOutlet weak var uiBlockingSwitch: UISwitch!
var naviItemTitleLabel: UILabel?
//MARK: - init
override func viewDidLoad() {
super.viewDidLoad()
naviItemTitleLabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: 80, height: 40))
naviItemTitleLabel?.textAlignment = .center
naviItemTitleLabel?.textColor = Color.mainGreen
naviItemTitleLabel?.font = .boldSystemFont(ofSize: 20)
naviItemTitleLabel?.text = "App"
naviItem.titleView = naviItemTitleLabel
labelCrashCount.frame.size = CGSize(width: 30, height: 20)
labelVersionNumber.text = CocoaDebugDeviceInfo.sharedInstance().appVersion
labelBuildNumber.text = CocoaDebugDeviceInfo.sharedInstance().appBuiltVersion
labelBundleName.text = CocoaDebugDeviceInfo.sharedInstance().appBundleName
labelScreenResolution.text = "\(Int(CocoaDebugDeviceInfo.sharedInstance().resolution.width))" + "*" + "\(Int(CocoaDebugDeviceInfo.sharedInstance().resolution.height))"
labelDeviceModel.text = "\(CocoaDebugDeviceInfo.sharedInstance().getPlatformString)"
labelBundleID.text = CocoaDebugDeviceInfo.sharedInstance().appBundleID
labelserverURL.text = CocoaDebugSettings.shared.serverURL
labelIOSVersion.text = UIDevice.current.systemVersion
if UIScreen.main.bounds.size.width == 320 {
labelHtml.font = UIFont.systemFont(ofSize: 15)
}
logSwitch.isOn = CocoaDebugSettings.shared.enableLogMonitoring
networkSwitch.isOn = !CocoaDebugSettings.shared.disableNetworkMonitoring
rnSwitch.isOn = CocoaDebugSettings.shared.enableRNMonitoring
webViewSwitch.isOn = CocoaDebugSettings.shared.enableWKWebViewMonitoring
slowAnimationsSwitch.isOn = CocoaDebugSettings.shared.slowAnimations
crashSwitch.isOn = CocoaDebugSettings.shared.enableCrashRecording
uiBlockingSwitch.isOn = CocoaDebugSettings.shared.enableUIBlockingMonitoring
logSwitch.addTarget(self, action: #selector(logSwitchChanged), for: UIControl.Event.valueChanged)
networkSwitch.addTarget(self, action: #selector(networkSwitchChanged), for: UIControl.Event.valueChanged)
rnSwitch.addTarget(self, action: #selector(rnSwitchChanged), for: UIControl.Event.valueChanged)
webViewSwitch.addTarget(self, action: #selector(webViewSwitchChanged), for: UIControl.Event.valueChanged)
slowAnimationsSwitch.addTarget(self, action: #selector(slowAnimationsSwitchChanged), for: UIControl.Event.valueChanged)
crashSwitch.addTarget(self, action: #selector(crashSwitchChanged), for: UIControl.Event.valueChanged)
uiBlockingSwitch.addTarget(self, action: #selector(uiBlockingSwitchChanged), for: UIControl.Event.valueChanged)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let count = UserDefaults.standard.integer(forKey: "crashCount_CocoaDebug")
labelCrashCount.text = "\(count)"
labelCrashCount.textColor = count > 0 ? .red : .white
}
//MARK: - alert
func showAlert() {
let alert = UIAlertController.init(title: nil, message: "You must restart APP to ensure the changes take effect", preferredStyle: .alert)
let cancelAction = UIAlertAction.init(title: "Restart later", style: .cancel, handler: nil)
let okAction = UIAlertAction.init(title: "Restart now", style: .destructive) { _ in
exit(0)
}
alert.addAction(cancelAction)
alert.addAction(okAction)
alert.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
alert.popoverPresentationController?.sourceView = self.view
alert.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
self.present(alert, animated: true, completion: nil)
}
//MARK: - target action
@objc func slowAnimationsSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.slowAnimations = slowAnimationsSwitch.isOn
// self.showAlert()
}
@objc func uiBlockingSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.enableUIBlockingMonitoring = uiBlockingSwitch.isOn
if uiBlockingSwitch.isOn == true {
WindowHelper.shared.startUIBlockingMonitoring()
} else {
WindowHelper.shared.stopUIBlockingMonitoring()
}
}
@objc func crashSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.enableCrashRecording = crashSwitch.isOn
self.showAlert()
}
@objc func networkSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.disableNetworkMonitoring = !networkSwitch.isOn
self.showAlert()
}
@objc func logSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.enableLogMonitoring = logSwitch.isOn
self.showAlert()
}
@objc func rnSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.enableRNMonitoring = rnSwitch.isOn
self.showAlert()
}
@objc func webViewSwitchChanged(sender: UISwitch) {
CocoaDebugSettings.shared.enableWKWebViewMonitoring = webViewSwitch.isOn
self.showAlert()
}
}
//MARK: - UITableViewDelegate
extension AppInfoViewController {
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
if section == 0 {
return 56
}
return 38
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.section == 1 && indexPath.row == 4 {
if labelserverURL.text == nil || labelserverURL.text == "" {
return 0
}
}
return 44
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
tableView.deselectRow(at: indexPath, animated: true)
if indexPath.section == 1 && indexPath.row == 2 {
UIPasteboard.general.string = CocoaDebugDeviceInfo.sharedInstance().appBundleName
let alert = UIAlertController.init(title: "copied bundle name to clipboard", message: nil, preferredStyle: .alert)
let action = UIAlertAction.init(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
alert.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
alert.popoverPresentationController?.sourceView = self.view
alert.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
self.present(alert, animated: true, completion: nil)
}
if indexPath.section == 1 && indexPath.row == 3 {
UIPasteboard.general.string = CocoaDebugDeviceInfo.sharedInstance().appBundleID
let alert = UIAlertController.init(title: "copied bundle id to clipboard", message: nil, preferredStyle: .alert)
let action = UIAlertAction.init(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
alert.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
alert.popoverPresentationController?.sourceView = self.view
alert.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
self.present(alert, animated: true, completion: nil)
}
if indexPath.section == 1 && indexPath.row == 4 {
if labelserverURL.text == nil || labelserverURL.text == "" {return}
UIPasteboard.general.string = CocoaDebugSettings.shared.serverURL
let alert = UIAlertController.init(title: "copied server to clipboard", message: nil, preferredStyle: .alert)
let action = UIAlertAction.init(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
alert.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
alert.popoverPresentationController?.sourceView = self.view
alert.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
self.present(alert, animated: true, completion: nil)
}
}
}

View File

@@ -0,0 +1,41 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
class CrashCell: UITableViewCell {
@IBOutlet weak var textview: CustomTextView!
override func awakeFromNib() {
super.awakeFromNib()
textview.isUserInteractionEnabled = false
}
var crash: _CrashModel? {
didSet {
guard let crash = crash else {return}
if let formatDate = _OCLoggerFormat.formatDate(crash.date) {
let content = "\("\(String(describing: formatDate))\n")\(crash.name ?? "unknown crash")"
textview.text = content
let attstr = NSMutableAttributedString(string: content)
attstr.addAttribute(.foregroundColor,
value: UIColor.white, range: NSMakeRange(0, content.count))
let range = NSMakeRange(0, formatDate.count)
attstr.addAttribute(.foregroundColor, value: Color.mainGreen, range: range)
attstr.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: 12), range: range)
textview.attributedText = attstr
}
}
}
}

View File

@@ -0,0 +1,62 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
class CrashDetailViewController: UITableViewController {
@IBOutlet weak var textviewName: CustomTextView!
@IBOutlet weak var textviewReason: CustomTextView!
@IBOutlet weak var textviewStackTraces: CustomTextView!
@IBOutlet weak var naviItem: UINavigationItem!
var naviItemTitleLabel: UILabel?
var crash: _CrashModel?
static func instanceFromStoryBoard() -> CrashDetailViewController {
let storyboard = UIStoryboard(name: "App", bundle: Bundle(for: CocoaDebug.self))
return storyboard.instantiateViewController(withIdentifier: "CrashDetailViewController") as! CrashDetailViewController
}
//MARK - init
override func viewDidLoad() {
super.viewDidLoad()
naviItemTitleLabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: 80, height: 40))
naviItemTitleLabel?.textAlignment = .center
naviItemTitleLabel?.textColor = Color.mainGreen
naviItemTitleLabel?.font = .boldSystemFont(ofSize: 20)
naviItemTitleLabel?.text = "Details"
naviItem.titleView = naviItemTitleLabel
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 50
tableView.delegate = self
textviewName.text = "\(crash?.name ?? "N/A")"
textviewReason.text = "\(crash?.reason ?? "N/A")"
let contentStack = crash?.callStacks?.reduce("", {
$0 == "" ? $1 : $0 + "\n" + $1
})
textviewStackTraces.text = contentStack
}
}
//MARK: - UITableViewDelegate
extension CrashDetailViewController {
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
}

View File

@@ -0,0 +1,115 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
class CrashListViewController: UITableViewController {
var models: [_CrashModel] = [_CrashModel]()
@IBOutlet weak var naviItem: UINavigationItem!
var naviItemTitleLabel: UILabel?
//MARK: - init
override func viewDidLoad() {
super.viewDidLoad()
naviItemTitleLabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: 80, height: 40))
naviItemTitleLabel?.textAlignment = .center
naviItemTitleLabel?.textColor = Color.mainGreen
naviItemTitleLabel?.font = .boldSystemFont(ofSize: 20)
naviItemTitleLabel?.text = "Crash"
naviItem.titleView = naviItemTitleLabel
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action:#selector(CrashListViewController.deleteCrashes))
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
models = CrashStoreManager.shared.crashArray
tableView.reloadData()
}
//MARK: - target action
@objc func deleteCrashes() {
models = []
CrashStoreManager.shared.resetCrashs()
// dispatch_main_async_safe { [weak self] in
tableView.reloadData()
// }
}
}
//MARK: - UITableViewDataSource
extension CrashListViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CrashCell", for: indexPath)
as! CrashCell
cell.crash = models[indexPath.row]
cell.accessoryType = .none
return cell
}
}
//MARK: - UITableViewDelegate
extension CrashListViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let vc = CrashDetailViewController.instanceFromStoryBoard()
vc.crash = models[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .destructive, title: "Delete") { [weak self] (action, sourceView, completionHandler) in
guard let models = self?.models else {return}
CrashStoreManager.shared.removeCrash(models[indexPath.row])
self?.models.remove(at: indexPath.row)
// self?.dispatch_main_async_safe { [weak self] in
self?.tableView.deleteRows(at: [indexPath], with: .automatic)
// }
completionHandler(true)
}
return UISwipeActionsConfiguration(actions: [delete])
}
//MARK: - only for ios8/ios9/ios10, not ios11
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Delete"
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
CrashStoreManager.shared.removeCrash(models[indexPath.row])
self.models.remove(at: indexPath.row)
// self.dispatch_main_async_safe { [weak self] in
self.tableView.deleteRows(at: [indexPath], with: .automatic)
// }
}
}
}

View File

@@ -0,0 +1,98 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
import Darwin
func exceptionHandler(exception: NSException) {
if CrashLogger.shared.crashed {
return
}
CrashLogger.shared.crashed = true
CrashLogger.addCrash(name: exception.name.rawValue, reason: exception.reason)
}
func handleSignal(signal: Int32) {
if CrashLogger.shared.crashed {
return
}
CrashLogger.shared.crashed = true
switch signal {
case SIGILL:
CrashLogger.addCrash(name: "SIGILL", reason: nil)
case SIGABRT:
CrashLogger.addCrash(name: "SIGABRT", reason: nil)
case SIGFPE:
CrashLogger.addCrash(name: "SIGFPE", reason: nil)
case SIGBUS:
CrashLogger.addCrash(name: "SIGBUS", reason: nil)
case SIGSEGV:
CrashLogger.addCrash(name: "SIGSEGV", reason: nil)
case SIGSYS:
CrashLogger.addCrash(name: "SIGSYS", reason: nil)
case SIGPIPE:
CrashLogger.addCrash(name: "SIGPIPE", reason: nil)
case SIGTRAP:
CrashLogger.addCrash(name: "SIGTRAP", reason: nil)
default: break
}
}
class CrashLogger {
static let shared = CrashLogger()
private init() {}
var hasBeenRegistered = false
var crashed = false
var enable: Bool = false {
didSet {
if enable {
CrashLogger.shared.register()
}
else {
CrashLogger.shared.unregister()
}
}
}
func register() {
if hasBeenRegistered == false {
hasBeenRegistered = true
NSSetUncaughtExceptionHandler(exceptionHandler)
signal(SIGILL, handleSignal)
signal(SIGABRT, handleSignal)
signal(SIGFPE, handleSignal)
signal(SIGBUS, handleSignal)
signal(SIGSEGV, handleSignal)
signal(SIGSYS, handleSignal)
signal(SIGPIPE, handleSignal)
signal(SIGTRAP, handleSignal)
}
}
func unregister() {
if hasBeenRegistered == true {
hasBeenRegistered = false
NSSetUncaughtExceptionHandler(nil)
signal(SIGILL, SIG_DFL)
signal(SIGABRT, SIG_DFL)
signal(SIGFPE, SIG_DFL)
signal(SIGBUS, SIG_DFL)
signal(SIGSEGV, SIG_DFL)
signal(SIGSYS, SIG_DFL)
signal(SIGPIPE, SIG_DFL)
signal(SIGTRAP, SIG_DFL)
}
}
static func addCrash(name: String, reason: String?) {
let newCrash = _CrashModel(name: name, reason: reason)
CrashStoreManager.shared.addCrash(newCrash)
}
}

View File

@@ -0,0 +1,79 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import Foundation
class CrashStoreManager {
var crashArray: [_CrashModel] = [_CrashModel]()
static let shared = CrashStoreManager()
private init() {
crashArray = self.getCrashs()
}
//MARK: - public
func addCrash(_ crash: _CrashModel) {
if self.crashArray.count >= 1000 {
if self.crashArray.count > 0 {
self.crashArray.remove(at: 0)
}
}
self.crashArray.append(crash)
archiveCrashs(self.crashArray)
}
func removeCrash(_ model: _CrashModel) {
if let index = self.crashArray.firstIndex(where: { (crash) -> Bool in
return crash.id == model.id
}) {
self.crashArray.remove(at: index)
}
archiveCrashs(self.crashArray)
}
func resetCrashs() {
if self.crashArray.count > 0 {
self.crashArray.removeAll()
UserDefaults.standard.removeObject(forKey: "crashArchive_CocoaDebug")
UserDefaults.standard.removeObject(forKey: "crashCount_CocoaDebug")
UserDefaults.standard.synchronize()
}
}
//MARK: - private
private func archiveCrashs(_ crashs: [_CrashModel]) {
do {
var dataArchive: Data
if #available(iOS 11.0, *) {
dataArchive = try NSKeyedArchiver.archivedData(withRootObject: crashs, requiringSecureCoding: false)
} else {
// Fallback on earlier versions
dataArchive = NSKeyedArchiver.archivedData(withRootObject: crashs)
}
UserDefaults.standard.set(dataArchive, forKey: "crashArchive_CocoaDebug")
UserDefaults.standard.set(crashs.count, forKey: "crashCount_CocoaDebug")
UserDefaults.standard.synchronize()
} catch {}
}
private func getCrashs() -> [_CrashModel] {
guard let data = UserDefaults.standard.object(forKey: "crashArchive_CocoaDebug") as? Data else {return []}
do {
if #available(iOS 9.0, *) {
let dataArchive = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
return dataArchive as! [_CrashModel]
} else {
// Fallback on earlier versions
return []
}
} catch {
return []
}
}
}

View File

@@ -0,0 +1,119 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import Foundation
import UIKit
class IgnoredURLsViewController: UITableViewController {
var ignoredURLs: Array<String>?
var onlyURLs: Array<String>?
var ignoredPrefixLogs: Array<String>?
var onlyPrefixLogs: Array<String>?
@IBOutlet weak var naviItem: UINavigationItem!
var naviItemTitleLabel: UILabel?
//MARK: - init
override func viewDidLoad() {
super.viewDidLoad()
naviItemTitleLabel = UILabel.init(frame: CGRect(x: 0, y: 0, width: 80, height: 40))
naviItemTitleLabel?.textAlignment = .center
naviItemTitleLabel?.textColor = Color.mainGreen
naviItemTitleLabel?.font = .boldSystemFont(ofSize: 20)
naviItemTitleLabel?.text = "Settings"
naviItem.titleView = naviItemTitleLabel
tableView.tableFooterView = UIView()
ignoredURLs = CocoaDebugSettings.shared.ignoredURLs
onlyURLs = CocoaDebugSettings.shared.onlyURLs
ignoredPrefixLogs = CocoaDebugSettings.shared.ignoredPrefixLogs
onlyPrefixLogs = CocoaDebugSettings.shared.onlyPrefixLogs
}
}
//MARK: - UITableViewDataSource
extension IgnoredURLsViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return ignoredURLs?.count ?? 0
case 1:
return onlyURLs?.count ?? 0
case 2:
return ignoredPrefixLogs?.count ?? 0
case 3:
return onlyPrefixLogs?.count ?? 0
default:
break
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell.init(style: .default, reuseIdentifier: "CocoaDebugSettingsCell")
cell.textLabel?.textColor = .white
cell.contentView.backgroundColor = .black
cell.selectionStyle = .none
switch indexPath.section {
case 0:
cell.textLabel?.text = ignoredURLs?[indexPath.row]
case 1:
cell.textLabel?.text = onlyURLs?[indexPath.row]
case 2:
cell.textLabel?.text = ignoredPrefixLogs?[indexPath.row]
case 3:
cell.textLabel?.text = onlyPrefixLogs?[indexPath.row]
default:
break
}
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "ignored URLs"
case 1:
return "only URLs"
case 2:
return "ignored Prefix Logs"
case 3:
return "only Prefix Logs"
default:
break
}
return ""
}
}
//MARK: - UITableViewDelegate
extension IgnoredURLsViewController {
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 20
}
}

View File

@@ -0,0 +1,57 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
import UIKit
class _CrashModel: NSObject, NSCoding {
var id: String
var date: Date
var reason: String?
var name: String?
var callStacks: [String]?
init(name: String, reason: String?) {
id = UUID().uuidString
date = Date()
self.reason = reason
self.name = name
callStacks = Thread.callStackSymbols
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(date, forKey: "date")
aCoder.encode(reason, forKey: "reason")
aCoder.encode(name, forKey: "name")
aCoder.encode(callStacks, forKey: "callstacks")
}
required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: "id") as? String ?? ""
date = aDecoder.decodeObject(forKey: "date") as? Date ?? Date()
reason = aDecoder.decodeObject(forKey: "reason") as? String
name = aDecoder.decodeObject(forKey: "name") as? String
callStacks = aDecoder.decodeObject(forKey: "callstacks") as? [String]
}
func toString() -> String {
let stringContent = NSMutableString()
stringContent.append("Date: \(String(describing: _OCLoggerFormat.formatDate(date)))\n")
stringContent.append("Name: \(name ?? "N/A")\n")
stringContent.append("Reason: \(reason ?? "N/A")\n")
let stacks = (callStacks ?? []).reduce("", {
return "\($0)\($1)\n"
})
stringContent.append(stacks)
return stringContent as String
}
}