Home > database >  Clear Cache JSON API SwiftUI
Clear Cache JSON API SwiftUI

Time:05-08

When I update the JSON API, the data in the application is not updated immediately, is it possible to add a button to reset the cache or make the data automatically update after some time?

struct Course: Hashable, Codable {
    let name: String
}

class ViewModel: ObservableObject {
    @Published var courses: [Course] = []

    func fetch() {
        guard let url = URL(string: "JSON URL") else {return}
        let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
            guard let data = data, error == nil else {return}
            do {
                let courses = try JSONDecoder().decode([Course].self, from: data)
                DispatchQueue.main.async {
                    self?.courses = courses
                }
            }
            catch {
                print(error)
            }
        }
        task.resume()
    }
}

View

struct Data: View {
    
    @StateObject var viewModel = ViewModel()
    
    let columns: [GridItem] = [
        GridItem(.flexible(), spacing: nil, alignment: nil),
        GridItem(.flexible(), spacing: nil, alignment: nil)
    ]
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            LazyVGrid(columns: columns) {
                ForEach(viewModel.courses, id: \.self) { course in
                    VStack {
                        Text(course.name)
                            .foregroundColor(.white)
                    }
                    .frame(width: 90, height: 90)
                    .background(Color.gray)
                }
            }
        }
        .onAppear {
            viewModel.fetch()
        }
    }
}

how to reset the cache and update the data that I get from the JSON API, I will be grateful for any help

CodePudding user response:

Before I start with a proposed solution, let me just recommend to avoid using the name Data for your view: that's the name of a Swift type.

If you can deploy for iOS 15, SwiftUI has a .refreshable() modifier, that invokes a piece of code whenever the user pulls the view down. This can be used to fetch the data.

You can find proper information following this link.

Here's how you could use it (it works well for lists and navigation views, see how it works with the grid):

    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            LazyVGrid(columns: columns) {
                ForEach(viewModel.courses, id: \.self) { course in
                    VStack {
                        Text(course.name)
                            .foregroundColor(.white)
                    }
                    .frame(width: 90, height: 90)
                    .background(Color.gray)
                }
            }

            // Use this modifier to fetch data when the user pulls the view down
            .refreshable {
                viewModel.fetch()
            }
        }
        .onAppear {
            viewModel.fetch()
        }
    }

To call instead a timer, you need to add the following in the view model:

// Inside the view model

private var timer = Timer()

init() {

    // This example fetches data every 60 seconds
        timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in
            guard let strongSelf = self else { return }
            Task {
                await strongSelf.fetch()
            }
        }
}
  • Related