If the issue is that the UI is blocked during transactions, why not just perform the writes onto a child private queue context as you've mentioned - then merge it against the main context. The fetch results controller should against the source of truth which is the main context.
Post
Replies
Boosts
Views
Activity
So one thing to keep in mind, NSManagedObjectContexts are fairly cheap to create. However, you will have the overhead of having to keep track of your child contexts - and especially implement guards to disallow cross context access of NSManagedObjects. So right off the bat, you should not be using any privateQueueConcurrencyType/Background Context for any user-facing interface. Mostly, operations performed on a background context aren't finalized until they're merged against the main persistent store. Basically you'll run into anomalous behavior if not crashes operating on objects that haven't persisted.My recommendation is to keep using that background context for large transactions, but use either the main viewContext or a child context w/ mainQueueConcurrencyType as a read-only fetch view into the persistent store. Then with the background context, you can perform create/update transactions without blocking the UI.Here's some snippets on how I've set up my background contexts. Side-note: you kinda have to use privateQueueConcurrencyType anyways if you want to support CloudKit+CoreData as I've discovered through testing.Creating background context, do your usual context.perform & save func newChildCreateContext(type: NSManagedObjectContextConcurrencyType = .privateQueueConcurrencyType, mergesChangesFromParent: Bool = true) -> NSManagedObjectContext {
let context = NSManagedObjectContext(concurrencyType: type)
context.parent = self
context.name = "privateCreateContext"
context.transactionAuthor = appTransactionAuthorName
context.automaticallyMergesChangesFromParent = mergesChangesFromParent
return context
}Observe the NSManagedObjectContextDidSave notification from NotificationCenter. Merge the changed objects and the main context should resolve everything. updateChangeObserver = NotificationObserver(name: .NSManagedObjectContextDidSave, object: updateContext)
updateChangeObserver.onReceived = mergeUpdateObjects
private func mergeUpdateObjects(notification: Notification) {
DispatchQueue.main.async { [unowned self] in
self.contextDidSave(self.updateContext, note: notification)
}
}
func contextDidSave(_ context: NSManagedObjectContext, note: Notification) {
guard context === createContext || context === updateContext else { return }
context.perform {
context.mergeChanges(fromContextDidSave: note)
}
}Signal to your FetchedResultsController refresh its fetchedObjects after the merge via some other NotificationCenter observer or something. Refresh Fetched Objects on your main context controller via a NotificationCenter call or something after the merge. Changes should be reflected in the UI non-blocking.func refreshFetchedObjects() {
fetchedResult.fetchedObjects?.forEach({ $0.objectWillChange.send() })
fetchedResult.managedObjectContext.refreshAllObjects()
}Also another note, if you're adding a constant amount of objects - are you doing it through the new NSBatchInsertRequest operation? If you aren't already, I've found the new operation to be incredibly performant. You just have to make sure you merge the changes against the main context. public func executeAndMergeChanges(using batchInsertRequest: NSBatchInsertRequest) throws {
batchInsertRequest.resultType = .objectIDs
let result = try execute(batchInsertRequest) as? NSBatchInsertResult
let changes: [AnyHashable: Any] = [NSInsertedObjectsKey: result?.result as? [NSManagedObjectID] ?? []]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
}
You all are overcomplicating things. Apple for the most part abides by the Oauth standard. Without messing around with things too much, the default response_type for Authentication Request is {code, id_token, state, user}. You can parse user for the PII you want.
You set response_mode to form_post so expect a POST request containing Authorization Response parameters. After that you can validate and exchange the code. Store user information and the server can execute a redirect to the user. Like I said, Apple’s implementation is nearly the same as everyones’s. The only difference is they go out-of-spec and include a user struct.
If you’re having to try and make modifications to fetchRequests, then you should probably be using fetchedresultscontroller. It’s kind of the purpose of it and handles your use-case.
So you have a few problems. The other post noted some stuff. But to answer your direct question, you have no data because the NSPersistentContainer is held and being instantiated in a StateObject. You should instantiate it in a more global sense, such as in AppDelegate or give it its own class so you instantiate it only once. I’ll point out other things, when you’re creating a new account, you probably want to be saving the context in the same scope and not have that in a separate function (saveAccountData).
As the other poster mentioned. You need to figure out a better structure for setting up the PersistentContainer first. Then you can figure out if you want to use @FetchedRequest in the views and/or implement NSFretchedController on some view model.
I just encountered and implemented this today actually. Your arrayGardenChildren shouldn’t return an optional per the compiler error. So that should be easy to fix. So I setup a SectionedFetchRequest<Folder, Note>. My example is similar but trickier. So I think if you wanted to do it on the children where its the same object type.
Also your SectionedFetchRequest, you can try looking at it from a different perspective. You’re going down the right path of handling the optional parent. But instead of filtering via the sectionIdentifier, maybe you should just add a predicate.
@SectionedFetchRequest private var notes: SectionedFetchResults<Folder, Note>
ForEach(notes) { folder in
DisclosureGroup(content: {
ForEach(section) { note in
NavigationLink(destination: NoteView(note: note),
label: { NoteRow(note: note)})}},
label: { FolderRow(folder: folder.id)
})
Modern sites will give you the information you need in the meta tags. So as an example, Apple grabs site meta image tiles, description and has a webkit screenshot of a website when you paste a link in iMessage. There’s really no reason you need to something beyond SwiftSoup to parse out the meta tags for you. Really, you can just grab the site meta description for that page and use some favicon or other img meta that the site owner has probable already done.
I’m trying to keep things simple for you since this is an entire field. Unless you’re looking to summarize large amounts of text then you’re going down the road of needing ML.
Put both views in a Pager view? Then add some condition for displaying the second view after validating the form contents in the first view.
There’s many ways you can approach this. At a surface level I thought plucky was doing DNS & HTTP filtering by acting as a proxy. But on closer look, it looks to be implemented as a browser plugin. For subdomain/domain filtering, you can look at implementing content blocking in a safari extension: https://developer.apple.com/documentation/safariservices/creating_a_content_blocker
To implement the HTML content blocking stuff, you’d probably want to look into DOM rewriting within the safari extension. At least it all seems pretty straight forward to implement.