Я пытаюсь удалить двоичные данные из основных данных. Я использую var int «место», чтобы определить, какой конкретный элемент я пытаюсь удалить.
Не удается преобразовать значение типа «Int» в ожидаемый тип аргумента «Info»
Что я могу сделать, чтобы удалить 1-й элемент, сохраненный в двоичном атрибуте основных данных?
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)
}
}
}
Я также новичок в быстроте и обучении, поэтому, если у кого-то есть отзывы, я более чем счастлив реализовать.
вот stroryBoard: при нажатии кнопки «Сохранить» мы будем сохранять изображения в CoreData, а при нажатии кнопки «Показать» мы отобразим tableView с нашими изображениями, полученными из CoreData
вот coreData: не забудьте проверить Manual/None в Codegen в coreData Class
затем вручную добавьте файлы coreData NSManagedObject SubClass (будет два файла).
Для первоначального создания файлов классов и свойств:
источник: https://developer.apple.com/documentation/coredata/modeling_data/generating_code
В строке меню Xcode выберите «Редактор» > «Создать подкласс NSManagedObject».
Выберите свою модель данных, затем соответствующую сущность и выберите место для сохранения файлов. Xcode помещает в ваш проект как класс, так и файл свойств.
// 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, мы будем передавать currentTimeStamp как идентификатор, чтобы быть уникальным.
// 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)
}
}
Я сделал функции CRUD в файле DataBaseHelper.swift.
// 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)")
}
}
}
вот наш ViewController:
Я добавил 4 изображения в папку Assets.
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]
}
}
если у вас есть сомнения, не стесняйтесь спрашивать!
вы также можете сослаться на эту статью: blog.devgenius.io/saving-images-in-coredata-8739690d0520
может быть, это может быть вам полезно: stackoverflow.com/questions/30200228/… , stackoverflow.com/questions/38017449/… , stackoverflow.com/questions/45341545/… , stackoverflow.com/questions/50477777/…