'SwiftUI & WidgetKit: Why Intent Handler does not load saved data?
I'm building a Widget with dynamic configuration. I provide a dynamic list of options with an Intents Extension - inside Intent Handler (code below).
However only sampleData
shows up, but not the userScrums
when tapping on "Edit Widget".
Why it doesn't load userScrums
?
import Intents
class IntentHandler: INExtension {
override func handler(for intent: INIntent) -> Any {
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
return self
}
}
extension IntentHandler: ScrumSelectionIntentHandling {
func provideScrumOptionsCollection(for intent: ScrumSelectionIntent) async throws -> INObjectCollection<ScrumType> {
let sampleScrums = DailyScrum.sampleData.map { scrum in
ScrumType(identifier: scrum.title, display: scrum.title)
}
let userScrums = try? await ScrumStore.load().map { scrum in
ScrumType(identifier: scrum.title, display: scrum.title)
}
let allScrums = sampleScrums + (userScrums ?? [])
let collection = INObjectCollection(items: allScrums)
return collection
}
// func provideScrumOptionsCollection(for intent: ScrumSelectionIntent, with completion: @escaping (INObjectCollection<ScrumType>?, Error?) -> Void) {}
}
import Foundation
import SwiftUI
class ScrumStore: ObservableObject {
@Published var scrums: [DailyScrum] = []
private static func fileURL() throws -> URL {
try FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
.appendingPathComponent("scrums.data")
}
static func load() async throws -> [DailyScrum] {
try await withCheckedThrowingContinuation { continuation in
load { result in
switch result {
case .failure(let error):
continuation.resume(throwing: error)
case .success(let scrums):
continuation.resume(returning: scrums)
}
}
}
}
static func load(completion: @escaping (Result<[DailyScrum], Error>)->Void) {
DispatchQueue.global(qos: .background).async {
do {
let fileURL = try fileURL()
guard let file = try? FileHandle(forReadingFrom: fileURL) else {
DispatchQueue.main.async {
completion(.success([]))
}
return
}
let dailyScrums = try JSONDecoder().decode([DailyScrum].self, from: file.availableData)
DispatchQueue.main.async {
completion(.success(dailyScrums))
}
} catch {
DispatchQueue.main.async {
completion(.failure(error))
}
}
}
}
@discardableResult
static func save(scrums: [DailyScrum]) async throws -> Int {
try await withCheckedThrowingContinuation { continuation in
save(scrums: scrums) { result in
switch result {
case .failure(let error):
continuation.resume(throwing: error)
case .success(let scrumsSaved):
continuation.resume(returning: scrumsSaved)
}
}
}
}
static func save(scrums: [DailyScrum], completion: @escaping (Result<Int, Error>)->Void) {
DispatchQueue.global(qos: .background).async {
do {
let data = try JSONEncoder().encode(scrums)
let outfile = try fileURL()
try data.write(to: outfile)
DispatchQueue.main.async {
completion(.success(scrums.count))
}
} catch {
DispatchQueue.main.async {
completion(.failure(error))
}
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|