デバッグ用のイベントログなどをCoreDataで管理する際に、一定件数を超えたら古いものから順に削除していきたい場合の処理です。
環境
- Swift:5.0.1
- Xcode:10.3 (10G8)
※注意
Swift 5.1、Xcode 11.0で正常に動作しなくなりました。
fetchRequest.fetchLimitで個数の制限ができなくなったようです。
コード
NSManagedObjectContextにExtensionとして追加します。
NSManagedObjectContext+Extension.swift
import CoreData
extension NSManagedObjectContext {
func delete(overLimit limit: Int, entityName: String, sortDescriptors: [NSSortDescriptor]?) throws {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
// ソート条件を指定
fetchRequest.sortDescriptors = sortDescriptors
// データ件数を取得
let n = try self.count(for: fetchRequest)
// 指定された上限を超えていれば削除を実行
if n > limit {
fetchRequest.fetchLimit = n - limit
try self.execute(NSBatchDeleteRequest(fetchRequest: fetchRequest))
}
}
}
使用例
TestEntityとして定義されたEntityを対象として、上限として指定した100件を超えたデータを日付の古いものから削除します。TestEntityはDate型のAttributeである日付データdateを持っています。contextはNSManagedObjectContextです。
do {
try context.delete(
overLimit: 100,
entityName: "TestEntity",
sortDescriptors: [NSSortDescriptor(key: "date", ascending: true)])
try context.save()
} catch {
...
}