From 102a5c4eb7ae65797edeb65f7bc2ecc00dd46d33 Mon Sep 17 00:00:00 2001 From: Wira Irawan Date: Wed, 29 Apr 2026 10:55:21 +0700 Subject: [PATCH] Deduplicate card history entries --- Emoney Info.xcodeproj/project.pbxproj | 8 ++++---- .../Classes/api/MandiriEmoneyApi.swift | 19 +++++++++++++++---- Emoney Info/HomeView.swift | 18 +++++++++++++++++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/Emoney Info.xcodeproj/project.pbxproj b/Emoney Info.xcodeproj/project.pbxproj index ba1e297..dcacfd7 100644 --- a/Emoney Info.xcodeproj/project.pbxproj +++ b/Emoney Info.xcodeproj/project.pbxproj @@ -623,7 +623,7 @@ CODE_SIGN_ENTITLEMENTS = "Emoney Info/Emoney Info.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_TEAM = 6S5573WXX4; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -643,7 +643,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.2; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.iiyh.emoneyinfo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -666,7 +666,7 @@ CODE_SIGN_ENTITLEMENTS = "Emoney Info/Emoney Info.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_TEAM = 6S5573WXX4; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -686,7 +686,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.2; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.iiyh.emoneyinfo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Emoney Info/Classes/api/MandiriEmoneyApi.swift b/Emoney Info/Classes/api/MandiriEmoneyApi.swift index 6bc9045..e078298 100755 --- a/Emoney Info/Classes/api/MandiriEmoneyApi.swift +++ b/Emoney Info/Classes/api/MandiriEmoneyApi.swift @@ -39,6 +39,7 @@ public class MandiriEmoneyApi : UnifiedNfcApi { debugLog(response.getData().hexEncodedString()) let balance = response.getData().hexEncodedString().subString(from: 0, to: 8) self.emoney.setBalance(self.getRealBalance(reverseHexa: balance)) + self.resetHistoryState() // self.updateScreen() if (self.cardType! == 131){ self.getLogStep01(index: self.start) @@ -64,7 +65,7 @@ public class MandiriEmoneyApi : UnifiedNfcApi { } else { self.parseNewLog() self.start = 0 - self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending }) + self.finalizeHistory() self.emoney.setRiwayatList(self.riwayatList) self.emoney.setTampilRiwayat(true) self.updateScreen() @@ -74,7 +75,7 @@ public class MandiriEmoneyApi : UnifiedNfcApi { } else { self.parseNewLog() self.start = 0 - self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending }) + self.finalizeHistory() self.emoney.setRiwayatList(self.riwayatList) self.emoney.setTampilRiwayat(true) self.updateScreen() @@ -125,7 +126,7 @@ public class MandiriEmoneyApi : UnifiedNfcApi { } else { self.parseOldLog() self.start = 0 - self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending }) + self.finalizeHistory() self.emoney.setRiwayatList(self.riwayatList) self.emoney.setTampilRiwayat(true) self.updateScreen() @@ -135,7 +136,7 @@ public class MandiriEmoneyApi : UnifiedNfcApi { } else { self.parseOldLog() self.start = 0 - self.riwayatList = self.riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending }) + self.finalizeHistory() self.emoney.setRiwayatList(self.riwayatList) self.emoney.setTampilRiwayat(true) self.updateScreen() @@ -198,6 +199,16 @@ public class MandiriEmoneyApi : UnifiedNfcApi { self.apduRunner.callback?.complete(emoney: self.emoney) } } + + private func resetHistoryState() { + riwayatList.removeAll() + mapv1 = "" + start = 0 + } + + private func finalizeHistory() { + riwayatList = riwayatList.sorted(by: { $0.getTransationTime()?.compare($1.getTransationTime()!) == .orderedDescending }) + } func riwayatCard(_ bArr: [UInt8]) -> RiwayatCard? { var str: String diff --git a/Emoney Info/HomeView.swift b/Emoney Info/HomeView.swift index 446ba2d..3c680aa 100644 --- a/Emoney Info/HomeView.swift +++ b/Emoney Info/HomeView.swift @@ -668,7 +668,7 @@ extension HomeViewController: ApduCallback { self.updateCardNumberDisplay() if (emoney.isTampilRiwayat()){ - let riwayat = emoney.getRiwayatList() + let riwayat = self.deduplicateHistory(emoney.getRiwayatList()) if let first = riwayat.first { let dateFmt = DateFormatter() dateFmt.dateFormat = "dd MMM yyyy, HH:mm" @@ -707,6 +707,22 @@ private extension HomeViewController { formatter.minimumFractionDigits = 0 return formatter }() + + func deduplicateHistory(_ items: [RiwayatCard]) -> [RiwayatCard] { + var seen = Set() + return items.filter { item in + let key = historyKey(for: item) + return seen.insert(key).inserted + } + } + + func historyKey(for item: RiwayatCard) -> String { + let timestamp = item.getTransationTime()?.timeIntervalSince1970 ?? 0 + let locationId = item.getLocationId() ?? "" + let locationName = item.getLocationName() ?? "" + let title = item.getTitle() ?? "" + return "\(timestamp)|\(item.getAmount())|\(item.getProsesTipe())|\(locationId)|\(locationName)|\(title)" + } } // MARK: - UILabel letter spacing helper