I debugged the app relaunch due to background URLSession download completion. This adds the logging required, which also matches the logging we have in the JobManager.
Adds logging
Fixes some minor bugs
Delete's app delegate (notifications only posted in background now)
Tips for debugging background session relaunch
Read tips here:
https://developer.apple.com/forums/thread/14855
Replace the start and observe functions with these, which causes the app to exit when a download starts.
```swift
/// Starts a job that will be managed by this instance.
/// - Parameter job: The job to start.
func start(job: any JobProtocol) {
Logger.offlineManager.debug("Starting Job from offline manager")
jobManager.jobs.append(job)
observeJob(job)
Task {
try? await Task.sleep(nanoseconds: 1_000_000_000)
job.start()
}
}
/// Observes a job for completion.
private func observeJob(_ job: any JobProtocol) {
Task { @MainActor in
for await message in job.messages {
guard message.text.contains("Started download") else { continue }
try? await Task.sleep(nanoseconds: 1_000_000_000)
Logger.offlineManager.debug("Simulating app termination")
JobManager.shared.saveState()
Logger.offlineManager.debug("Exiting...")
exit(1)
}
}
Task {
Logger.offlineManager.debug("Observing job completion")
// Wait for job to finish.
_ = try? await job.output
// Remove completed job from JobManager.
Logger.offlineManager.debug("Removing completed job from job manager")
jobManager.jobs.removeAll { $0 === job }
// Call job completion action.
jobCompletionAction?(job)
}
}
```
For getting device logs:
https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code
```
sudo log collect --device-name "Ryans iPhone" --last 10m --output "~/Desktop"
```
Also make sure to add the appropriate environment argument so that the logger is active:
```swift
extension Logger {
/// A logger for the offline manager.
static var offlineManager: Logger {
if ProcessInfo.processInfo.environment.keys.contains("LOGGING_FOR_OFFLINE_MANAGER") {
Logger(subsystem: "com.esri.ArcGISToolkit", category: "OfflineManager")
} else {
.init(.disabled)
}
}
}
```
And if you expect logging when the device wasn't started by Xcode, then you will want to comment the appropriate lines out so that the logger is always active:
```swift
extension Logger {
/// A logger for the offline manager.
static var offlineManager: Logger {
// if ProcessInfo.processInfo.environment.keys.contains("LOGGING_FOR_OFFLINE_MANAGER") {
Logger(subsystem: "com.esri.ArcGISToolkit", category: "OfflineManager")
// } else {
// .init(.disabled)
// }
}
}
```
I debugged the app relaunch due to background URLSession download completion. This adds the logging required, which also matches the logging we have in the JobManager.
Tips for debugging background session relaunch
Read tips here: https://developer.apple.com/forums/thread/14855 Replace the start and observe functions with these, which causes the app to exit when a download starts. ```swift /// Starts a job that will be managed by this instance. /// - Parameter job: The job to start. func start(job: any JobProtocol) { Logger.offlineManager.debug("Starting Job from offline manager") jobManager.jobs.append(job) observeJob(job) Task { try? await Task.sleep(nanoseconds: 1_000_000_000) job.start() } } /// Observes a job for completion. private func observeJob(_ job: any JobProtocol) { Task { @MainActor in for await message in job.messages { guard message.text.contains("Started download") else { continue } try? await Task.sleep(nanoseconds: 1_000_000_000) Logger.offlineManager.debug("Simulating app termination") JobManager.shared.saveState() Logger.offlineManager.debug("Exiting...") exit(1) } } Task { Logger.offlineManager.debug("Observing job completion") // Wait for job to finish. _ = try? await job.output // Remove completed job from JobManager. Logger.offlineManager.debug("Removing completed job from job manager") jobManager.jobs.removeAll { $0 === job } // Call job completion action. jobCompletionAction?(job) } } ``` For getting device logs: https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code ``` sudo log collect --device-name "Ryans iPhone" --last 10m --output "~/Desktop" ``` Also make sure to add the appropriate environment argument so that the logger is active: ```swift extension Logger { /// A logger for the offline manager. static var offlineManager: Logger { if ProcessInfo.processInfo.environment.keys.contains("LOGGING_FOR_OFFLINE_MANAGER") { Logger(subsystem: "com.esri.ArcGISToolkit", category: "OfflineManager") } else { .init(.disabled) } } } ``` And if you expect logging when the device wasn't started by Xcode, then you will want to comment the appropriate lines out so that the logger is always active: ```swift extension Logger { /// A logger for the offline manager. static var offlineManager: Logger { // if ProcessInfo.processInfo.environment.keys.contains("LOGGING_FOR_OFFLINE_MANAGER") { Logger(subsystem: "com.esri.ArcGISToolkit", category: "OfflineManager") // } else { // .init(.disabled) // } } } ```