![](/img/trans.png)
[英]SwiftUI - How do I know when the back button of a navigation view has been clicked?
[英]How do I refresh my SwiftUI view when my core data store has been updated from a background extension?
我有一個帶有意圖擴展目標的 SwiftUI 應用程序。 我還有一個位於共享應用程序組的核心數據存儲。
Intents 擴展可以使用 Shortcuts 應用程序中的newBackgroundContext()
成功地將數據寫入存儲。 我的viewContext
應用程序可以從 viewContext 中的應用程序組讀取數據,但只有當我強制退出應用程序並重新打開它時。
我想我需要一種方法讓我的應用知道它已在不同的上下文中更新,但我不確定如何做到這一點?
我嘗試在應用程序委托中設置context.automaticallyMergesChangesFromParent = true
並在 SwiftUI 視圖中將context.refreshAllObjects()
添加到onAppear
,但這似乎沒有任何區別。
mergeChanges(fromContextDidSave:)看起來很有希望,但我不確定如何獲得通知。
我是 Core Data 的新手並且非常困惑,所以任何正確方向的指針都會很棒,謝謝!
這是我當前代碼的凈化版本:
應用代理
lazy var persistentContainer: NSCustomPersistentContainer = {
let container = NSCustomPersistentContainer(name: "exampleContainerName")
container.loadPersistentStores { description, error in
if let error = error {
print("error loading persistent core data store")
}
}
return container
}()
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
print("error saving core data context")
}
}
}
class NSCustomPersistentContainer: NSPersistentContainer {
override open class func defaultDirectoryURL() -> URL {
var storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "exampleAppGroupName")
storeURL = storeURL?.appendingPathComponent("exampleContainerName")
return storeURL!
}
}
場景代表
guard let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ExampleView.environment(\.managedObjectContext, context))
self.window = window
window.makeKeyAndVisible()
}
Swift 用戶界面視圖
import SwiftUI
import CoreData
struct ExampleView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: ExampleEntityName.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \ExampleEntityName.date, ascending: false),
]
) var items: FetchedResults<ExampleEntityName>
var body: some View {
VStack {
List(items, id: \.self) { item in
Text("\(item.name)")
}
}
}
}
意圖擴展
class NSCustomPersistentContainer: NSPersistentContainer {
override open class func defaultDirectoryURL() -> URL {
var storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "exampleContainerName")
storeURL = storeURL?.appendingPathComponent("exampleAppGroupName")
return storeURL!
}
}
let persistentContainer: NSCustomPersistentContainer = {
let container = NSCustomPersistentContainer(name: "exampleContainerName")
container.loadPersistentStores { description, error in
if let error = error {
print("error loading persistent core data store: \(error)")
}
}
return container
}()
let context = persistentContainer.newBackgroundContext()
let entity = NSEntityDescription.entity(forEntityName: "ExampleEntityName", in: context)
let newEntry = NSManagedObject(entity: entity!, insertInto: context)
newEntry.setValue(Date(), forKey: "date")
newEntry.setValue("Hello World", forKey: "name")
do {
try context.save()
} catch {
print("Failed saving")
}
不知道您是否找到了答案,但我在共享應用程序組中使用 UserDefaults 和意圖擴展時遇到了類似的問題。 最終對我有用的事情是在 SceneDelegate 的以下方法中添加調用以加載項目:
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
SiriResponseManager.shared.grabUD()
}
在我的示例中,我使用的是 singleton,其中包含從 UserDefaults 加載項目的方法。 這個 singleton class 是一個 ObservableObject。 在我加載的第一個視圖中(在我的情況下為 ContentView),我將 ObservedObject 變量分配給我的 singleton class 並檢索我的 singleton 中的 @State 變量以填充我的視圖中的字符串
希望這會有所幫助。
class Data: ObservableObject {
@Published var dataToUpdate: Int
}
struct UpdateView : View {
@EnvironmentObject data: Data
...body ... {
// use data.dataToUpdate here
}
}
只需像您在此示例中看到的那樣定義數據。 然后在您的數據庫更改時填充 dataToUpdate ......當然這只是一個簡單的例子,只有一個 Int 值......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.