@IBOutlets going nil when simulating Background App Refresh

Hello, I have an application which displays the APOD (Astronomy Photo Of The Day), using NASA's API (this includes displaying the actual picture, description, author and title). I am learning how to implement Background App Refresh using the BackgroundTasks framework and simulating it using Apple's code for simulating Background App Refresh

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]

My Background App Refresh Task, updates the UI from the main View Controller (including the outlets), by fetching this information from the APOD API by NASA. However, when I simulate the Background App Refresh Task, the app crashes with the following message:

2023-03-01 16:43:08.394054-0600 SpacePhoto[9069:858984] SpacePhoto/ViewController.swift:73: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

This message is pointed out in the following code line:

 descriptionLabelOutlet.text = photoInfo.description

From what I have read, when my Background App Refresh Task is executed, the @IBOutlets are deallocated from memory and the View Controller references for such outlets are not being read, thus leading to the application crash.

Here is the code from my View Controller:

import UIKit

@MainActor
class ViewController: UIViewController, UIImagePickerControllerDelegate {
    
    static var shared = ViewController()
    
    var spacePhotoInfoTask: Task<Void, Never>? = nil
    deinit { spacePhotoInfoTask?.cancel()}
    
    // Access network request
    let photoInfoController = PhotoInfoController()
    
   ...
    
    @IBOutlet var descriptionLabelOutlet: UILabel!

    ...


// Send network request and assign the resulting String to the descriptionLabelOutlet       
        func updateInterface() {
            spacePhotoInfoTask?.cancel()
            spacePhotoInfoTask = Task {
                do {
                    let photoInfo = try await photoInfoController.fetchPhotoInfo()
                    self.descriptionLabelOutlet.text = photoInfo.description
                
            } catch {
                print("Could not update extra Label with \(error)")
            }
        }
    }
    
   ...
}

Here is the code corresponding to the AppDelegate:

import UIKit
import BackgroundTasks

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        BGTaskScheduler.shared.register(forTaskWithIdentifier: "Space", using: nil) { task in
            self.handleAppRefresh(task: task as! BGAppRefreshTask)
        }
        
        return true
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        scheduleAppRefresh()
        print("Scheduled")
        
    }
    
    
    func scheduleAppRefresh() {
        
        let request = BGAppRefreshTaskRequest(identifier: "Space")
        
        request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
        
        do {
            try BGTaskScheduler.shared.submit(request)
            
        } catch {
            print("Could not schedule app refresh: \(error)")
        }
        
    }
    
    
    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        
        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1

// The performApplicationUpdates method, performs the UI update (method declaration included below)

            let operations = Operations.performApplicationUpdates()
            let lastOpertation = operations.last!
        
        
        task.expirationHandler = {
            queue.cancelAllOperations()
        }
        
        lastOpertation.completionBlock = {
            task.setTaskCompleted(success: !lastOpertation.isCancelled)
        }
        
        queue.addOperations(operations, waitUntilFinished: false)
        
        print("Handled App Refresh")
        
    }
    
}

And finally, here is the declaration for the performApplicationUpdates method, which calls the updateInterface() method from the main View Controller:

import Foundation
import UIKit



@available(iOS 16.0, *)
struct Operations {
    static func performApplicationUpdates() -> [Operation] {
        let refreshHomeViewController = RefreshViewControllerInterface()
        return [refreshHomeViewController]
        
    }
}


@available(iOS 16.0, *)
class RefreshViewControllerInterface: Operation {
    
    override func main() {
        DispatchQueue.main.async {
            ViewController.shared.updateInterface()
        }
    }
}

How can I fix this? Is there a way to update the UI and my @IBOutlets' information using Background App Refresh?

Thank you!

&#64;IBOutlets going nil when simulating Background App Refresh
 
 
Q