简体   繁体   中英

How to use `.backgroundTask` modifier while still targeting iOS 15?

I'm trying to use the new .backgroundTask modifier announced at WWDC '22 but I can't get the below to compile? Xcode says Cannot infer contextual base in reference to member 'appRefresh' 🤔 How can I do this?

import SwiftUI
import Foundation
import BackgroundTasks

  var body: some Scene {
      WindowGroup {
          if #available(iOS 16, *) {
              AppRootView()
                  .backgroundTask(.appRefresh("refreshAllData")) {
                      refreshData() 
                  }
          } else {
              AppRootView()
          }
      }
  }

Edit: as agentBilly said .backgroundTask is a scene modifier, so should look like this but I'm still unsure how to check for iOS 16 availability?

import SwiftUI
import Foundation
import BackgroundTasks


@main
struct myApp: App {
    
    @Environment(\.scenePhase) var scenePhase
   
    var body: some Scene {
        WindowGroup {
            AppRootView()
        }
        .backgroundTask(.appRefresh("refreshAllData")) {
            refreshAllData() 
        }
}

We cannot use condition right in scene body, because SceneBuilder does not support conditional expression, so a solution is to have completely different apps loaded depending on availability.

Simplified code to have less lines:

struct AppScene: Scene {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

@available(iOS 16, *)
struct RefreshingAppScene: Scene {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .backgroundTask(.appRefresh("refreshAllData")) {
            refreshAllData()
        }
    }
}

@main
struct AppLoader {
    static func main() {
        if #available(iOS 16, *) {  // << conditional availability !!
            New_iOSApp.main()
        } else {
            Old_iOSApp.main()
        }
    }
}

@available (iOS 16, *)
struct New_iOSApp: App {
    var body: some Scene {
        RefreshingAppScene()
    }
}

struct Old_iOSApp: App {
    var body: some Scene {
        AppScene()
    }
}

Tested with Xcode 14b3 / iOS 16

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM