Skip to content

Instantly share code, notes, and snippets.

@calda
Created April 2, 2019 21:32
Show Gist options
  • Save calda/5e76b04541ae882ca069ccdbd645dabf to your computer and use it in GitHub Desktop.
Save calda/5e76b04541ae882ca069ccdbd645dabf to your computer and use it in GitHub Desktop.
LoggingManager.swift
//
// DateFormatterHelpers.swift
// WindowKit
//
// Created by Cal Stephens on 1/20/19.
// Copyright © 2019 Cal Stephens. All rights reserved.
//
import Foundation
public extension DateFormatter {
convenience init(withFormat format: String) {
self.init()
self.dateFormat = format
}
// ...
}
//
// LoggingManager.swift
// WindowKit
//
// Created by Cal Stephens on 11/30/18.
// Copyright © 2018 Cal Stephens. All rights reserved.
//
import Foundation
public class LoggingManager: Codable {
// MARK: - Singleton
public static var shared: LoggingManager = UserDefaults.standard.codableObject(for: userDefaultsKey) ?? LoggingManager()
private static let userDefaultsKey = "WDLoggingManagerKey"
private static let dateFormatter = DateFormatter(withFormat: "dd MMM yyyy, hh:mm:ss.SSSS a")
#if os(iOS)
private let maximumNumberOfLogMessages = 500
#elseif os(watchOS)
private let maximumNumberOfLogMessages = 200
#endif
// MARK: - Instance
public private(set) var logMessages: [String] {
didSet {
if logMessages.count > maximumNumberOfLogMessages {
logMessages.remove(at: 0)
}
}
}
private init() {
self.logMessages = []
}
private func save() {
UserDefaults.shared.setCodableObject(self, forKey: LoggingManager.userDefaultsKey)
}
public func log(_ message: String) {
#if os(iOS)
let platform = "iOS"
#elseif os(watchOS)
let platform = "watchOS"
#endif
let time = LoggingManager.dateFormatter.string(from: .now)
let logEntry = "[\(time)] [\(platform)]: \(message)"
logMessages.append(logEntry)
save()
NSLog(message)
}
public func fatalError(_ message: String, file: StaticString = #file, line: UInt = #line) -> Never {
log("🛑 [FATAL ISSUE] " + message)
Swift.fatalError(message, file: file, line: line)
}
public func debugFatalError(_ message: String, file: StaticString = #file, line: UInt = #line) {
log("🛑 [CRITICAL ISSUE] " + message)
#if DEBUG
Swift.fatalError(message, file: file, line: line)
#endif
}
private func date(from logMessage: String) -> Date {
let dateString = logMessage.components(separatedBy: CharacterSet(charactersIn: "[]"))[1]
return LoggingManager.dateFormatter.date(from: dateString) ?? .distantPast
}
public func logAll(_ messages: [String]) {
for message in messages {
logMessages.append(message)
}
logMessages.sort(by: { lhs, rhs in
date(from: lhs) < date(from: rhs)
})
save()
}
public func discardLogContents() {
logMessages.removeAll()
save()
}
}
//
// UserDefaults+Helpers.swift
// WindowKit
//
// Created by Cal Stephens on 12/27/18.
// Copyright © 2018 Cal Stephens. All rights reserved.
//
import Foundation
// MARK: - UserDefaults + Codable
public extension UserDefaults {
/// Saves a Codable / Encodable object to the given key
func setCodableObject<T: Encodable>(
_ object: T,
forKey key: String,
using encoder: JSONEncoder = JSONEncoder())
{
let data = try? encoder.encode(object)
setValue(data, forKey: key)
}
/// Retrieves a Codable / Decodable object of the given type from the given key
func codableObject<T: Decodable>(
of type: T.Type = T.self,
for key: String,
using decoder: JSONDecoder = JSONDecoder()) -> T?
{
guard let data = data(forKey: key) else { return nil }
return try? decoder.decode(T.self, from: data)
}
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment