development

iOS : 모든 핵심 데이터 Swift 삭제

big-blog 2021. 1. 10. 19:51
반응형

iOS : 모든 핵심 데이터 Swift 삭제


신속하게 모든 핵심 데이터를 삭제하는 방법에 대해 약간 혼란 스럽습니다. IBAction링크 된 버튼을 만들었습니다 . 버튼을 클릭하면 다음이 있습니다.

let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext

그런 다음 모든 핵심 데이터 콘텐츠를 시도하고 삭제하는 다양한 방법을 엉망으로 만들었지 만 작동하지 않는 것 같습니다. removeAll을 사용하여 저장된 배열에서 삭제했지만 여전히 핵심 데이터에서 삭제할 수 없습니다. 나는 어떤 유형의 for 루프가 필요하다고 가정하지만 요청에서 만드는 방법을 잘 모르겠습니다.

단일 행 삭제의 기본 원칙을 적용 해 보았습니다.

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {

    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext

    if editingStyle == UITableViewCellEditingStyle.Delete {

        if let tv = tblTasks {
            context.deleteObject(myList[indexPath!.row] as NSManagedObject)
            myList.removeAtIndex(indexPath!.row)
            tv.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
        }

        var error: NSError? = nil
        if !context.save(&error) {
            abort()
        }

    }

}

그러나이 문제는 버튼을 클릭 할 때 indexPath 값이없고 컨텍스트로 할 수없는 모든 값을 반복해야한다는 것입니다.


이 간단한 해결책을 시도하십시오.

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false

    do 
    {
        let results = try managedContext.executeFetchRequest(fetchRequest)
        for managedObject in results
        {
            let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
            managedContext.deleteObject(managedObjectData)
        }
    } catch let error as NSError {
        print("Detele all data in \(entity) error : \(error) \(error.userInfo)")
    }
}

스위프트 4

func deleteAllData(_ entity:String) {
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false
    do {
        let results = try dataController.viewContext.fetch(fetchRequest)
        for object in results {
            guard let objectData = object as? NSManagedObject else {continue}
            dataController.viewContext.delete(objectData)
        }
    } catch let error {
        print("Detele all data in \(entity) error :", error)
    }
}

이행:

 self.deleteAllData("your_entityName")

모든 데이터를 삭제하려면 NSBatchDeleteRequest를 사용할 수 있습니다.

func deleteAllData(entity: String)
{
    let ReqVar = NSFetchRequest(entityName: entity)
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
    do { try ContxtVar.executeRequest(DelAllReqVar) }
    catch { print(error) }
}

다음 방법을 사용하여 작동했습니다.

@IBAction func btnDelTask_Click(sender: UIButton){

    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext  
    let request = NSFetchRequest(entityName: "Food")

    myList = context.executeFetchRequest(request, error: nil)


    if let tv = tblTasks {

        var bas: NSManagedObject!

        for bas: AnyObject in myList
        {
           context.deleteObject(bas as NSManagedObject)
        }

        myList.removeAll(keepCapacity: false)

        tv.reloadData()
        context.save(nil)
    }
}

그러나 이것이 최선의 방법인지 확실하지 않습니다. 나는 또한 anyobject가있는 것으로 추론 된 'constant'bas '오류를 받고있다. 그래서 그것에 대한 해결책이 있다면 그것은 좋을 것이다.

편집하다

bas로 변경하여 수정 : AnyObject


에 대한 Swift 3.0

func DeleteAllData(){


    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedContext = appDelegate.persistentContainer.viewContext
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: NSFetchRequest<NSFetchRequestResult>(entityName: "Entity"))
    do {
        try managedContext.execute(DelAllReqVar)
    }
    catch {
        print(error)
    }
}

Swift 3.0에서

 func deleteAllRecords() {
        //delete all data
        let context = appDelegate.persistentContainer.viewContext

        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "YourClassName")
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)

        do {
            try context.execute(deleteRequest)
            try context.save()
        } catch {
            print ("There was an error")
        }
    }

