Update Relationship #199

Closed
opened 2025-12-29 15:26:32 +01:00 by adam · 5 comments
Owner

Originally created by @KrishnaKaira on GitHub (Feb 8, 2018).

Getting error:
[CoreStore: Assertion Failure] DataStack+Querying.swift:105 fetchOne
↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread.

I have 2 tables with one-many relation, I am using importUniqueObjects method to import data in the second table. from inside of didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws function I am not able to update the relationship.

Kindly help.

What is the right way to update relationship from inside importUniqueObjects method? A code snippet would help.

Below is my code snippet:

insertion code:

CoreStore.perform( asynchronous: { (transaction) -> Void in _ = try! transaction.importUniqueObjects(Into<Content>(), sourceArray: data) }, completion: { (result) -> Void in switch result { case .success: print("DATA SAVED SUCCESSFULLY!") case .failure(let error): print(error) } }

updating relationship: (inside of didInsert(from source:, in transaction: ) method)

`if let siteID = self.siteId {
let filteredPred = "(siteId MATCHES '(siteID)')"

        CoreStore.perform (
            asynchronous: { (transaction) -> Void in
                
                DispatchQueue.main.async {
                    
                    if var siteManagedObject = CoreStore.fetchOne(From<Site>(), Where<Site>(NSPredicate(format: filteredPred))) {
                        
                        siteManagedObject = transaction.edit(siteManagedObject)!

// let contentObj = transaction.edit(self)!

                        siteManagedObject.addToSiteContent(self)

// contentObj.contentSite = siteManagedObject
self.contentSite = siteManagedObject
}
}
},
completion: { _ in } )`

Originally created by @KrishnaKaira on GitHub (Feb 8, 2018). Getting error: ❗ [CoreStore: Assertion Failure] DataStack+Querying.swift:105 fetchOne ↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread. I have 2 tables with one-many relation, I am using **importUniqueObjects** method to import data in the second table. from inside of `didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws` function I am not able to update the relationship. Kindly help. What is the right way to update relationship from inside importUniqueObjects method? A code snippet would help. Below is my code snippet: **insertion code:** ` CoreStore.perform( asynchronous: { (transaction) -> Void in _ = try! transaction.importUniqueObjects(Into<Content>(), sourceArray: data) }, completion: { (result) -> Void in switch result { case .success: print("DATA SAVED SUCCESSFULLY!") case .failure(let error): print(error) } }` **updating relationship:** (inside of `didInsert(from source:, in transaction: )` method) `if let siteID = self.siteId { let filteredPred = "(siteId MATCHES '\(siteID)')" CoreStore.perform ( asynchronous: { (transaction) -> Void in DispatchQueue.main.async { if var siteManagedObject = CoreStore.fetchOne(From<Site>(), Where<Site>(NSPredicate(format: filteredPred))) { siteManagedObject = transaction.edit(siteManagedObject)! // let contentObj = transaction.edit(self)! siteManagedObject.addToSiteContent(self) // contentObj.contentSite = siteManagedObject self.contentSite = siteManagedObject } } }, completion: { _ in } )`
adam added the question label 2025-12-29 15:26:32 +01:00
adam closed this issue 2025-12-29 15:26:32 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Feb 8, 2018):

Don't dispatch asynchronously from inside didInsert(from:in:). Use the transaction argument directly:

func didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws {
    guard if let siteID = self.siteId else {
        return
    }
    guard if let siteManagedObject = transaction.fetchOne(From<Site>(), Where<Site>("siteId", isEqualTo: siteID)) else {
        return
    }
    siteManagedObject.addToSiteContent(self)
    // Your relationships should have their inverse-relationships set, in which case you don't need to call
    // self.contentSite = siteManagedObject
}
@JohnEstropia commented on GitHub (Feb 8, 2018): Don't dispatch asynchronously from inside `didInsert(from:in:)`. Use the `transaction` argument directly: ```swift func didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws { guard if let siteID = self.siteId else { return } guard if let siteManagedObject = transaction.fetchOne(From<Site>(), Where<Site>("siteId", isEqualTo: siteID)) else { return } siteManagedObject.addToSiteContent(self) // Your relationships should have their inverse-relationships set, in which case you don't need to call // self.contentSite = siteManagedObject } ```
Author
Owner

