Я разрабатываю расширение Today (виджет) для приложения iOS. Приложение использует SwiftUI, и я создаю виджет, используя UIHostingController
, как описано в этого руководства , упомянутого в этого SO ответа . Виджет может отображать состояние c SwiftUI без проблем, но когда я пытаюсь отобразить данные из Core Data (List
из Text
), я получаю ошибку:
2020-04-14 23:22:42.268955+0300 CountdownsWidget[6825:2146713] [error] error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'Countdown' so +entity is confused. Have you loaded your NSManagedObjectModel yet ?
CoreData: error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'Countdown' so +entity is confused. Have you loaded your NSManagedObjectModel yet ?
2020-04-14 23:22:42.269096+0300 CountdownsWidget[6825:2146713] [error] error: +[Countdown entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[Countdown entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
2020-04-14 23:22:42.269613+0300 CountdownsWidget[6825:2146713] [SwiftUI] Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x2819289a0>
(Эта ошибка возникает при тестировании на физическом устройстве.)
CountdownsWidget
- цель расширения на сегодня. Countdown
- это сущность в моем Countdowns.xcdatamodel
файле. Countdowns.xcdatamodel.xcdatamodel
, Countdown+CoreDataClass.swift
и Countdown+CoreDataProperties.swift
- во всех файлах проверен целевой объект CountdownsWidget
в File Inspector.
Мое намерение - отобразить динамические c данные из запроса на выборку в Core Data в этом SwiftUI представление:
ContentView.swift
:
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
var body: some View {
FilteredList(filter: false)
}
}
Из представления FilteredList.swift
, где отображается элемент List
:
import SwiftUI
struct FilteredList: View {
var fetchRequest: FetchRequest<Countdown>
var body: some View {
List(fetchRequest.wrappedValue, id: \.self) { countdown in
Text("\(countdown.title ?? "Countdown Title")")
}
}
init(filter: Bool) {
fetchRequest = filter
? FetchRequest<Countdown>(entity: Countdown.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Countdown.date, ascending: true)], predicate: NSPredicate(format: "favorite = %d", filter))
: FetchRequest<Countdown>(entity: Countdown.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Countdown.date, ascending: true)])
}
}
И TodayViewController.swift
, просто чтобы быть уверенным:
import UIKit
import NotificationCenter
import SwiftUI
class TodayViewController: UIViewController, NCWidgetProviding {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBSegueAction func addSwiftUIView(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: ContentView())
}
func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
completionHandler(NCUpdateResult.newData)
}
}
UPD: в SceneDelegate.swift
, под основным iOS приложением, у меня есть этот код:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = ContentView().environment(\.managedObjectContext, context) // ContentView() is a view for iOS target
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
}
Буду признателен за отзыв о том, как отобразить результат с FilteredList.swift
в виджете. Кроме того, исследование, которое я сделал, заставило меня думать, что я должен использовать возможность групп приложений для своего приложения? Пожалуйста, поправьте меня, если я ошибаюсь. Застрял в этой проблеме, на самом деле просто хочу запросить некоторые Text
в один List
и отобразить в виджете.