mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Logging changes
- Adds `Logging` protocol - Moves to Swift-style `OSLog` usage os_log to Logger os_log audit Replacment of os.log with Logging
This commit is contained in:
@@ -11,8 +11,9 @@ import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import SafariServices
|
||||
import RSCore
|
||||
|
||||
class FeedbinAccountViewController: UITableViewController {
|
||||
class FeedbinAccountViewController: UITableViewController, Logging {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@@ -116,7 +117,9 @@ class FeedbinAccountViewController: UITableViewController {
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .basic)
|
||||
} catch {}
|
||||
} catch {
|
||||
self.logger.error("Error removing credentials: \(error.localizedDescription, privacy: .public).")
|
||||
}
|
||||
try self.account?.storeCredentials(credentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
@@ -132,6 +135,7 @@ class FeedbinAccountViewController: UITableViewController {
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public).")
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error"))
|
||||
|
||||
@@ -10,9 +10,10 @@ import UIKit
|
||||
import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import RSCore
|
||||
import SafariServices
|
||||
|
||||
class NewsBlurAccountViewController: UITableViewController {
|
||||
class NewsBlurAccountViewController: UITableViewController, Logging {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@@ -118,7 +119,9 @@ class NewsBlurAccountViewController: UITableViewController {
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .newsBlurBasic)
|
||||
try self.account?.removeCredentials(type: .newsBlurSessionId)
|
||||
} catch {}
|
||||
} catch {
|
||||
self.logger.error("Error removing credentials: \(error.localizedDescription, privacy: .public).")
|
||||
}
|
||||
try self.account?.storeCredentials(basicCredentials)
|
||||
try self.account?.storeCredentials(sessionCredentials)
|
||||
|
||||
@@ -135,6 +138,7 @@ class NewsBlurAccountViewController: UITableViewController {
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public).")
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid username/password combination.", comment: "Credentials Error"))
|
||||
|
||||
@@ -11,8 +11,9 @@ import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import SafariServices
|
||||
import RSCore
|
||||
|
||||
class ReaderAPIAccountViewController: UITableViewController {
|
||||
class ReaderAPIAccountViewController: UITableViewController, Logging {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@@ -187,6 +188,7 @@ class ReaderAPIAccountViewController: UITableViewController {
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public).")
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid username/password combination.", comment: "Credentials Error"))
|
||||
|
||||
@@ -11,14 +11,13 @@ import RSCore
|
||||
import RSWeb
|
||||
import Account
|
||||
import BackgroundTasks
|
||||
import os.log
|
||||
import Secrets
|
||||
import WidgetKit
|
||||
|
||||
var appDelegate: AppDelegate!
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, UnreadCountProvider {
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, UnreadCountProvider, Logging {
|
||||
|
||||
private var bgTaskDispatchQueue = DispatchQueue.init(label: "BGTaskScheduler")
|
||||
|
||||
@@ -36,8 +35,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
||||
}
|
||||
}
|
||||
|
||||
var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application")
|
||||
|
||||
var userNotificationManager: UserNotificationManager!
|
||||
var faviconDownloader: FaviconDownloader!
|
||||
var imageDownloader: ImageDownloader!
|
||||
@@ -83,7 +80,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
||||
|
||||
let isFirstRun = AppDefaults.shared.isFirstRun
|
||||
if isFirstRun {
|
||||
os_log("Is first run.", log: log, type: .info)
|
||||
logger.info("Is first run.")
|
||||
}
|
||||
|
||||
if isFirstRun && !AccountManager.shared.anyAccountHasAtLeastOneFeed() {
|
||||
@@ -166,7 +163,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
||||
func resumeDatabaseProcessingIfNecessary() {
|
||||
if AccountManager.shared.isSuspended {
|
||||
AccountManager.shared.resumeAll()
|
||||
os_log("Application processing resumed.", log: self.log, type: .info)
|
||||
logger.info("Application processing resumed.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +273,7 @@ private extension AppDelegate {
|
||||
self.waitBackgroundUpdateTask = UIApplication.shared.beginBackgroundTask { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.completeProcessing(true)
|
||||
os_log("Accounts wait for progress terminated for running too long.", log: self.log, type: .info)
|
||||
self.logger.info("Accounts wait for progress terminated for running too long.")
|
||||
}
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
@@ -288,18 +285,18 @@ private extension AppDelegate {
|
||||
|
||||
func waitToComplete(completion: @escaping (Bool) -> Void) {
|
||||
guard UIApplication.shared.applicationState == .background else {
|
||||
os_log("App came back to foreground, no longer waiting.", log: self.log, type: .info)
|
||||
logger.info("App came back to foreground, no longer waiting.")
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
|
||||
if AccountManager.shared.refreshInProgress || isSyncArticleStatusRunning {
|
||||
os_log("Waiting for sync to finish...", log: self.log, type: .info)
|
||||
logger.info("Waiting for sync to finish...")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
|
||||
self?.waitToComplete(completion: completion)
|
||||
}
|
||||
} else {
|
||||
os_log("Refresh progress complete.", log: self.log, type: .info)
|
||||
logger.info("Refresh progress complete.")
|
||||
completion(true)
|
||||
}
|
||||
}
|
||||
@@ -324,9 +321,9 @@ private extension AppDelegate {
|
||||
self.syncBackgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
|
||||
}
|
||||
|
||||
self.syncBackgroundUpdateTask = UIApplication.shared.beginBackgroundTask {
|
||||
self.syncBackgroundUpdateTask = UIApplication.shared.beginBackgroundTask { [weak self] in
|
||||
completeProcessing()
|
||||
os_log("Accounts sync processing terminated for running too long.", log: self.log, type: .info)
|
||||
self?.logger.info("Accounts sync processing terminated for running too long.")
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
@@ -350,7 +347,7 @@ private extension AppDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
os_log("Application processing suspended.", log: self.log, type: .info)
|
||||
logger.info("Application processing suspended.")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -374,11 +371,11 @@ private extension AppDelegate {
|
||||
|
||||
// We send this to a dedicated serial queue because as of 11/05/19 on iOS 13.2 the call to the
|
||||
// task scheduler can hang indefinitely.
|
||||
bgTaskDispatchQueue.async {
|
||||
bgTaskDispatchQueue.async { [weak self] in
|
||||
do {
|
||||
try BGTaskScheduler.shared.submit(request)
|
||||
} catch {
|
||||
os_log(.error, log: self.log, "Could not schedule app refresh: %@", error.localizedDescription)
|
||||
self?.logger.error("Could not schedule app refresh: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,7 +387,7 @@ private extension AppDelegate {
|
||||
|
||||
scheduleBackgroundFeedRefresh() // schedule next refresh
|
||||
|
||||
os_log("Woken to perform account refresh.", log: self.log, type: .info)
|
||||
logger.info("Woken to perform account refresh.")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if AccountManager.shared.isSuspended {
|
||||
@@ -400,7 +397,7 @@ private extension AppDelegate {
|
||||
if !AccountManager.shared.isSuspended {
|
||||
try? WidgetDataEncoder.shared.encodeWidgetData()
|
||||
self.suspendApplication()
|
||||
os_log("Account refresh operation completed.", log: self.log, type: .info)
|
||||
self.logger.info("Account refresh operation completed.")
|
||||
task.setTaskCompleted(success: true)
|
||||
}
|
||||
}
|
||||
@@ -408,7 +405,7 @@ private extension AppDelegate {
|
||||
|
||||
// set expiration handler
|
||||
task.expirationHandler = { [weak task] in
|
||||
os_log("Accounts refresh processing terminated for running too long.", log: self.log, type: .info)
|
||||
self.logger.info("Accounts refresh processing terminated for running too long.")
|
||||
DispatchQueue.main.async {
|
||||
self.suspendApplication()
|
||||
task?.setTaskCompleted(success: false)
|
||||
@@ -431,12 +428,12 @@ private extension AppDelegate {
|
||||
resumeDatabaseProcessingIfNecessary()
|
||||
let account = AccountManager.shared.existingAccount(with: accountID)
|
||||
guard account != nil else {
|
||||
os_log(.debug, log: self.log, "No account found from notification.")
|
||||
logger.debug("No account found from notification.")
|
||||
return
|
||||
}
|
||||
let article = try? account!.fetchArticles(.articleIDs([articleID]))
|
||||
guard article != nil else {
|
||||
os_log(.debug, log: self.log, "No article found from search using %@", articleID)
|
||||
logger.debug("No account found from search using \(articleID, privacy: .public)")
|
||||
return
|
||||
}
|
||||
account!.markArticles(article!, statusKey: .read, flag: true) { _ in }
|
||||
@@ -459,12 +456,12 @@ private extension AppDelegate {
|
||||
resumeDatabaseProcessingIfNecessary()
|
||||
let account = AccountManager.shared.existingAccount(with: accountID)
|
||||
guard account != nil else {
|
||||
os_log(.debug, log: self.log, "No account found from notification.")
|
||||
logger.debug("No account found from notification.")
|
||||
return
|
||||
}
|
||||
let article = try? account!.fetchArticles(.articleIDs([articleID]))
|
||||
guard article != nil else {
|
||||
os_log(.debug, log: self.log, "No article found from search using %@", articleID)
|
||||
logger.debug("No article found from search using \(articleID, privacy: .public)")
|
||||
return
|
||||
}
|
||||
account!.markArticles(article!, statusKey: .starred, flag: true) { _ in }
|
||||
|
||||
@@ -8,24 +8,21 @@
|
||||
|
||||
import UIKit
|
||||
import RSCore
|
||||
import os.log
|
||||
|
||||
struct ErrorHandler {
|
||||
|
||||
private static var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application")
|
||||
struct ErrorHandler: Logging {
|
||||
|
||||
public static func present(_ viewController: UIViewController) -> (Error) -> () {
|
||||
return { [weak viewController] error in
|
||||
if UIApplication.shared.applicationState == .active {
|
||||
viewController?.presentError(error)
|
||||
} else {
|
||||
ErrorHandler.log(error)
|
||||
log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func log(_ error: Error) {
|
||||
os_log(.error, log: self.log, "%@", error.localizedDescription)
|
||||
ErrorHandler.logger.error("\(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ struct FeedNode: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
class SceneCoordinator: NSObject, UndoableCommandRunner, Logging {
|
||||
|
||||
var undoableCommands = [UndoableCommand]()
|
||||
var undoManager: UndoManager? {
|
||||
@@ -1272,6 +1272,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
try ArticleThemeImporter.importTheme(controller: rootSplitViewController, filename: filename)
|
||||
} catch {
|
||||
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error" : error])
|
||||
logger.error("Failed to import theme with error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,9 @@ import UIKit
|
||||
import UserNotifications
|
||||
import Account
|
||||
import Zip
|
||||
import RSCore
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate, Logging {
|
||||
|
||||
var window: UIWindow?
|
||||
var coordinator: SceneCoordinator!
|
||||
@@ -184,7 +185,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: .didBeginDownloadingTheme, object: nil)
|
||||
}
|
||||
let task = URLSession.shared.downloadTask(with: request) { location, response, error in
|
||||
let task = URLSession.shared.downloadTask(with: request) { [weak self] location, response, error in
|
||||
guard
|
||||
let location = location else { return }
|
||||
|
||||
@@ -192,6 +193,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
try ArticleThemeDownloader.shared.handleFile(at: location)
|
||||
} catch {
|
||||
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
||||
self?.logger.error("Failed to import theme with error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
task.resume()
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import RSCore
|
||||
|
||||
struct ArticleThemeImporter {
|
||||
struct ArticleThemeImporter: Logging {
|
||||
|
||||
static func importTheme(controller: UIViewController, filename: String) throws {
|
||||
let theme = try ArticleTheme(path: filename, isAppTheme: false)
|
||||
@@ -39,6 +40,7 @@ struct ArticleThemeImporter {
|
||||
confirmImportSuccess(controller: controller, themeName: theme.name)
|
||||
} catch {
|
||||
controller.presentError(error)
|
||||
ArticleThemeImporter.logger.error("Error importing theme: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
import Foundation
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
import RSCore
|
||||
import UIKit
|
||||
|
||||
class ArticleThemesTableViewController: UITableViewController {
|
||||
class ArticleThemesTableViewController: UITableViewController, Logging {
|
||||
|
||||
override func viewDidLoad() {
|
||||
let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:)));
|
||||
@@ -118,6 +118,7 @@ extension ArticleThemesTableViewController: UIDocumentPickerDelegate {
|
||||
try ArticleThemeImporter.importTheme(controller: self, filename: url.standardizedFileURL.path)
|
||||
} catch {
|
||||
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
||||
logger.error("Did fail to import theme: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ import SafariServices
|
||||
import SwiftUI
|
||||
import UniformTypeIdentifiers
|
||||
import UserNotifications
|
||||
import RSCore
|
||||
|
||||
class SettingsViewController: UITableViewController {
|
||||
class SettingsViewController: UITableViewController, Logging {
|
||||
|
||||
private weak var opmlAccount: Account?
|
||||
|
||||
@@ -509,6 +510,7 @@ private extension SettingsViewController {
|
||||
try opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
|
||||
} catch {
|
||||
self.presentError(title: "OPML Export Error", message: error.localizedDescription)
|
||||
logger.error("OPML Export Error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
let docPicker = UIDocumentPickerViewController(forExporting: [tempFile], asCopy: true)
|
||||
|
||||
Reference in New Issue
Block a user