@KrishnaKaira commented on GitHub (Feb 8, 2018):

Hi JohnEStropia,

Thanks for the quick reply, I wish I had asked here before wasting my whole day to find a workaround. Thanks a lot for your reply it worked pretty well.

@KrishnaKaira commented on GitHub (Feb 8, 2018): Hi JohnEStropia, Thanks for the quick reply, I wish I had asked here before wasting my whole day to find a workaround. Thanks a lot for your reply it worked pretty well.
Author
Owner

@KrishnaKaira commented on GitHub (Feb 8, 2018):

I am facing issue with fetch query as well.
I have more than 20,000 data in the database, and if I fetch data using fetchAll method it takes approximately 2.5 sec - 3 sec of time; but if I use query in a loop with fetchOne it hardly takes 0.3 sec in total.

fetchAll:
`var predicateArray = String
for item in rawData {

        predicateArray.append("(\(Content.uniqueIDKeyPath) MATCHES '\(item)')")
    }
    if predicateArray.count > 0 {
        
        let filteredPred = predicateArray.joined(separator: " OR ")
        let localData = (CoreStore.fetchAll(From<Content>(), Where<Content>(NSPredicate(format: filteredPred))) ?? [])
    }`

takes approx 3 sec (on an avg.)

fetchOne:
`for item in rawData {

        let filteredPred = "(\(Content.uniqueIDKeyPath) MATCHES '\(item)')"
        if let content = CoreStore.fetchOne(From<Content>(), Where<Content>(filteredPred)) {
            if isForFavorite {
                content.isFavorited = true
            }
            contentArray.append(content)
            
        }
    }`

takes approx 0.3 sec (on an avg.)

in rawData, there is finite number of id's depends on page size, which could be either 16 or 32.

Could you help me with this, please?

@KrishnaKaira commented on GitHub (Feb 8, 2018): I am facing issue with fetch query as well. I have more than 20,000 data in the database, and if I fetch data using fetchAll method it takes approximately 2.5 sec - 3 sec of time; but if I use query in a loop with fetchOne it hardly takes 0.3 sec in total. **fetchAll:** `var predicateArray = [String]() for item in rawData { predicateArray.append("(\(Content.uniqueIDKeyPath) MATCHES '\(item)')") } if predicateArray.count > 0 { let filteredPred = predicateArray.joined(separator: " OR ") let localData = (CoreStore.fetchAll(From<Content>(), Where<Content>(NSPredicate(format: filteredPred))) ?? []) }` _takes approx 3 sec (on an avg.)_ **fetchOne:** `for item in rawData { let filteredPred = "(\(Content.uniqueIDKeyPath) MATCHES '\(item)')" if let content = CoreStore.fetchOne(From<Content>(), Where<Content>(filteredPred)) { if isForFavorite { content.isFavorited = true } contentArray.append(content) } }` _takes approx 0.3 sec (on an avg.)_ _in **rawData**, there is finite number of id's depends on page size, which could be either 16 or 32._ Could you help me with this, please?
Author
Owner

@JohnEstropia commented on GitHub (Feb 9, 2018):

Just a hunch, but MATCHES issues a regular expression query. Try using Where<T>.init(_:isEqualTo:) , or a variant of it, instead.

@JohnEstropia commented on GitHub (Feb 9, 2018): Just a hunch, but `MATCHES` issues a regular expression query. Try using `Where<T>.init(_:isEqualTo:)` , or a variant of it, instead.
Author
Owner

@JohnEstropia commented on GitHub (Apr 14, 2018):

Closing this issue due for now. Let me know if the issues persist.

@JohnEstropia commented on GitHub (Apr 14, 2018): Closing this issue due for now. Let me know if the issues persist.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#199