如何在Swift 3中使用Core Data保存和展示图片

5

我正在使用 Swift 3 - xcode 8 进行项目开发,尝试使用核心数据(core data)来保存并展示一些图片在一个名为“users”的数据库表格中。

这些图片是用户个人资料中的头像。

目前我已经成功地保存了字符串,并能够从核心数据中展示出来。但是在处理图片时遇到了问题。

将用户添加到核心数据中

func addUser() {
    let app = UIApplication.shared.delegate as! AppDelegate
    let context = app.persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
    request.returnsObjectsAsFaults = false

    let newUser = NSEntityDescription.insertNewObject(forEntityName: "Users", into: context)

    if (firstName.text == "" && lastName.text == "" && contact.text == "" && email.text == "") { //if we have a user profile delete it
        deleteUser()
    } else { // add a new user profile
        newUser.setValue(firstName.text, forKey: "firstName")
        newUser.setValue(lastName.text, forKey: "lastName")
        newUser.setValue(contact.text, forKey: "contact")
        newUser.setValue(email.text, forKey: "email")

        //newUser.setValue(imageView.image, forKey: "photo")
        //let imgUrl = UIImagePickerControllerReferenceURL as! NSURL
        let img = UIImage(named: "f.png")
        let imgData = UIImageJPEGRepresentation(img!, 1)

        newUser.setValue(imgData, forKey: "photo")

        print ("Data added in Users")
    }
    do {
        try context.save()
        //print("saved!!!")
        Alert.show(title: "Success", message: "Profile Saved", vc: self)
    } catch {
       // print ("Error")
        Alert.show(title: "Error", message: "Profile not Saved", vc: self)
    }
}

core data 中展示用户

func showUser() {
    let app = UIApplication.shared.delegate as! AppDelegate
    let context = app.persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")

    request.returnsObjectsAsFaults = false

    do {
        let results = try context.fetch(request)

        if results.count > 0 {
            print("Profile: Data Found:")
            for result in results as! [NSManagedObject] {
               if let firstNameinData = result.value(forKey: "firstName") as? String{
                    firstName.text = firstNameinData
                    print(firstNameinData)
                }

                if let lastNameinData = result.value(forKey: "lastName") as? String{
                    lastName.text = lastNameinData
                    print(lastNameinData)
                }

                if let contactinData = result.value(forKey: "contact") as? String{
                    contact.text = contactinData
                    print(contactinData)
                }

                if let emailinData = result.value(forKey: "email") as? String{
                    email.text = emailinData
                    print(emailinData)
                }

                if let photoinData = result.value(forKey: "photo") as? UIImage{
                    imageView.image = photoinData
                }
            }
        } else {  // if there is not a user profile
            firstName.text = ""
            lastName.text = ""
            contact.text = ""
            email.text = ""
            print("Profile : No data found")
        }
        //print("Loaded!!!")
    } catch {
        print ("Error Loading")
    }
}

我不能展示我保存的图片。 你有什么建议吗?

编辑:Xcode 给出以下信息 "Connection to assetsd was interrupted or assetsd died"


你保存了一个(NS)Data对象到属性photo,而不是UIImage对象。所以我猜测:if let photoinData = result.value(forKey: "photo") as? NSData{imageView.image = UIImage(data: photoinData);} 或者类似的代码应该可以工作。 - Larme
我做到了,它起作用了。很好,谢谢 :) - H.N.
类似的方法吗?如何在Swift中从照片库获取视频的NSData? - Larme
那是另一个话题,请在SO上提出另一个问题,而不是在评论中。 - Larme
好的,谢谢。已完成。 - H.N.
显示剩余3条评论
4个回答

11
Usersphoto属性是(NS)Data类型,你需要将UIImage转换为NSData
let img = UIImage(named: "f.png")
let imgData = UIImageJPEGRepresentation(img!, 1)
newUser.setValue(imgData, forKey: "photo")

当您检索信息时,您所做的类似于将 photo 视为 UIImage 对象:

if let photoinData = result.value(forKey: "photo") as? UIImage{
    imageView.image = photoinData
}

根据之前的内容,这是不合逻辑的。应该像这样:

if let imageData = result.value(forKey: "photo") as? NSData {
    if let image = UIImage(data:imageData) as? UIImage {
        imageView.image = image
    }
}

注意:我不懂Swift语言,所以提供的代码可能无法编译,但是你应该能够理解哪里出了问题以及需要做什么。


1
"Larme几乎说对了,但是应该是这样的:

"
if let image = UIImage(data:imageData) as? UIImage

do this:

if let image = UIImage(data: imageData as Data)

1
希望这能对您有所帮助。起初我也很困惑如何在Core Data中存储图像。
以下是用于在CoreData中保存图像的方法:
首先创建一个Nsmanaged Object Class。
class Item: NSManagedObject {


}

Declare the image as NSData

import CoreData

extension Item {

    @NSManaged var image: NSData?
    @NSManaged var name: String?
    @NSManaged var email: String?

}

现在进入您想要保存图像的视图控制器。
class newViewController: UIViewController ,UIImagePickerControllerDelegate,UINavigationControllerDelegate{

 var item : Item? = nil

    var imagePicker = UIImagePickerController()

    var PassImages = UIImage()

    @IBOutlet var name: UITextField!

    @IBOutlet var email: UITextField!

    @IBOutlet var photoclick: UIButton!

        var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext


    @IBAction func clickaction(_ sender: Any) {

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
            print("Button capture")

            let picker = UIImagePickerController()
            picker.allowsEditing = true
            picker.sourceType = .photoLibrary
            picker.delegate = self  //Don't forget this line!
            self.present(picker, animated: true, completion: nil)


        }
    }


    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        var selectedImage: UIImage?
        if let editedImage = info[.editedImage] as? UIImage {
            selectedImage = editedImage
            self.image.image = selectedImage!
            picker.dismiss(animated: true, completion: nil)
        } else if let originalImage = info[.originalImage] as? UIImage {
            selectedImage = originalImage
            self.image.image = selectedImage!
            picker.dismiss(animated: true, completion: nil)
        }

    }


    func imagePickerControllerDidCancel(picker: UIImagePickerController!) {

        self.dismiss(animated: true, completion: nil)
    }

    @IBOutlet var image: UIImageView!=nil


    @IBAction func submit(_ sender: Any) {

        if name.text != "" && email.text != ""
        {

            let entityDescription = NSEntityDescription.entity(forEntityName: "Table", in: context)

            let item = Item(entity: entityDescription!, insertInto: context)

            item.name = name.text
            item.email = email.text

            item.image = image.image!.pngData()! as NSData

            do {
                try context.save()
                print("saved this moc")
            } catch {
                return
            }

 let UserDetailsVc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController

            self.navigationController?.pushViewController(UserDetailsVc, animated: true)

        }
        else
        {
            print("mail check")
            let alertController1 = UIAlertController (title: "Fill Email id", message: "Enter valid email", preferredStyle: UIAlertController.Style.alert)

            alertController1.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            present(alertController1, animated: true, completion: nil)
        }
    }

override func viewDidLoad() {

        super.viewDidLoad()

        if item != nil {
            name.text = item?.name
            email.text = item?.email
            image.image = UIImage(data: (item?.image)! as Data)
        }
    }

这个控制器用于获取所有内容。
class ViewController: UIViewController ,UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate{

    var userarray: [Table] = []

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return userarray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell

        let name = userarray[indexPath.row]
        cell.username.text = name.name

        cell.showImage?.image = UIImage(data: (name.image)!)

         return cell
    }

    @IBOutlet var table: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()

        fetchData()
    }

    override func viewWillAppear(_ animated: Bool) {
        fetchData()
    }

    func fetchData(){

        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

        do {
            userarray = try context.fetch(Table.fetchRequest())
            print(userarray,"user")

        }catch{
            print("error")
        }

    }

}

1
希望我能帮到你。对我来说很好用。
var results :[Any] = []

let image = UIImage(named: "image.png")
        //this is the line that appears to be wrong
        let imageData = UIImagePNGRepresentation(image!) as NSData?



        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }


        // 1
        let managedContext =
            appDelegate.persistentContainer.viewContext

        // 2
        let entity =
            NSEntityDescription.entity(forEntityName: "Image",
                                       in: managedContext)!

        let person = NSManagedObject(entity: entity,
                                     insertInto: managedContext)

        // 3
        person.setValue(imageData, forKeyPath: "name")

        // 4
        do {
            try managedContext.save()
            results.append(person)


        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接