mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-28 13:58:23 +02:00
Use os logging framework, so logs can be retrieved later
This commit is contained in:
parent
9dd532285c
commit
d9313a1654
3 changed files with 97 additions and 15 deletions
|
@ -60,6 +60,7 @@
|
||||||
E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507428AEF93100C746DD /* PlayerSettings.swift */; };
|
E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507428AEF93100C746DD /* PlayerSettings.swift */; };
|
||||||
E9DFCBFB28C28F4A00B36356 /* AudioPlayerSleepTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DFCBFA28C28F4A00B36356 /* AudioPlayerSleepTimer.swift */; };
|
E9DFCBFB28C28F4A00B36356 /* AudioPlayerSleepTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9DFCBFA28C28F4A00B36356 /* AudioPlayerSleepTimer.swift */; };
|
||||||
E9E985F828B02D9400957F23 /* PlayerProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E985F728B02D9400957F23 /* PlayerProgress.swift */; };
|
E9E985F828B02D9400957F23 /* PlayerProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E985F728B02D9400957F23 /* PlayerProgress.swift */; };
|
||||||
|
E9FA07E328C82848005520B0 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FA07E228C82848005520B0 /* Logger.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
@ -120,6 +121,7 @@
|
||||||
E9D5507428AEF93100C746DD /* PlayerSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerSettings.swift; sourceTree = "<group>"; };
|
E9D5507428AEF93100C746DD /* PlayerSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerSettings.swift; sourceTree = "<group>"; };
|
||||||
E9DFCBFA28C28F4A00B36356 /* AudioPlayerSleepTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerSleepTimer.swift; sourceTree = "<group>"; };
|
E9DFCBFA28C28F4A00B36356 /* AudioPlayerSleepTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerSleepTimer.swift; sourceTree = "<group>"; };
|
||||||
E9E985F728B02D9400957F23 /* PlayerProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerProgress.swift; sourceTree = "<group>"; };
|
E9E985F728B02D9400957F23 /* PlayerProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerProgress.swift; sourceTree = "<group>"; };
|
||||||
|
E9FA07E228C82848005520B0 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
@ -199,6 +201,7 @@
|
||||||
3AFCB5E627EA23F700ECCC05 /* util */ = {
|
3AFCB5E627EA23F700ECCC05 /* util */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E9FA07E228C82848005520B0 /* Logger.swift */,
|
||||||
3AFCB5E727EA240D00ECCC05 /* NowPlayingInfo.swift */,
|
3AFCB5E727EA240D00ECCC05 /* NowPlayingInfo.swift */,
|
||||||
3AD4FCEA280443DD006DB301 /* Database.swift */,
|
3AD4FCEA280443DD006DB301 /* Database.swift */,
|
||||||
3AD4FCEC28044E6C006DB301 /* Store.swift */,
|
3AD4FCEC28044E6C006DB301 /* Store.swift */,
|
||||||
|
@ -412,6 +415,7 @@
|
||||||
E9D5506228AC1CC900C746DD /* PlayerState.swift in Sources */,
|
E9D5506228AC1CC900C746DD /* PlayerState.swift in Sources */,
|
||||||
3AD4FCE728043E72006DB301 /* AbsDatabase.m in Sources */,
|
3AD4FCE728043E72006DB301 /* AbsDatabase.m in Sources */,
|
||||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
||||||
|
E9FA07E328C82848005520B0 /* Logger.swift in Sources */,
|
||||||
3A90295F280968E700E1D427 /* PlaybackReport.swift in Sources */,
|
3A90295F280968E700E1D427 /* PlaybackReport.swift in Sources */,
|
||||||
E9D5505A28AC1C4500C746DD /* Folder.swift in Sources */,
|
E9D5505A28AC1C4500C746DD /* Folder.swift in Sources */,
|
||||||
3ABF580928059BAE005DFBE5 /* PlaybackSession.swift in Sources */,
|
3ABF580928059BAE005DFBE5 /* PlaybackSession.swift in Sources */,
|
||||||
|
|
|
@ -14,6 +14,8 @@ class PlayerProgress {
|
||||||
|
|
||||||
private static let TIME_BETWEEN_SESSION_SYNC_IN_SECONDS = 10.0
|
private static let TIME_BETWEEN_SESSION_SYNC_IN_SECONDS = 10.0
|
||||||
|
|
||||||
|
private let logger = AppLogger(category: "PlayerProgress")
|
||||||
|
|
||||||
private init() {}
|
private init() {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,8 +30,8 @@ class PlayerProgress {
|
||||||
try await updateServerSessionFromLocalSession(session, rateLimitSync: !isStopping)
|
try await updateServerSessionFromLocalSession(session, rateLimitSync: !isStopping)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
debugPrint("Failed to syncFromPlayer")
|
logger.error("Failed to syncFromPlayer")
|
||||||
debugPrint(error)
|
logger.error(error)
|
||||||
}
|
}
|
||||||
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
||||||
}
|
}
|
||||||
|
@ -39,8 +41,8 @@ class PlayerProgress {
|
||||||
do {
|
do {
|
||||||
try await updateAllServerSessionFromLocalSession()
|
try await updateAllServerSessionFromLocalSession()
|
||||||
} catch {
|
} catch {
|
||||||
debugPrint("Failed to syncToServer")
|
logger.error("Failed to syncToServer")
|
||||||
debugPrint(error)
|
logger.error(error)
|
||||||
}
|
}
|
||||||
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
||||||
}
|
}
|
||||||
|
@ -50,8 +52,8 @@ class PlayerProgress {
|
||||||
do {
|
do {
|
||||||
try await updateLocalSessionFromServerMediaProgress()
|
try await updateLocalSessionFromServerMediaProgress()
|
||||||
} catch {
|
} catch {
|
||||||
debugPrint("Failed to syncFromServer")
|
logger.error("Failed to syncFromServer")
|
||||||
debugPrint(error)
|
logger.error(error)
|
||||||
}
|
}
|
||||||
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
await UIApplication.shared.endBackgroundTask(backgroundToken)
|
||||||
}
|
}
|
||||||
|
@ -96,7 +98,7 @@ class PlayerProgress {
|
||||||
|
|
||||||
try localMediaProgress.updateFromPlaybackSession(session)
|
try localMediaProgress.updateFromPlaybackSession(session)
|
||||||
|
|
||||||
NSLog("Local progress saved to the database")
|
logger.debug("Local progress saved to the database")
|
||||||
|
|
||||||
// Send the local progress back to front-end
|
// Send the local progress back to front-end
|
||||||
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.localProgress.rawValue), object: nil)
|
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.localProgress.rawValue), object: nil)
|
||||||
|
@ -141,7 +143,7 @@ class PlayerProgress {
|
||||||
session = session.freeze()
|
session = session.freeze()
|
||||||
|
|
||||||
guard safeToSync else { return }
|
guard safeToSync else { return }
|
||||||
NSLog("Sending sessionId(\(session.id)) to server with currentTime(\(session.currentTime))")
|
logger.debug("Sending sessionId(\(session.id)) to server with currentTime(\(session.currentTime))")
|
||||||
|
|
||||||
var success = false
|
var success = false
|
||||||
if session.isLocal {
|
if session.isLocal {
|
||||||
|
@ -161,25 +163,25 @@ class PlayerProgress {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateLocalSessionFromServerMediaProgress() async throws {
|
private func updateLocalSessionFromServerMediaProgress() async throws {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: Checking if local media progress was updated on server")
|
logger.debug("updateLocalSessionFromServerMediaProgress: Checking if local media progress was updated on server")
|
||||||
guard let session = try await Realm().objects(PlaybackSession.self).last(where: {
|
guard let session = try await Realm().objects(PlaybackSession.self).last(where: {
|
||||||
$0.isActiveSession == true && $0.serverConnectionConfigId == Store.serverConfig?.id
|
$0.isActiveSession == true && $0.serverConnectionConfigId == Store.serverConfig?.id
|
||||||
})?.freeze() else {
|
})?.freeze() else {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: Failed to get session")
|
logger.debug("updateLocalSessionFromServerMediaProgress: Failed to get session")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the current progress
|
// Fetch the current progress
|
||||||
let progress = await ApiClient.getMediaProgress(libraryItemId: session.libraryItemId!, episodeId: session.episodeId)
|
let progress = await ApiClient.getMediaProgress(libraryItemId: session.libraryItemId!, episodeId: session.episodeId)
|
||||||
guard let progress = progress else {
|
guard let progress = progress else {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: No progress object")
|
logger.debug("updateLocalSessionFromServerMediaProgress: No progress object")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine which session is newer
|
// Determine which session is newer
|
||||||
let serverLastUpdate = progress.lastUpdate
|
let serverLastUpdate = progress.lastUpdate
|
||||||
guard let localLastUpdate = session.updatedAt else {
|
guard let localLastUpdate = session.updatedAt else {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: No local session updatedAt")
|
logger.debug("updateLocalSessionFromServerMediaProgress: No local session updatedAt")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let serverCurrentTime = progress.currentTime
|
let serverCurrentTime = progress.currentTime
|
||||||
|
@ -190,16 +192,16 @@ class PlayerProgress {
|
||||||
|
|
||||||
// Update the session, if needed
|
// Update the session, if needed
|
||||||
if serverIsNewerThanLocal && currentTimeIsDifferent {
|
if serverIsNewerThanLocal && currentTimeIsDifferent {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: Server has newer time than local serverLastUpdate=\(serverLastUpdate) localLastUpdate=\(localLastUpdate)")
|
logger.debug("updateLocalSessionFromServerMediaProgress: Server has newer time than local serverLastUpdate=\(serverLastUpdate) localLastUpdate=\(localLastUpdate)")
|
||||||
guard let session = session.thaw() else { return }
|
guard let session = session.thaw() else { return }
|
||||||
try session.update {
|
try session.update {
|
||||||
session.currentTime = serverCurrentTime
|
session.currentTime = serverCurrentTime
|
||||||
session.updatedAt = serverLastUpdate
|
session.updatedAt = serverLastUpdate
|
||||||
}
|
}
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: Updated session currentTime newCurrentTime=\(serverCurrentTime) previousCurrentTime=\(localCurrentTime)")
|
logger.debug("updateLocalSessionFromServerMediaProgress: Updated session currentTime newCurrentTime=\(serverCurrentTime) previousCurrentTime=\(localCurrentTime)")
|
||||||
PlayerHandler.seek(amount: session.currentTime)
|
PlayerHandler.seek(amount: session.currentTime)
|
||||||
} else {
|
} else {
|
||||||
NSLog("updateLocalSessionFromServerMediaProgress: Local session does not need updating; local has latest progress")
|
logger.debug("updateLocalSessionFromServerMediaProgress: Local session does not need updating; local has latest progress")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
76
ios/App/Shared/util/Logger.swift
Normal file
76
ios/App/Shared/util/Logger.swift
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// AppLogger.swift
|
||||||
|
// AppLogger
|
||||||
|
//
|
||||||
|
// Created by Fernando Fernandes on 29.06.20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import os
|
||||||
|
|
||||||
|
/// Logs app info by using the newest Swift unified logging APIs.
|
||||||
|
///
|
||||||
|
/// Reference:
|
||||||
|
/// - [Explore logging in Swift (WWDC20)](https://developer.apple.com/wwdc20/10168)
|
||||||
|
/// - [Unified Logging](https://developer.apple.com/documentation/os/logging)
|
||||||
|
/// - [OSLog](https://developer.apple.com/documentation/os/oslog)
|
||||||
|
/// - [Logger](https://developer.apple.com/documentation/os/logger)
|
||||||
|
public struct AppLogger {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
/// Default values used by the `AppLogger`.
|
||||||
|
public struct Defaults {
|
||||||
|
public static let subsystem = Bundle.main.bundleIdentifier ?? "ABS"
|
||||||
|
public static let category = "default"
|
||||||
|
public static let isPrivate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private Properties
|
||||||
|
|
||||||
|
private let logger: Logger
|
||||||
|
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
|
/// Creates an `AppLogger` instance.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - subsystem: `String`. Organizes large topic areas within the app or apps. For example, you might define
|
||||||
|
/// a subsystem for each process that you create. The default is `Bundle.main.bundleIdentifier ?? "AppLogger"`.
|
||||||
|
/// - category: `String`. Within a `subsystem`, you define categories to further distinguish parts of that
|
||||||
|
/// subsystem. For example, if you used a single subsystem for your app, you might create separate categories for
|
||||||
|
/// model code and user-interface code. In a game, you might use categories to distinguish between physics, AI,
|
||||||
|
/// world simulation, and rendering. The default is `default`.
|
||||||
|
public init(subsystem: String = Defaults.subsystem, category: String = Defaults.category) {
|
||||||
|
self.logger = Logger(subsystem: subsystem, category: category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Interface
|
||||||
|
|
||||||
|
public extension AppLogger {
|
||||||
|
|
||||||
|
func log(_ information: String, isPrivate: Bool = Defaults.isPrivate) {
|
||||||
|
if isPrivate {
|
||||||
|
logger.debug("\(information, privacy: .private)")
|
||||||
|
} else {
|
||||||
|
logger.debug("\(information, privacy: .public)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func debug(_ information: String, isPrivate: Bool = Defaults.isPrivate) {
|
||||||
|
this.log(information, isPrivate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func error(_ information: String, isPrivate: Bool = Defaults.isPrivate) {
|
||||||
|
if isPrivate {
|
||||||
|
logger.error("\(information, privacy: .private)")
|
||||||
|
} else {
|
||||||
|
logger.error("\(information, privacy: .public)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func error(_ error: Error) {
|
||||||
|
logger.error("\(String(describing: error))")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue