Fixed that caching Core Data entities in Dictionaries didn't really work. Setting now Core Data Ids on BankingUi model classes and retrieving Core Data entities by that ID
This commit is contained in:
parent
b6561debb0
commit
b4e712f6b8
|
@ -1,6 +1,7 @@
|
|||
package net.dankito.banking.ui.model.tan
|
||||
|
||||
import net.dankito.banking.ui.model.Displayable
|
||||
import net.dankito.utils.multiplatform.UUID
|
||||
|
||||
|
||||
open class TanProcedure(
|
||||
|
@ -18,6 +19,9 @@ open class TanProcedure(
|
|||
val isNumericTan: Boolean = allowedTanFormat == AllowedTanFormat.Numeric
|
||||
|
||||
|
||||
open var technicalId: String = UUID.random()
|
||||
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is TanProcedure) return false
|
||||
|
|
|
@ -26,11 +26,30 @@ class CoreDataBankingPersistence: IBankingPersistence, IRemitteeSearcher {
|
|||
context.insert(mapped)
|
||||
|
||||
try context.save()
|
||||
|
||||
setIds(customer, mapped)
|
||||
} catch {
|
||||
NSLog("Could not save Customer \(customer): \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func setIds(_ customer: Customer, _ mappedCustomer: PersistedCustomer) {
|
||||
customer.technicalId = mappedCustomer.objectIDAsString
|
||||
|
||||
for account in customer.accounts {
|
||||
if let mappedAccount = mappedCustomer.accounts?.first { ($0 as! PersistedBankAccount).identifier == account.identifier} as? PersistedBankAccount {
|
||||
account.technicalId = mappedAccount.objectIDAsString
|
||||
}
|
||||
}
|
||||
|
||||
for tanProcedure in customer.supportedTanProcedures {
|
||||
if let mappedTanProcedure = mappedCustomer.supportedTanProcedures?.first { ($0 as! PersistedTanProcedure).bankInternalProcedureCode == tanProcedure.bankInternalProcedureCode } as? PersistedTanProcedure {
|
||||
tanProcedure.technicalId = mappedTanProcedure.objectIDAsString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func readPersistedAccounts_() -> [Customer] {
|
||||
var customers: [PersistedCustomer] = []
|
||||
|
||||
|
|
|
@ -4,16 +4,6 @@ import BankingUiSwift
|
|||
|
||||
|
||||
class Mapper {
|
||||
|
||||
/* Cache mapped object to not save them twice */
|
||||
private var mappedBanks = [Customer:PersistedCustomer]()
|
||||
|
||||
private var mappedAccounts = [BankAccount:PersistedBankAccount]()
|
||||
|
||||
private var mappedTransactions = [AccountTransaction:PersistedAccountTransaction]()
|
||||
|
||||
private var mappedTanProcedures = [TanProcedure:PersistedTanProcedure]()
|
||||
|
||||
|
||||
func map(_ customer: PersistedCustomer) -> Customer {
|
||||
let mapped = Customer(bankCode: map(customer.bankCode), customerId: map(customer.customerId), password: map(customer.password), finTsServerAddress: map(customer.finTsServerAddress), bankName: map(customer.bankName), bic: map(customer.bic), customerName: map(customer.customerName), userId: map(customer.userId), iconUrl: customer.iconUrl, accounts: [])
|
||||
|
@ -28,13 +18,11 @@ class Mapper {
|
|||
|
||||
mapped.technicalId = customer.objectIDAsString
|
||||
|
||||
mappedBanks[mapped] = customer
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
func map(_ customer: Customer, _ context: NSManagedObjectContext) -> PersistedCustomer {
|
||||
let mapped = mappedBanks[customer] ?? PersistedCustomer(context: context)
|
||||
let mapped = context.objectByID(customer.technicalId) ?? PersistedCustomer(context: context)
|
||||
|
||||
mapped.bankCode = customer.bankCode
|
||||
mapped.customerId = customer.customerId
|
||||
|
@ -51,8 +39,6 @@ class Mapper {
|
|||
|
||||
mapped.accounts = NSOrderedSet(array: map(mapped, customer.accounts, context))
|
||||
|
||||
mappedBanks[customer] = mapped
|
||||
|
||||
mapped.supportedTanProcedures = NSOrderedSet(array: map(customer.supportedTanProcedures, context))
|
||||
mapped.selectedTanProcedureCode = customer.selectedTanProcedure?.bankInternalProcedureCode
|
||||
|
||||
|
@ -76,8 +62,6 @@ class Mapper {
|
|||
|
||||
mapped.technicalId = account.objectIDAsString
|
||||
|
||||
mappedAccounts[mapped] = account
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
|
@ -86,7 +70,7 @@ class Mapper {
|
|||
}
|
||||
|
||||
func map(_ customer: PersistedCustomer, _ account: BankAccount, _ context: NSManagedObjectContext) -> PersistedBankAccount {
|
||||
let mapped = mappedAccounts[account] ?? PersistedBankAccount(context: context)
|
||||
let mapped = context.objectByID(account.technicalId) ?? PersistedBankAccount(context: context)
|
||||
|
||||
mapped.customer = customer
|
||||
mapped.identifier = account.identifier
|
||||
|
@ -112,8 +96,6 @@ class Mapper {
|
|||
|
||||
mapped.transactions = NSSet(array: map(mapped, account.bookedTransactions, context))
|
||||
|
||||
mappedAccounts[account] = mapped
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
|
@ -157,7 +139,7 @@ class Mapper {
|
|||
func map(_ account: BankAccount, _ transaction: PersistedAccountTransaction) -> AccountTransaction {
|
||||
let mapped = AccountTransaction(bankAccount: account, amount: map(transaction.amount), currency: map(transaction.currency), unparsedUsage: map(transaction.unparsedUsage), bookingDate: map(transaction.bookingDate), otherPartyName: transaction.otherPartyName, otherPartyBankCode: transaction.otherPartyBankCode, otherPartyAccountId: transaction.otherPartyAccountId, bookingText: transaction.bookingText, valueDate: map(transaction.valueDate), statementNumber: Int32(transaction.statementNumber), sequenceNumber: map(transaction.sequenceNumber), openingBalance: map(transaction.openingBalance), closingBalance: map(transaction.closingBalance), endToEndReference: transaction.endToEndReference, customerReference: transaction.customerReference, mandateReference: transaction.mandateReference, creditorIdentifier: transaction.creditorIdentifier, originatorsIdentificationCode: transaction.originatorsIdentificationCode, compensationAmount: transaction.compensationAmount, originalAmount: transaction.originalAmount, sepaUsage: transaction.sepaUsage, deviantOriginator: transaction.deviantOriginator, deviantRecipient: transaction.deviantRecipient, usageWithNoSpecialType: transaction.usageWithNoSpecialType, primaNotaNumber: transaction.primaNotaNumber, textKeySupplement: transaction.textKeySupplement, currencyType: transaction.currencyType, bookingKey: map(transaction.bookingKey), referenceForTheAccountOwner: map(transaction.referenceForTheAccountOwner), referenceOfTheAccountServicingInstitution: transaction.referenceOfTheAccountServicingInstitution, supplementaryDetails: transaction.supplementaryDetails, transactionReferenceNumber: map(transaction.transactionReferenceNumber), relatedReferenceNumber: transaction.relatedReferenceNumber)
|
||||
|
||||
mappedTransactions[mapped] = transaction
|
||||
mapped.technicalId = transaction.objectIDAsString
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
@ -168,7 +150,7 @@ class Mapper {
|
|||
}
|
||||
|
||||
func map(_ account: PersistedBankAccount, _ transaction: AccountTransaction, _ context: NSManagedObjectContext) -> PersistedAccountTransaction {
|
||||
let mapped = mappedTransactions[transaction] ?? PersistedAccountTransaction(context: context)
|
||||
let mapped = context.objectByID(transaction.technicalId) ?? PersistedAccountTransaction(context: context)
|
||||
|
||||
mapped.account = account
|
||||
|
||||
|
@ -210,8 +192,6 @@ class Mapper {
|
|||
mapped.transactionReferenceNumber = transaction.transactionReferenceNumber
|
||||
mapped.relatedReferenceNumber = transaction.relatedReferenceNumber
|
||||
|
||||
mappedTransactions[transaction] = mapped
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
|
@ -229,7 +209,7 @@ class Mapper {
|
|||
allowedTanFormat: tanProcedure.allowedTanFormat == "numeric" ? .numeric : .alphanumeric
|
||||
)
|
||||
|
||||
mappedTanProcedures[mapped] = tanProcedure
|
||||
mapped.technicalId = tanProcedure.objectIDAsString
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
@ -239,7 +219,7 @@ class Mapper {
|
|||
}
|
||||
|
||||
func map(_ tanProcedure: TanProcedure, _ context: NSManagedObjectContext) -> PersistedTanProcedure {
|
||||
let mapped = mappedTanProcedures[tanProcedure] ?? PersistedTanProcedure(context: context)
|
||||
let mapped = context.objectByID(tanProcedure.technicalId) ?? PersistedTanProcedure(context: context)
|
||||
|
||||
mapped.displayName = tanProcedure.displayName
|
||||
mapped.type = tanProcedure.type.name
|
||||
|
@ -248,8 +228,6 @@ class Mapper {
|
|||
mapped.maxTanInputLength = map(tanProcedure.maxTanInputLength) ?? -1
|
||||
mapped.allowedTanFormat = tanProcedure.allowedTanFormat.name
|
||||
|
||||
mappedTanProcedures[tanProcedure] = mapped
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
|
||||
extension String {
|
||||
|
@ -39,6 +40,11 @@ extension String {
|
|||
return String(self[startIndex...endIndex])
|
||||
}
|
||||
|
||||
|
||||
var isCoreDataId: Bool {
|
||||
return self.starts(with: "x-coredata://")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Optional where Wrapped == String {
|
||||
|
@ -171,3 +177,31 @@ extension URL {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension NSManagedObject {
|
||||
|
||||
var objectIDAsString: String {
|
||||
return self.objectID.uriRepresentation().absoluteString
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NSManagedObjectContext {
|
||||
|
||||
func objectByID<T : NSManagedObject>(_ objectID: String) -> T? {
|
||||
if objectID.isCoreDataId {
|
||||
if let url = URL(string: objectID) {
|
||||
if let managedObjectId = self.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url) {
|
||||
let object = try? self.existingObject(with: managedObjectId) as? T
|
||||
if object?.isFault == false {
|
||||
return object
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue