2017-12-12 8 views
1

私のios swiftアプリケーションでコアデータを使用するデータベースがあります。 これは多くのエンティティを持ち、すべてのエンティティはsyncStatusという整数フィールドを持っています。それは0, 1, or 2にすることができます。起動時にコアデータ - 同じフィールドを使用してすべてのエンティティを取得します

、私だけでは、各タイプを取得し、それを変更することなく、それを行うための方法はありsyncStatus = 1を持っており、それが0

に変更するすべてのエンティティをループにしたいですか?

だから、私が欲しいのです:

  • はそれらを介してsyncStatus = 1
  • LoopALLエンティティを取得し、現在、私はそれらを一つ一つやってsyncStatus = 0

を設定します。

  • それらを介してsyncStatus = 1
  • ループでUserEntitiesをフェッチし、syncStatus = 0
  • それらを介してsyncStatus = 1
  • ループでcountryEntitiesをフェッチし、syncStatus = 0

によってすべてのエンティティ1のために同じことを行いますが設定を設定しますコード:

let allUsers = context?.fetch(FetchRequest<UserEntity>().filtered(with: "syncStatus", equalTo: "1")) 
let allCountries = context?.fetch(FetchRequest<CountryEntity>().filtered(with: "syncStatus", equalTo: "1")) 
. 
. 
. 

私は単なる一般的なアプローチを見つけようとしています。後で、このコードに戻ってここに追加する必要のない別のエンティティ/テーブルを追加します。

答えて

0

NSManagedObjectModelは、含まれるエンティティを列挙でき、NSEntityDescriptionは各エンティティにプロパティを与えることができます。モデルへの参照を取得したら:

let entitiesWithSync = model.entities.filter { 
    $0.properties.contains(where: { $0.name == "syncStatus" }) 
} 

関連するすべてのエンティティを提供します。このエンティティのリストを使用して更新を駆動することができます。スタートアップ時にNSBatchUpdateRequestを使用する方が速いことに注意してください。上記のループで取得したエンティティの説明を使用して、バッチ更新要求を作成できます。

2

まず、すべてのエントリをフェッチしてフィルタリングすると、述語を適用するよりもはるかに高価になります。

静的メソッドを使用するプロトコル拡張を使用することをお勧めします。利点は、あなたが、それを使用するすべてのNSManagedObjectサブクラスのためSyncStatusResettableを採用し、

do { 
    try UserEntity.resetSyncStatus(in: managedObjectContext) 
    try CountryEntity.resetSyncStatus(in: managedObjectContext) 
} catch { print(error) } 

managedObjectContextを呼び出すにはタイプ

protocol SyncStatusResettable 
{ 
    associatedtype Entity: NSManagedObject = Self 

    var syncStatus : String {get set} 
    static var entityName : String { get } 
    static func resetSyncStatus(in context: NSManagedObjectContext) throws 
} 

extension SyncStatusResettable where Entity == Self 
{ 
    static var entityName : String { 
     return NSStringFromClass(self).components(separatedBy: ".").last! 
    } 

    static func resetSyncStatus(in context: NSManagedObjectContext) throws 
    { 
     let request = NSFetchRequest<Entity>(entityName: entityName) 
     request.predicate = NSPredicate(format: "syncStatus == 1") 
     let items = try context.fetch(request) 
     for var item in items { item.syncStatus = "0" } 
     if context.hasChanges { try context.save() } 
    } 

} 

に直接メソッドを呼び出すことができるということであることには

+0

本当にこの回答が好きです – davidethell

0

現在NSManagedObjectContextのインスタンスであります私はオブジェクトモデルからすべてのエンティティByNameをループしています:

lazy var managedObjectModel: NSManagedObjectModel = { 
    let modelUrl = NSBundle.mainBundle().URLForResource("SomeProject", withExtension: "momd")! 
    return NSManagedObjectModel(contentsOf: modelUrl) 
} 

func updateAllData() { 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 

    context.performAndWait { 
     let allEntities = self.managedObjectModel.entitiesByName 
     for (entity, items) in allEntities { 
      let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity) 
      ... 
     } 
    } 
} 
関連する問題