簡體   English   中英

使用 func 從核心數據二進制數據中刪除特定項目

[英]use func to delete a specific item from core data binary data

我正在嘗試從核心數據中刪除二進制數據。 我正在使用 var int 'place' 來確定我要刪除的特定項目 我在下面的 helpImage.shareInstance.deleteInfo(info: place) 下收到運行時錯誤。

無法將“Int”類型的值轉換為預期的參數類型“Info”

我該怎么做才能刪除保存在核心數據二進制屬性中的第一項?

import UIKit;import CoreData

class ViewController: UIViewController {

    var place = 0
  
    
    override func viewDidLoad() {
        super.viewDidLoad()
     
        
        let gwen = UIImage(named: "unnamed.jpg")
        
        if let imageData = gwen.self?.pngData() {
            helpImage.shareInstance.saveImage(data: imageData)
        }
        
        let alz = UIImage(named: "alba.jpeg")
        
        if let imageData = alz.self?.pngData() {
            helpImage.shareInstance.saveImage(data: imageData)
        }
        

  
        
       
        
    }
    
   
   
    
    
   
   
   
    
    @objc func deleteM(){
       
       
            helpImage.shareInstance.deleteInfo(info: place)





        
        
    }
    
}



class helpImage: UIViewController{
    private class func getContext() -> NSManagedObjectContext {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
        return appDelegate.persistentContainer.viewContext
    }
    static let shareInstance = helpImage()
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
 
    
    func saveImage(data: Data) {
        let imageInstance = Info(context: context)
        
        imageInstance.img = data
            
        do {
            try context.save()
          
        } catch {
            print(error.localizedDescription)
        }
    }
    
 
    func deleteInfo(info: Info) {
         do {
             try context.delete(info)
           
         } catch {
             print(error.localizedDescription)
         }
      }
  
    
   
}

我也是 swift 的新手,正在學習,所以如果有人有反饋,我很樂意實施。

這是 stroryBoard:點擊“保存”按鈕,我們會將圖像保存在 CoreData 中,點擊“顯示”按鈕,我們將顯示一個 tableView,其中包含從 CoreData 獲取的圖像在此處輸入圖像描述

這是 coreData:不要忘記在 coreData Class 的 Codegen 中檢查 Manual/None 在此處輸入圖像描述

然后手動添加 coreData NSManagedObject SubClass 文件(會有兩個文件)。

最初生成 class 和屬性文件:

資料來源: https://developer.apple.com/documentation/coredata/modeling_data/generating_code

  1. 從 Xcode 菜單欄中,選擇編輯器 > 創建 NSManagedObject 子類。

  2. Select 您的數據 model,然后選擇相應的實體,並選擇保存文件的位置。 Xcode 將 class 和屬性文件都放入您的項目中。

// this is how your "Picture+CoreDataClass.swift" looks like

import Foundation
import CoreData

@objc(Picture)
public class Picture: NSManagedObject {

}

// this how your "Picture+CoreDataProperties.swift" looks like

import Foundation
import CoreData


extension Picture {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Picture> {
        return NSFetchRequest<Picture>(entityName: "Picture")
    }

    @NSManaged public var pic: String?
    @NSManaged public var id: Int64

}

extension Picture : Identifiable {

}

我使用下面的擴展來獲取 currentTimeStamp,因為我們需要每個 coreData object 的唯一 ID,我們將傳遞 currentTimeStamp 作為唯一的 ID。

// MARK: - Get the Current Local Time and Date Timestamp
source: https://stackoverflow.com/questions/46376823/ios-swift-get-the-current-local-time-and-date-timestamp

extension Date {
    static var currentTimeStamp: Int64{
        return Int64(Date().timeIntervalSince1970 * 1000)
    }
}

我在 DataBaseHelper.swift 文件中創建了 CRUD 函數

// this "DataBaseHelper" Class

import Foundation
import UIKit
import CoreData

class DataBaseHelper {
    
    // MARK: - Get Context
    
    class func getContext() -> NSManagedObjectContext{
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        return appDelegate.persistentContainer.viewContext
    }
    
    static let shareInstance = DataBaseHelper()
        
    let context = getContext()
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Picture")
    
    // MARK: - Save Images
    
    func saveImage(picString: String, id: Int64 = Date.currentTimeStamp) {

// here I have passed id = Date.currentTimeStamp, as we need unique ID for each of our object in coreData and Date.currentTimeStamp will always give unique integer. we will use this ID to update and delete particular object.
        
        let entity = NSEntityDescription.entity(forEntityName: "Picture", in: context)!
        
        let image = NSManagedObject(entity: entity, insertInto: context)
                
        image.setValue(picString, forKey: "pic") // key should be same as the attributes taken in coreData Table.
        image.setValue(id, forKey: "id") // key should be same as the attributes taken in coreData Table.
        
        do {
            try context.save()
            print("Images saved in coreData")
            print("imageString: \(picString), id: \(id)") // this will print your entered (saved) object in coreData
        }  catch let error {
            print("Could not save images: \(error.localizedDescription)")
        }
    }
    