Swift 4.0 ( svmrajesh의 답변 수정 버전 ... 또는 적어도 Xcode가 나를 위해 실행하기 전에 무엇으로 바꿨는지)

func deleteAllData(entity: String) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
fetchRequest.returnsObjectsAsFaults = false

do
{
    let results = try managedContext.fetch(fetchRequest)
    for managedObject in results
    {
        let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
        managedContext.delete(managedObjectData)
    }
} catch let error as NSError {
    print("Delete all data in \(entity) error : \(error) \(error.userInfo)")
}
}

이행:

deleteAllData(entity: "entityName")

iOS 9.0Swift 3destroyPersistentStore 부터 사용할 수 있습니다 .

public func clearDatabase() {
    guard let url = persistentContainer.persistentStoreDescriptions.first?.url else { return }

    let persistentStoreCoordinator = persistentContainer.persistentStoreCoordinator

     do {
         try persistentStoreCoordinator.destroyPersistentStore(at:url!, ofType: NSSQLiteStoreType, options: nil)
         try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url!, options: nil)
    } catch let error {
         print("Attempted to clear persistent store: " + error.localizedDescription)
        }
    }
}

이 clean () 메소드는 DataModel에서 엔티티 목록을 가져오고 모든 데이터를 지 웁니다.

func deleteAll(entityName: String) -> Error? {
            if #available(iOS 9.0, *) {
                do {
                    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                    try context.execute(batchDeleteRequest)
                } catch {
                    return error
                }
                return nil
            } else {
                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                fetchRequest.returnsObjectsAsFaults = false
                do
                {
                    let results = try context.fetch(fetchRequest)
                    for managedObject in results
                    {
                        if let managedObjectData:NSManagedObject = managedObject as? NSManagedObject {
                            context.delete(managedObjectData)
                        }
                    }
                } catch  {
                    return error
                }
                return nil
            }
        }

        var objectModel: NSManagedObjectModel? {
            if #available(iOS 10.0, *) {
                return persistentContainer.managedObjectModel
            } else {
                return persistentStoreCoordinator?.managedObjectModel
            }
        }

        open func clean() {
            if let models = objectModel?.entities {
                for entity in models {
                    if let entityName = entity.name {
                        _ = deleteAll(entityName: entityName)
                    }
                }
            }
        }

행복한 코딩!


Jayant Dash의 우수하고 포괄적 인 답변을 기반으로 Swift 3의 모든 핵심 데이터를 지우는 구현은 다음과 같습니다. iOS10 + 만 지원하기 때문에 더 간단합니다. 하드 코딩하지 않고 모든 핵심 데이터 엔티티를 삭제합니다.

public func clearAllCoreData() {
    let entities = self.persistentContainer.managedObjectModel.entities
    entities.flatMap({ $0.name }).forEach(clearDeepObjectEntity)
}

private func clearDeepObjectEntity(_ entity: String) {
    let context = self.persistentContainer.viewContext

    let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)

    do {
        try context.execute(deleteRequest)
        try context.save()
    } catch {
        print ("There was an error")
    }
}

대안은 영구 저장소 (iOS 10+, swift 3)를 완전히 제거하고 다시 만드는 것입니다.

let urls = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask);
    var dbUrl = urls[urls.count-1];
    dbUrl = dbUrl.appendingPathComponent("Application Support/nameOfYourCoredataFile.sqlite")
    do {
        try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: dbUrl, ofType: NSSQLiteStoreType, options: nil);
    } catch {
        print(error);
    }
    do {
        try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: dbUrl, options: nil);
    } catch {
        print(error);
    }

내가 아는 한 두 가지 간단한 방법이 있습니다.

방법 1 :

가져 오기, 삭제, 반복

// 가져 오기 요청 초기화

let fetchRequest = NSFetchRequest(entityName: "Item")

// 가져 오기 요청 구성

 fetchRequest.includesPropertyValues = false

do {

let items = try managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]

for item in items {
    managedObjectContext.deleteObject(item)
}

// Save Changes
try managedObjectContext.save()

} catch {
// Error Handling
// ...

}

