#json #swift #swiftui #codable #widgetkit
Вопрос:
Мое приложение запускает json для постоянных данных, и я пытаюсь использовать эти сохраненные данные в своем виджете.
В моем приложении я использую эту функцию для загрузки моих данных из файлового менеджера в объект и объект наблюдения, как это
class jsonData: ObservableObject {
@Published var bookData: [Book]
init() {
self.bookData = Bundle.load("list")
}
}
extension Bundle {
static func load<T: Decodable>(_ filename: String) -> T {
let readURL = Bundle.main.url(forResource: filename, withExtension: "json")!
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let jsonURL = documentDirectory
.appendingPathComponent(filename)
.appendingPathExtension("json")
if !FileManager.default.fileExists(atPath: jsonURL.path) {
try? FileManager.default.copyItem(at: readURL, to: jsonURL)
}
return try! JSONDecoder().decode(T.self, from: Data(contentsOf: jsonURL))
}
}
Который работает безупречно, но когда я добавил функцию загрузки к своему поставщику виджетов, как это:
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), book: testBook)
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), book: testBook)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let books = self.load("list") //error here
let entry = SimpleEntry(date: entryDate, book: testBook)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
func load<T: Decodable>(_ filename: String) -> T {
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let jsonURL = documentDirectory
.appendingPathComponent(filename)
.appendingPathExtension("json")
return try! JSONDecoder().decode(T.self, from: Data(contentsOf: jsonURL))
}
}
Я получаю ошибку Generic parameter 'T' could not be inferred
в строке let books = self.load("list")
в функции getTimeline.
То, что я пытаюсь сделать, это загрузить весь список книг в list.json и отобразить случайную книгу в виджете.
Комментарии:
1.
let books: [Book] = self.load("list")
? Или какого там типа это должно быть? Возможно, вам потребуется помочь компилятору, потому что, как таковой, он не может угадать, какой тип возвращаемого значения, так что жеT
здесь? Или, может быть,let books = load("hello") as [Book]
2. @Larme Возвращаемое значение будет представлять собой массив структурной книги, который соответствует Хэшируемому, кодируемому и идентифицируемому, но да, я вижу, что в моем исходном классе я помог компилятору в опубликованной переменной.
3. @Larme это то, что я сделал, спасибо!