You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
i have an issue and i-m thinking that i doing something wrong with saving or creating/mapping CoreDataModels while getting data from a Webservice.
Situation:
I download from a Webservice all users cardboxes and serialize the Json into an DTO Object and then map the DTO to the CoreData DBOCardBoxModel
ForEach downloaded and mapped Cardbox download the Cards async
2.1) When the Api Call is finished, serialize the Json into a DTO Object
2.1.1) Then i want create a new CoreDataModel when the DTO.cardNbr not exists, else get first and map then the properties from the dto to dbo
2.1.2) In the Mapper.Map(dto->dbo) i want to map all the properties and set relations, so in example a card can have multiple choice answers, so i want to create them and add this relation to the card
Exception throw at the firstOrCreateWithAttributes methode when my call was for example 25 times called, when it called 5 times the exception didnt throw.
I think it is because the NSManagementObjectContext is not on each thread, how can i handle this?
Here is some of my Code:
I using the following extensions:
Another question from me is where i place my the Save funktion? I¥m not shure about this.
1.) The Api Call that will call 25 Times: (the self.saveDB will call the saveAndWait(default) funktion)
public func ActiveCardBoxesById(dboCardBoxes : Array<String>){
//let operationQueue = NSOperationQueue()
//operationQueue.maxConcurrentOperationCount = dboCardBoxes.count
for cardBox in dboCardBoxes {
if self.CanSendRequest() {
var request = self.CreateBaseRequest()
request.requestSerializer.headers["clientid"] = self.UniqueId
request.GET("/cardbox/\(cardBox)/cards", parameters: nil, success: {(response: HTTPResponse) -> Void in
if (response.responseObject != nil) {
//TODO
let dtoCards = Cards(JSONDecoder(response.responseObject!))
for dtoCard in dtoCards.cards! {
var dboCard = DBOCard.firstOrCreateWithAttribute("cardNbr", value: dtoCard.cardNbr!) as DBOCard
Mapper.Map(dtoCard, dbo: dboCard)
}
self.dataDelegate?.ConfirmLastSyncCardBox!()
self.logger.info("ConfirmLastSyncCardBox \(cardBox)")
}
}, failure: {(error: NSError, response: HTTPResponse?) -> Void in
self.logger.error("Getting ActiveCardboxesById throw error : \(error)")
self.baseDelegate?.ErrorInWebService(error)
})
}
else {
logger.warn("Can not communicate with API")
self.baseDelegate?.ErrorSendingRequest()
}
}
self.saveDB()
}
2.) This is the Mapper.Map methode: (the self.saveDB will call the saveAndWait(default) funktion)
class func Map(dto : DTOCard, dbo : DBOCard) -> DBOCard {
if let cardNbr = dto.cardNbr {
dbo.setValue(cardNbr, forKey: "cardNbr")
}
if let cardBoxNbr = dto.cardBoxNbr {
dbo.setValue(cardBoxNbr, forKey: "cardBoxNbr")
}
if let daystowait = dto.daystowait {
dbo.setValue(daystowait, forKey: "daystowait")
}
if let delay = dto.delay {
dbo.setValue(delay, forKey: "delay")
}
if let favorite = dto.favorite {
dbo.setValue(favorite, forKey: "favorite")
}
if let knownInPlannedRow = dto.knownInPlannedRow {
dbo.setValue(knownInPlannedRow, forKey: "knownInPlannedRow")
}
if let knownInRow = dto.knownInRow {
dbo.setValue(knownInRow, forKey: "knownInRow")
}
if let lastPlannedPlayed = dto.lastPlannedPlayed {
dbo.setValue(lastPlannedPlayed, forKey: "lastPlannedPlayed")
}
if let lastPlayed = dto.lastPlayed {
dbo.setValue(lastPlayed, forKey: "lastPlayed")
}
if let multipleChoice = dto.multipleChoice {
dbo.setValue(multipleChoice, forKey: "multipleChoice")
}
if let timesKnown = dto.timesKnown {
dbo.setValue(timesKnown, forKey: "timesKnown")
}
if let timesNotKnown = dto.timesNotKnown {
dbo.setValue(timesNotKnown, forKey: "timesNotKnown")
}
if let selectedForLearning = dto.selectedForLearning {
dbo.setValue(selectedForLearning, forKey: "selectedForLearning")
}
if let delete = dto.delete {
dbo.setValue(delete, forKey: "delete")
}
if let answer = dto.answer {
dbo.setValue(answer, forKey: "answer")
}
if let answerImage = dto.answerImage {
dbo.setValue(answerImage, forKey: "answerImage")
}
if let answerPureText = dto.answerPureText {
dbo.setValue(answerPureText, forKey: "answerPureText")
}
if let question = dto.question {
dbo.setValue(question, forKey: "question")
}
if let questionImage = dto.questionImage {
dbo.setValue(questionImage, forKey: "questionImage")
}
if let questionPureText = dto.questionPureText {
dbo.setValue(questionPureText, forKey: "questionPureText")
}
if let dtoMultipleChoices = dto.multipleChoiceCards {
var counter = 1
for dtoMultipleChoice in dtoMultipleChoices {
var acessableOrderIndex = counter
if let orderIndex = dtoMultipleChoice.orderIndex {
acessableOrderIndex = orderIndex
}
//TODO LOOK FIRST FOR CARDID AND ORDERINDEX
let predicate = NSPredicate(format: "cardId = \(dtoMultipleChoice.cardId! + counter) AND orderIndex = \(acessableOrderIndex)")
var mappedMultipleChoice : DBOMultipleChoice
if let existingDboMultipleChoice = DBOMultipleChoice.firstWithPredicate(predicate!) as? DBOMultipleChoice {
mappedMultipleChoice = self.Map(dtoMultipleChoice, dbo: existingDboMultipleChoice)
mappedMultipleChoice.setValue(acessableOrderIndex, forKey: "orderIndex")
}
else {
var dboMultipleChoice = DBOMultipleChoice.firstOrCreateWithAttribute("cardId", value: dtoMultipleChoice.cardId! + counter) as DBOMultipleChoice
mappedMultipleChoice = self.Map(dtoMultipleChoice, dbo: dboMultipleChoice)
mappedMultipleChoice.setValue(acessableOrderIndex, forKey: "orderIndex")
}
dbo.addMultipleChoice(mappedMultipleChoice)
}
counter = 1
}
if let dtoCategories = dto.categories {
for dtoCategory in dtoCategories {
var dboCategory = DBOCategory.firstOrCreateWithAttribute("categoryId", value: dtoCategory.categoryId!) as DBOCategory
var mappedCategory = self.Map(dtoCategory, dbo: dboCategory)
mappedCategory.addCard(dbo)
//add category to card
dbo.addCategorie(mappedCategory)
//add card to category
}
}
// //get cardbox and add card
if let dboCardBox = DBOCardBox.firstWithAttribute("cardBoxNbr", value: "\(dbo.cardBoxNbr)") as? DBOCardBox {
//we have an cardbox
dboCardBox.addCard(dbo)
dbo.cardInCardBox = dboCardBox
}
self.save()
return dbo
}
Exceptions sometimes dangling with reference Dangling reference to an invalid object.=null, NSValidationErrorValue
Or
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFSet: 0x7fc1aa487870> was mutated while being enumerated.'
XCode Version: 6.1
The text was updated successfully, but these errors were encountered:
Ok i solved it and UNDERSTAND what i´m doing wrong. When you downloading ASYNC Data from Webserver and want to store it in CoreData you have to create a temporary MOC (Management Object Context) and work in the Thread with this MOC and when your data is finished loading, you can save your MOC with your BaseStoreCoordinator and thats it, changes will merge in MainThread and everything is fine 👍 Here is my fixed code snippet:
//This is really important for working with background queues and core data
let moc = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
moc.persistentStoreCoordinator = DBContext.persistentStoreCoordinator
let dtoCards = Cards(JSONDecoder(response.responseObject!))
for dtoCard in dtoCards.cards! {
var dboCard = DBOCard.firstOrCreateWithAttribute("cardNbr", value: dtoCard.cardNbr!,context:moc) as DBOCard
var mappedDboCard = Mapper.Map(dtoCard, dbo: dboCard,context: moc)
}
DBContext.saveContextAndWait(context: moc)
hey Marko,
i have an issue and i-m thinking that i doing something wrong with saving or creating/mapping CoreDataModels while getting data from a Webservice.
Situation:
2.1) When the Api Call is finished, serialize the Json into a DTO Object
2.1.1) Then i want create a new CoreDataModel when the DTO.cardNbr not exists, else get first and map then the properties from the dto to dbo
2.1.2) In the Mapper.Map(dto->dbo) i want to map all the properties and set relations, so in example a card can have multiple choice answers, so i want to create them and add this relation to the card
Exception throw at the firstOrCreateWithAttributes methode when my call was for example 25 times called, when it called 5 times the exception didnt throw.
I think it is because the NSManagementObjectContext is not on each thread, how can i handle this?
Here is some of my Code:
I using the following extensions:
Another question from me is where i place my the Save funktion? I¥m not shure about this.
1.) The Api Call that will call 25 Times: (the self.saveDB will call the saveAndWait(default) funktion)
2.) This is the Mapper.Map methode: (the self.saveDB will call the saveAndWait(default) funktion)
Exceptions sometimes dangling with reference Dangling reference to an invalid object.=null, NSValidationErrorValue
Or
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFSet: 0x7fc1aa487870> was mutated while being enumerated.'
XCode Version: 6.1
The text was updated successfully, but these errors were encountered: