Saturday, November 7, 2026
HomeiOS Developmentios - SwiftUI Background Duties

ios – SwiftUI Background Duties

[ad_1]

I am having problem attempting to determine the right way to use Background Duties appropriately in my SwiftUI challenge for iOS 15. For the reason that new SwiftUI lifecycle does not include an AppDelegate, I used my knowledge mannequin as an alternative for including background duties and set an surroundings object in App.

Every thing appears to work, background duties are being run however the subject I am having is my Printed variable solely appears to replace after I open the applying. I am undecided if that is even the proper method to fetch knowledge from an API within the background.

Here is a demo video since a gif would have been to giant to add. The difficulty appears to be the Pokémon does not appear to alter however solely when the applying has been launched after seeing there’s been a background process run. The tip purpose is to have my View replace with out having to open the applying earlier than I see any adjustments. I am nonetheless studying as I am going, any assist can be a lot appreciated.

Knowledge Mannequin

struct Pokemon: Codable {
    let sprites: Sprites
    let identify: String
    
    enum CodingKeys: String, CodingKey {
        case sprites
        case identify
    }
}

struct Sprites: Codable {
    let frontDefault: String
    enum CodingKeys: String, CodingKey {
        case frontDefault = "front_default"
    }
}

class DataModel: ObservableObject {
    let taskIdentifier = "com.instance.take a look at.refresh"
    non-public var cancellables = Set<AnyCancellable>()
    
    @Printed var pokemon = Pokemon(sprites: Sprites(frontDefault: "", frontShiny: ""), identify: "", varieties: [])

    func getpokemon() {
        let request = URLRequest(url: URL(string: "https://pokeapi.co/api/v2/pokemon/(Int.random(in: 1..<450))")!)
        URLSession.shared.dataTaskPublisher(for: request)
            .map{ $0.knowledge }
            .decode(kind: Pokemon.self, decoder: JSONDecoder())
            .obtain(on: DispatchQueue.principal)
            .sink(receiveCompletion: { print ("Obtained completion: ($0).") },
                  receiveValue: { pokemon in
                self.pokemon = pokemon
            })
            .retailer(in: &cancellables)
    }
    
    func register() {
        BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, utilizing: nil) { process in
            self.handleAppRefresh(process: process as! BGAppRefreshTask)
        }
    }
    
    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: taskIdentifier)
        request.earliestBeginDate = Date(timeIntervalSinceNow: 10 * 60)
        do {
            strive BGTaskScheduler.shared.submit(request)
        } catch {
            print("Couldn't schedule app refresh: (error)")
        }
    }
    
    
    func handleAppRefresh(process: BGAppRefreshTask) {
        scheduleAppRefresh()
        process.expirationHandler = {
            print("expired")
            //process.setTaskCompleted(success: false)
        }
        self.getpokemon()
        process.setTaskCompleted(success: true)
    }
}

App

import SwiftUI
import BackgroundTasks

@principal
struct BackgroudTaskApp: App {
    @ObservedObject var knowledge = DataModel()
    
    init() {
        knowledge.register()
        knowledge.scheduleAppRefresh()
    }
    
    var physique: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(knowledge)
                .onAppear(carry out: knowledge.getpokemon)
        }
    }
}

SwiftUI View

struct ContentView: View {
    @EnvironmentObject var knowledge: DataModel
    var physique: some View {
        Button(motion: {
            withAnimation {
                knowledge.getpokemon()
            }
        }, label: {
            VStack(spacing: 0) {
                AsyncImage(url:URL(string:knowledge.pokemon.sprites.frontDefault)) { picture in
                    picture
                        .resizable()
                } placeholder: {
                    ProgressView()
                }
                .body(width: 120, top: 120)
            }}
        ).buttonStyle(.plain)
    }
}

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments