Hello everyone!
Need your help related to the following:
I import some IDs (in format int64) from webservice and save them local. While saving, the IDs are changed and I don't understand where is the trouble.
As per sample, I import a value 1266757 (the Id's are 7-digits numbers).
But from time to time (not always) while saving, this value is 1266756 or 1266758 and so on. As the last digit is different from the original.
import Soap
import AEXML
import CoreData
struct GetUserMessage: SchedulableOperation {
let ticket: String
let userId: Int64
let beginRowNr: Int
let endRowNr: Int
}
extension GetUserMessage {
typealias Result = ResultStatus
func uniqId() -> String {
return "\(type(of: self))_begin_row_\(beginRowNr)_end_row_\(endRowNr)"
}
func threshold() -> TimeInterval {
return 1
}
func willCreateSyncMark(using context: NSManagedObjectContext) {
if beginRowNr != 0 { return }
let predicate = NSPredicate(format: "domain = %@", "\(type(of: self)))")
let items: [SyncMark] = CoreDataStorage.shared.objects(
context, predicate: predicate
)
items.forEach { context.delete($0) }
}
func sync(response: ResultStatus, _ context: NSManagedObjectContext) {
let storage = CoreDataStorage.shared
if beginRowNr == 0 {
let messages: [Message] = storage.objects(context)
messages.forEach { $0.removed = true }
}
response.sync(context)
}
struct ResultStatus: ResponseModel & SoapStorable {
static func canDecode(element: DomNode) -> Bool {
return element.name == "ResultStatus"
}
var Message: [MessageElement]?
var TotalsNoRead: TotalsNoReadElement?
func sync(_ context: NSManagedObjectContext) {
if let messages = Message {
for item in messages {
item.sync(context)
}
}
if let totalsNoRead = TotalsNoRead {
totalsNoRead.sync(context)
}
}
}
struct TotalsNoReadElement: SoapStorable {
static func decodeKey() -> String {
return "TotalsNoRead"
}
var Total: Int32?
func sync(_ context: NSManagedObjectContext) {
let storage = CoreDataStorage.shared
guard let user: User = storage.object(context) else { return }
user.notificationsCount = Total ?? 0
}
}
struct MessageElement: SoapStorable {
static func decodeKey() -> String {
return "Message"
}
var Id: Int64
var TitleRo: String?
var TitleRu: String?
var TitleEn: String?
var Date: String?
var TextRo: String?
var TextRu: String?
var TextEn: String?
var Priority: String?
var IsRead: Bool?
func sync(_ context: NSManagedObjectContext) {
let storage = CoreDataStorage.shared
let predicate = NSPredicate(format: "id == %lld", Id)
let message: Message = storage.object(context, predicate: predicate) ?? {
let message = Message(context: context)
message.id = Id
message.unready = true
message.priority = Priority
return message
}()
Will much appreciate every feedback.
Thank you!
That sounds like some sort of race condition, both because of the non-determinism and because it's a small difference that you could easily get from the concurrent use of a counter. How are you coming up with your IDs, and how are you finding out that they're wrong?
Hi. Thank you for feedback.
IDs are generated on the webservice side, we are only imported them from webservice and while parsing them we find out that they are wrong, different from the original.
And you've checked that they're being serialized correctly, right? What format are you serializing to?