删除 Realm 对象所有未来出现的正确方法是什么?



目前,我正在使用此代码删除所有未来的重复事务:

let futureRecurringTransactions = self.transactions.filter(NSPredicate(format: "transactionDescription == %@ && transactionDate >= %@ && transactionCategory == %@", transaction!.transactionDescription!, transaction!.transactionDate as CVarArg, transaction!.transactionCategory!))

for transaction in futureRecurringTransactions {
try! self.realm.write {
self.realm.delete(transaction)
}
}

这是我的Realm数据模型:

import RealmSwift
class Transaction: Object {

@objc dynamic var transactionDescription: String? = nil
@objc dynamic var transactionAmount = 0.0
@objc dynamic var transactionDate = Date()
@objc dynamic var transactionCategory: Category? = nil
@objc dynamic var repeatInterval = ""
@objc dynamic var isCleared = false
@objc dynamic var transactionName = ""
@objc dynamic var transactionID = UUID().uuidString

convenience init(theDate: Date) {
self.init()
self.transactionDate = theDate
}

override static func primaryKey() -> String? {
return "transactionID"
}

}

代码是有效的,但感觉我做这件事的方式很业余,很笨拙。有没有更好的方法更准确、更恰当?

我认为使用transactionID可能很好,但每个事务都有一个唯一的transactionID,所以我不确定这将如何工作。

我通常会为要放置在集合上的每个约束创建一个唯一的NSPredcate。您可以混合和匹配每个谓词以形成一组唯一的筛选器。例如:

extension NSPredicate {
static func transactionDescriptionEqualTo(_ description: String?) -> NSPredicate {
if let description = description {
return .init(format: "transactionDescription == %@", description)
}
return .init(format: "transactionDescription == nil")
}
static func transactionCategoryEqualTo(_ category: Category?) -> NSPredicate {
if let category = category {
return .init(format: "transactionCategory == %@", category)
}
return .init(format: "transactionCategory == nil")
}
static func transactionDateIsAfter(_ date: Date) -> NSPredicate {
return .init(format: "transactionDate >= %@", date as NSDate)
}
static func transactionIDNotEqualTo(_ id: String) -> NSPredicate {
return .init(format: "transactionID != %@", id)
}
static func futureRepeats(of transaction: Transaction) -> NSPredicate {
return NSCompoundPredicate(andPredicateWithSubpredicates: [
.transactionDescriptionEqualTo(transaction.transactionDescription),
.transactionCategoryEqualTo(transaction.transactionCategory),
.transactionDateIsAfter(transaction.transactionDate),
.transactionIDNotEqualTo(transaction.transactionID),
])
}
}

还要注意,您不需要对结果进行循环。您可以删除结果中的所有对象,如下所示:

let realm = try Realm()
try realm.write {
realm.delete(transactions.filter(.futureRepeats(of: transaction)))
}

最后,最好将transactionID作为约束包含在内。否则,原始交易将包含在结果中。

相关内容

最新更新