    // MARK: - fetch Images
    
    func fetchImages() -> [Picture] {
        
        var arrImages = [Picture]()
        
        fetchRequest.returnsObjectsAsFaults = false
        
        do {
            arrImages = try context.fetch(fetchRequest) as? [Picture] ?? [Picture]()
            print("Images while fetching from coreData: \(arrImages)") // this will print all objects saved in coreData in an array form.
        } catch let error {
            print("Could not fetch images: \(error.localizedDescription)")
        }
        return arrImages
    }
    
    // MARK: - fetch Images by ID
    
    func fetchImagesByID(id: Int64) -> Picture {
        
        fetchRequest.returnsObjectsAsFaults =  false
        let predicate = NSPredicate(format: "id == \(id)")
        fetchRequest.predicate = predicate
        
        let result = try? context.fetch(fetchRequest)
        return result?.first as? Picture ?? Picture()
    }
    
    // MARK: - Update Image
    
    func updateImage(object: Picture) {
        
        let image = fetchImagesByID(id: object.id) // we will first fetch object by its ID then update it.
        
        image.pic = object.pic
        
        do {
            try context.save()
            print("Image updated in CoreData")
            print("after updating Picture --> \(object)")
        } catch let error {
            print("Could not update Picture: \(error.localizedDescription)")
        }
    }
    
    // MARK: - Delete Image
    
    func deleteImage(id: Int64) {
        
        let image = fetchImagesByID(id: id) // we will first fetch object by its ID then delete it.
        
        context.delete(image)
        
        do {
            try context.save()
            print("Image deleted from CoreData")
        } catch let error {
            print("Could not delete Image --> \(error.localizedDescription)")
        }
    }
}

這是我們的視圖控制器:

我在 Assets 文件夾中添加了 4 張圖像。

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var btnSaveImages: UIButton!
    @IBOutlet weak var tableViewPicture: UITableView!
    @IBOutlet weak var btnShowImages: UIButton!
    
    
    var resultImages = [Picture]() // this an an instance of our model class (coreData)

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationItem.title = "CoreData Demo"
        
        setUpTableView()
        
    }
    
    // MARK: - Save Images
    
    func saveImagesInCoreData() {
        
        // I have added 4 images in Assets folder, here we will save 3 images in CoreData
        
        let image1 = "flower1"
        let image2 = "flower2"
        let image3 = "flower3"
        
        DataBaseHelper.shareInstance.saveImage(picString: image1)
        DataBaseHelper.shareInstance.saveImage(picString: image2)
        DataBaseHelper.shareInstance.saveImage(picString: image3)
    }
    
    // MARK: - Fetch Images
    
    func fetchImagesFromCoreData() {
        
        resultImages = DataBaseHelper.shareInstance.fetchImages() // this will give fetched images
        
    }
    
    // MARK: - Set Up TableView
    
    func setUpTableView () {
        
        tableViewPicture.delegate = self
        tableViewPicture.dataSource = self
    }
    
    // MARK: - Button Save Images Event

    @IBAction func btnSaveImages_Event(_ sender: UIButton) {
        
        saveImagesInCoreData() // save images in CoreData
        
    }
    
    // MARK: - Button Show Images Event
    
    @IBAction func btnShowImages_Event(_ sender: UIButton) {
        
        fetchImagesFromCoreData() // fetch Images from CoreData
        self.tableViewPicture.reloadData() // reload tableView
    }
}

// MARK: - Extesnion TableViewDelegate and TableViewDataSource

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return resultImages.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell") ?? UITableViewCell()
        
        cell.imageView?.image = UIImage(named: resultImages[indexPath.row].pic ?? "")
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        
        return true
    }
    
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        
        let editAction = UITableViewRowAction(style: .default, title: "Edit") { (action, indexPath) in
            print("Action Edit")
            
            // here we will edit image of selected row in our tableView, we will update selected row with new image that is "flower4".
            
            let image4 = "flower4"
            
            self.resultImages[indexPath.row].pic = image4
            
            DataBaseHelper.shareInstance.updateImage(object: self.resultImages[indexPath.row]) // update image of selected row in tableView
            self.tableViewPicture.reloadData()
                                    
        }
        
        editAction.backgroundColor = .lightGray
        
        let deleteAction = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
            print("Action Delete")
            
            // here we will delete an object of selected row in our tableView.
            
            DataBaseHelper.shareInstance.deleteImage(id: self.resultImages[indexPath.row].id) // delete object of selected row in tableView
            self.resultImages.remove(at: indexPath.row) // remove from resultImages array
            self.tableViewPicture.reloadData()
        }
        
        return [deleteAction, editAction]
        
    }
    
}

如果您有疑問,請隨時詢問!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM