Originally created by @wm-j-ray on GitHub (May 27, 2016).
John,
Just getting started with CoreStore, so...
If I 'needed' to use another complementary framework that needs a NSFetchedResultsController and a context for reading//writing, what is the safest way to create/access them without breaking a CoreStore dataStack set up like so:
struct DataStoreService {
static let coreDataStack: DataStack = {
let dataStack = DataStack(modelName: "AppName")
do {
try dataStack.addSQLiteStoreAndWait(
fileName: "AppName.sqlite",
configuration:nil,
resetStoreOnModelMismatch: true
)
} catch {
print("Failed creating dataStack with error: \(error as NSError)")
}
return dataStack
}()
}
And the stack is used from an interactor like structure using something like this:
I 'think' what I'm looking for is just a way to access the correct context to used for the NSFetchedResultsController (yours ideally, so I can use CoreStore fetching and queries) and the best way to deal with CoreStore transactions. If I can't access your NSFetchedController I would create one. Monitors and Observers, with my level of knowledge about CoreStore, seem a little beyond me.
And what are the pitfalls and downside to doing something like this?
Basically, I would really like to somehow wire CoreStore and DTTableViewManager together.
I want to make sure I'm aware of all of the potential issues and pick the best approach before I go any further.
Thanx in Advance
Originally created by @wm-j-ray on GitHub (May 27, 2016).
John,
Just getting started with CoreStore, so...
If I 'needed' to use another complementary framework that needs a NSFetchedResultsController and a context for reading//writing, what is the safest way to create/access them without breaking a CoreStore dataStack set up like so:
```
struct DataStoreService {
static let coreDataStack: DataStack = {
let dataStack = DataStack(modelName: "AppName")
do {
try dataStack.addSQLiteStoreAndWait(
fileName: "AppName.sqlite",
configuration:nil,
resetStoreOnModelMismatch: true
)
} catch {
print("Failed creating dataStack with error: \(error as NSError)")
}
return dataStack
}()
}
```
And the stack is used from an interactor like structure using something like this:
```
func fetchAllWidgets() -> [WidgetsMO]
{
return DataStoreService.coreDataStack.fetchAll(From(WidgetsMO))!
}
```
I 'think' what I'm looking for is just a way to access the correct context to used for the NSFetchedResultsController (yours ideally, so I can use CoreStore fetching and queries) and the best way to deal with CoreStore transactions. If I can't access your NSFetchedController I would create one. Monitors and Observers, with my level of knowledge about CoreStore, seem a little beyond me.
And what are the pitfalls and downside to doing something like this?
The library is https://github.com/DenHeadless/DTTableViewManager by the way (which lightens up tableViews by using a manager (https://github.com/DenHeadless/DTModelStorage) to bind the model against tableViewCells), and I envision using it primarily for reads and using the CoreStore functionality for hopefully all of the writes.
Basically, I would really like to somehow wire CoreStore and DTTableViewManager together.
I want to make sure I'm aware of all of the potential issues and pick the best approach before I go any further.
Thanx in Advance
adam
added the question label 2025-12-29 18:22:06 +01:00
The only NSManagedObjectContext exposed by CoreStore is the context held by UnsafeDataTransactions.
lettransaction=CoreStore.beginUnsafe()// store this somewhere so it doesn't get deallocatedletcontext=transaction.internalContext// this is what you need and you're free to do dirty things to it :)
@JohnEstropia commented on GitHub (May 27, 2016):
The only NSManagedObjectContext exposed by CoreStore is the context held by `UnsafeDataTransaction`s.
``` swift
let transaction = CoreStore.beginUnsafe() // store this somewhere so it doesn't get deallocated
let context = transaction.internalContext // this is what you need and you're free to do dirty things to it :)
```
See the documentation on `UnsafeDataTransaction.internalContext`: https://github.com/JohnEstropia/CoreStore/blob/master/CoreStore/Saving%20and%20Processing/UnsafeDataTransaction.swift#L153
Also, note that this means the objects you are working on are not from the main context. Don't mix objects fetched from the DataStack to the objects fetched from the transaction
// BAD!!letsomeObject=CoreStore.fetchOne(From(...))lettransaction=CoreStore.beginUnsafe()// store this somewhere so it doesn't get deallocatedletcontext=transaction.internalContextletanotherObject=// fetch from transaction/contextanotherObject.someRelationship=someObject// BAD!
@JohnEstropia commented on GitHub (May 27, 2016):
Also, note that this means the objects you are working on are not from the main context. Don't mix objects fetched from the `DataStack` to the objects fetched from the transaction
``` swift
// BAD!!
let someObject = CoreStore.fetchOne(From(...))
let transaction = CoreStore.beginUnsafe() // store this somewhere so it doesn't get deallocated
let context = transaction.internalContext
let anotherObject = // fetch from transaction/context
anotherObject.someRelationship = someObject // BAD!
```
@JohnEstropia commented on GitHub (May 27, 2016):
If all you need is an `NSFetchedResultsController` instance, CoreStore can also create one for you. See
[NSFetchedResultsController+Convenience.swift](https://github.com/JohnEstropia/CoreStore/blob/master/CoreStore/Convenience%20Helpers/NSFetchedResultsController%2BConvenience.swift#L37)
Thanks for the help. Let me make sure I understand...
So I can call NSFetchedResultsController.createForStack I would be using the correct context. I could use that NSFetchedResultsController to drive the tableView. Can you give me an example of what that call would look like using my dataStack? (lame, I know, but thanks in advance)
And, if I update I wouldn't be able to use the default CoreStore methods even though I'm in the proper context but rather I would have to do a save() manually or an UnsafeDataTransaction commit.
@wm-j-ray commented on GitHub (May 27, 2016):
Thanks for the help. Let me make sure I understand...
So I can call NSFetchedResultsController.createForStack I would be using the correct context. I could use that NSFetchedResultsController to drive the tableView. Can you give me an example of what that call would look like using my dataStack? (lame, I know, but thanks in advance)
And, if I update I wouldn't be able to use the default CoreStore methods even though I'm in the proper context but rather I would have to do a save() manually or an UnsafeDataTransaction commit.
If I understand how DTTableViewManager works, it's only for displaying data, correct? If so then the NSFetchedResultsController created with CoreStore should notify DTTableViewManager without any issues, and you can still make updates using any of CoreStore's transactions (not just UnsafeDataTransactions).
@JohnEstropia commented on GitHub (May 27, 2016):
Let me push an update so the API call is simpler. Once it's up you should be able to call with
``` swift
let controller = NSFetchedResultsController.createForStack(
CoreStore.defaultStack,
From(MyEntity),
SectionBy("sectionKey"), // optional
Where("value > %@", minValue), // optional
OrderBy(.Ascending("value")) // optional
)
```
If I understand how DTTableViewManager works, it's only for displaying data, correct? If so then the NSFetchedResultsController created with CoreStore should notify DTTableViewManager without any issues, and you can still make updates using any of CoreStore's transactions (not just UnsafeDataTransactions).
Check out version 1.6.8. Renamed createForStack() to createFor() and now accepts either DataStack or UnsafeDataTransaction
@JohnEstropia commented on GitHub (May 27, 2016):
Check out version 1.6.8. Renamed `createForStack()` to `createFor()` and now accepts either `DataStack` or `UnsafeDataTransaction`
How do the optional parameters work? Why can't I do this?
let controller = NSFetchedResultsController.createForStack(
CoreStore.defaultStack,
From(NoteMO))
I get a missing fetchClauses in call error.
I've also tried this:
let fetchreq = NSFetchRequest(entityName: "NoteMO")
let controller = NSFetchedResultsController.createForStack(CoreStore.defaultStack, fetchRequest: fetchreq, fetchClauses: nil)
I'm not sure what I'm doing incorrectly.
@wm-j-ray commented on GitHub (May 27, 2016):
John,
I pulled down 1.6.8 and I must be an idiot because I can't get the stub you provided to work:
```
let controller = NSFetchedResultsController.createForStack(
CoreStore.defaultStack,
From(MyEntity),
SectionBy("sectionKey"), // optional
Where("value > %@", minValue), // optional
OrderBy(.Ascending("value")) // optional
```
)
How do the optional parameters work? Why can't I do this?
```
let controller = NSFetchedResultsController.createForStack(
CoreStore.defaultStack,
From(NoteMO))
```
I get a missing fetchClauses in call error.
I've also tried this:
```
let fetchreq = NSFetchRequest(entityName: "NoteMO")
let controller = NSFetchedResultsController.createForStack(CoreStore.defaultStack, fetchRequest: fetchreq, fetchClauses: nil)
```
I'm not sure what I'm doing incorrectly.
Sorry for the confusion, I renamed createForStack() to createFor(). The current createForStack() is deprecated and requires argument labels. Here's the correct syntax
letcontroller=NSFetchedResultsController.createFor(CoreStore.defaultStack,From(MyEntity),SectionBy("sectionKey"),// optionalWhere("value > %@",minValue),// optionalOrderBy(.Ascending("value"))// sorting is required)
@JohnEstropia commented on GitHub (May 28, 2016):
Sorry for the confusion, I renamed `createForStack()` to `createFor()`. The current `createForStack()` is deprecated and requires argument labels. Here's the correct syntax
``` swift
let controller = NSFetchedResultsController.createFor(
CoreStore.defaultStack,
From(MyEntity),
SectionBy("sectionKey"), // optional
Where("value > %@", minValue), // optional
OrderBy(.Ascending("value")) // sorting is required
)
```
will compile, but will raise an assertion because NSFetchedResultsControllers requires sorting information. Provide an OrderBy clause.
I'll update the documentation.
@JohnEstropia commented on GitHub (May 28, 2016):
By the way,
``` swift
let controller = NSFetchedResultsController.createFor(
CoreStore.defaultStack,
From(NoteMO))
```
will compile, but will raise an assertion because NSFetchedResultsControllers requires sorting information. Provide an `OrderBy` clause.
I'll update the documentation.
@wm-j-ray commented on GitHub (May 28, 2016):
Got it and many thanks.
I'll give it a shot.
On May 27, 2016, 7:28 PM -0400, John Estropianotifications@github.com, wrote:
> By the way,
>
> letcontroller=NSFetchedResultsController.createFor( CoreStore.defaultStack, From(NoteMO))
>
> will compile, but will raise an assertion because NSFetchedResultsControllers requires sorting information. Provide anOrderByclause.
>
> I'll update the documentation.
>
> —
> You are receiving this because you modified the open/close state.
> Reply to this email directly,view it on GitHub(https://github.com/JohnEstropia/CoreStore/issues/76#issuecomment-222274075), ormute the thread(https://github.com/notifications/unsubscribe/AAvDJJWyhYrXSoRQecQnCGsunqG_q_qTks5qF34DgaJpZM4IocDM).
func test() {
let controller = NSFetchedResultsController.createFor(
CoreStore.defaultStack,
From(NoteMO), OrderBy(.Ascending("content")))
do {
try controller.performFetch()
} catch {
print("Failed performing fetch with error: \(error as NSError)")
}
controller.fetchedObjects
// breakpoint here
}
And I see the controller, but there is nothing in it...
@wm-j-ray commented on GitHub (May 28, 2016):
OK, now I'm perplexed (and probably don't know what I'm doing)
1. Set up the stack like so:
```
func startService() {
CoreStore.defaultStack = DataStack(
modelName: "WriteTrack"
//migrationChain: ["MyStore", "MyStoreV2", "MyStoreV3"]
)
do {
try CoreStore.addSQLiteStoreAndWait(
fileName: "WriteTrack.sqlite",
configuration:nil,
resetStoreOnModelMismatch: true
)
} catch {
print("Failed creating CoreStore with error: \(error as NSError)")
}
}
```
2. Fetch all records normal CoreStore way, like so:
```
func fetchAllNotes() -> [NoteMO]
{
return CoreStore.fetchAll(From(NoteMO))!
}
```
Returns all of the records.
1. Try with a NSFetchedController like so:
```
func test() {
let controller = NSFetchedResultsController.createFor(
CoreStore.defaultStack,
From(NoteMO), OrderBy(.Ascending("content")))
do {
try controller.performFetch()
} catch {
print("Failed performing fetch with error: \(error as NSError)")
}
controller.fetchedObjects
// breakpoint here
```
}
And I see the controller, but there is nothing in it...

Did you set the NSFetchedResultsControllerDelegate? NSFetchedResultsControllers are lazy, and will not do actual fetching until you access it's array or unless you have a delegate that implements controllerDidChangeContent(_:)
@JohnEstropia commented on GitHub (May 28, 2016):
Did you set the NSFetchedResultsControllerDelegate? NSFetchedResultsControllers are lazy, and will not do actual fetching until you access it's array or unless you have a delegate that implements `controllerDidChangeContent(_:)`
@JohnEstropia commented on GitHub (May 28, 2016):
Try to print the content after performFetch()
```
try controller.performFetch()
print(controller.fetchedObjects)
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @wm-j-ray on GitHub (May 27, 2016).
John,
Just getting started with CoreStore, so...
If I 'needed' to use another complementary framework that needs a NSFetchedResultsController and a context for reading//writing, what is the safest way to create/access them without breaking a CoreStore dataStack set up like so:
And the stack is used from an interactor like structure using something like this:
I 'think' what I'm looking for is just a way to access the correct context to used for the NSFetchedResultsController (yours ideally, so I can use CoreStore fetching and queries) and the best way to deal with CoreStore transactions. If I can't access your NSFetchedController I would create one. Monitors and Observers, with my level of knowledge about CoreStore, seem a little beyond me.
And what are the pitfalls and downside to doing something like this?
The library is https://github.com/DenHeadless/DTTableViewManager by the way (which lightens up tableViews by using a manager (https://github.com/DenHeadless/DTModelStorage) to bind the model against tableViewCells), and I envision using it primarily for reads and using the CoreStore functionality for hopefully all of the writes.
Basically, I would really like to somehow wire CoreStore and DTTableViewManager together.
I want to make sure I'm aware of all of the potential issues and pick the best approach before I go any further.
Thanx in Advance
@JohnEstropia commented on GitHub (May 27, 2016):
The only NSManagedObjectContext exposed by CoreStore is the context held by
UnsafeDataTransactions.See the documentation on
UnsafeDataTransaction.internalContext: https://github.com/JohnEstropia/CoreStore/blob/master/CoreStore/Saving%20and%20Processing/UnsafeDataTransaction.swift#L153@JohnEstropia commented on GitHub (May 27, 2016):
Also, note that this means the objects you are working on are not from the main context. Don't mix objects fetched from the
DataStackto the objects fetched from the transaction@JohnEstropia commented on GitHub (May 27, 2016):
If all you need is an
NSFetchedResultsControllerinstance, CoreStore can also create one for you. SeeNSFetchedResultsController+Convenience.swift
@wm-j-ray commented on GitHub (May 27, 2016):
Thanks for the help. Let me make sure I understand...
So I can call NSFetchedResultsController.createForStack I would be using the correct context. I could use that NSFetchedResultsController to drive the tableView. Can you give me an example of what that call would look like using my dataStack? (lame, I know, but thanks in advance)
And, if I update I wouldn't be able to use the default CoreStore methods even though I'm in the proper context but rather I would have to do a save() manually or an UnsafeDataTransaction commit.
@JohnEstropia commented on GitHub (May 27, 2016):
Let me push an update so the API call is simpler. Once it's up you should be able to call with
If I understand how DTTableViewManager works, it's only for displaying data, correct? If so then the NSFetchedResultsController created with CoreStore should notify DTTableViewManager without any issues, and you can still make updates using any of CoreStore's transactions (not just UnsafeDataTransactions).
@JohnEstropia commented on GitHub (May 27, 2016):
Check out version 1.6.8. Renamed
createForStack()tocreateFor()and now accepts eitherDataStackorUnsafeDataTransaction@wm-j-ray commented on GitHub (May 27, 2016):
Excellent. Thanks so much.
On to the next.
@wm-j-ray commented on GitHub (May 27, 2016):
John,
I pulled down 1.6.8 and I must be an idiot because I can't get the stub you provided to work:
)
How do the optional parameters work? Why can't I do this?
I get a missing fetchClauses in call error.
I've also tried this:
I'm not sure what I'm doing incorrectly.
@JohnEstropia commented on GitHub (May 28, 2016):
Sorry for the confusion, I renamed
createForStack()tocreateFor(). The currentcreateForStack()is deprecated and requires argument labels. Here's the correct syntax@JohnEstropia commented on GitHub (May 28, 2016):
By the way,
will compile, but will raise an assertion because NSFetchedResultsControllers requires sorting information. Provide an
OrderByclause.I'll update the documentation.
@wm-j-ray commented on GitHub (May 28, 2016):
Got it and many thanks.
I'll give it a shot.
On May 27, 2016, 7:28 PM -0400, John Estropianotifications@github.com, wrote:
@wm-j-ray commented on GitHub (May 28, 2016):
OK, now I'm perplexed (and probably don't know what I'm doing)
Returns all of the records.
}
And I see the controller, but there is nothing in it...
@JohnEstropia commented on GitHub (May 28, 2016):
Did you set the NSFetchedResultsControllerDelegate? NSFetchedResultsControllers are lazy, and will not do actual fetching until you access it's array or unless you have a delegate that implements
controllerDidChangeContent(_:)@JohnEstropia commented on GitHub (May 28, 2016):
Try to print the content after performFetch()
@wm-j-ray commented on GitHub (May 28, 2016):
That was it. Thanks again and I can't tell you how much I appreciate your patience.
@JohnEstropia commented on GitHub (May 28, 2016):
No problem! Feel free to ask anything else anytime :)