방법 2 :

일괄 삭제 요청

// 가져 오기 요청 생성

let fetchRequest = NSFetchRequest(entityName: "Item")

// 일괄 삭제 요청 생성

     let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
       do {
          try managedObjectContext.executeRequest(batchDeleteRequest)

          } catch {
// Error Handling
    }

나는 둘 다 테스트했고 둘 다 잘 작동합니다.


Swift3의 모든 핵심 데이터 엔티티를 삭제하기 위해 이것을 사용합니다.

func deleteAllCD(){
    for entityName in ["EntityName", "AnotherEntityName"]{
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let delAllReqVar = NSBatchDeleteRequest(fetchRequest: request)
        do { try persistentContainer.viewContext.execute(delAllReqVar) }
        catch { print(error) }
    }
}

스위프트 3

// Replace 'MyEntityName' with your managed object class.
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<MyEntityName> = MyEntityName.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
moc.perform {
    do {
        let myEntities = try fetchRequest.execute()
        for myEntity in myEntities {
            moc.delete(myEntity)
        }
        try moc.save()
    } catch let error {
        print("Delete Error: \(error.localizedDescription)")
    }
}

위와 비슷하지만 AppDelegte 호출이 제거되고 UIView 변수가 사용됩니다.

var context: NSManagedObjectContext?
//deleting Message

func deleteMessages(entity: String) {
   do {
      let request = NSFetchRequest(entityName: entity)
      print(request)

      if let result = try context!.executeFetchRequest(request) as? [your class of NSManagedObject] {
          for message in result {
             context!.deleteObject(message)
             try context!.save()
             print(message)
             self.tableView.reloadData()
          }
      }
   } catch {
         print("miss")
   }
}

통화 기능을 사용하려면

self.deleteMessages("TimeMaster")

이 시도:

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let ReqVar = NSFetchRequest(entityName: entity)
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
    do { try ContxtVar.executeRequest(DelAllReqVar) }
    catch { print(error) }
}

스위프트 4 :

destroyPersistentStoreAtURL(_:withType:options:) will delete (or truncate) the target persistent store. This will safely destroy a persistent store.

Add:

do {
    try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: nil)
} catch {
    // Error Handling
}

Destroy / Delete / Truncate:

do {
    try persistentStoreCoordinator.destroyPersistentStoreAtURL(persistentStoreURL, withType: NSSQLiteStoreType, options: nil)
} catch {
    // Error Handling
}

Note : Parameters in above method should be identical to addPersistentStoreWithType method. You need to re-initiate storeCoordinator to use store again.


For Swift 4.0

  func deleteAllData(_ entity:String) {

    let managedContext =  DatabaseController.getContext().persistentStoreCoordinator
     let context = DatabaseController.getContext()
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    do {
        try managedContext?.execute(batchDeleteRequest, with: context)
    }
    catch {
        print(error)
    }


  }

Swift 4

From iOS 9, there is the possibility of erasing persistent storage. For better maintenance – create NSPersistentStoreCoordinator extension with abstract function.

extension NSPersistentStoreCoordinator {
    func destroyPersistentStore(type: String) -> NSPersistentStore? {
        guard 
            let store = persistentStores.first(where: { $0.type == type }),
            let storeURL = store.url 
        else {
            return nil
        }

        try? destroyPersistentStore(at: storeURL, ofType: store.type, options: nil)

        return store
    }
}

Then destroying SQLite persistent storage looks pretty simple:

let coordinator = persistentContainer.persistentStoreCoordinator
let store = coordinator.destroyPersistentStore(type: NSSQLiteStoreType)

Recommendations

  1. Update destroyPersistentStore function which is no-nullable and throws specific errors, for example CoreDataError enum.
  2. Probably you want to refresh your persistent storage. For this, you can use addPersistentStore function of NSPersistentStoreCoordinator, with retrieved NSPersistentStore object from destroyPersistentStore.

ReferenceURL : https://stackoverflow.com/questions/24658641/ios-delete-all-core-data-swift

반응형