0

When I pick an image from gallery, I convert it to NSData & assign it a variable like so...

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

  if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
     UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)

     let data = UIImagePNGRepresentation(image) as NSData?
     self.appDelegate.mydata1 = data!
  }

Now I'm trying to store self.appDelegate.mydata1 to coredata like so..

guard let appDelegate = ... else {
    return
}
let managedContext = ...
let entity = ...

let newProdObj = ...

newProdObj.setValue(self.appDelegate.mydata1, forKey: "imageData") //The attribute imageData in xcdatamodel is of type 'Binary Data'

do {
    try managedContext.save()
    self.newProductDetails.append(newProdObj as! NewProduct)

} catch let error as NSError {}

Later in another viewcontroller I'm fetching it like so...

guard let appDelegate = ...

        let managedContext = ...
        let fetchRequest = ...

        do {
            newProdDetails = try managedContext.fetch(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) as! [NewProduct]

               for result in newProdDetails {
                print(result)

                if let imageData = result.value(forKey: "imageData") as? NSData {
                    print(imageData)
                }}
        } catch let error as NSError {}

But when I try to print imageData, the control gets stuck and it goes on continuously printing numbers (which is the data) something like so...<123214 434534 345345 ...etc.

Did go through other posts with the same issue but couldn't get much help from them...

3 Answers3

0

Instead of saving image data in coreData, save your images in document directory and name of those images in UserDefaults/Core Data.

And then you can fetch name from UserDefaults/Core Data and you can get the filPath for those images using this :

// Get path for any filename in document directory
    func getFilePathInDocuments(fileName:String, completionHandler:@escaping(String, Bool)->()) {
        let path        = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
        let url         = NSURL(fileURLWithPath: path)
        let fileManager = FileManager.default
        let filePath    = url.appendingPathComponent(fileName)?.path

        if (fileManager.fileExists(atPath: filePath!)) {
            completionHandler(filePath!, true)
        }else{
            completionHandler("File not found!",false)
        }
    }

If you want to know how to write your images in document directory see this : how to use writeToFile to save image in document directory?

Sharad Chauhan
  • 4,487
  • 1
  • 21
  • 46
  • Hi bro!..regarding your suggestion, I actually might have more than 1 image and so after storing them, at some other place I want to show them in a tableview at proper indexpath.row. Can that be achieved using your suggestion...? –  Jan 17 '18 at 07:43
  • Yes, just write all those images to document directory (check link to achieve that) and then just store the names of all the images in your database. In any controller you can get the filePath of your image from the above function, just pass the stored image name to that function. – Sharad Chauhan Jan 17 '18 at 07:47
  • .@sharad chauhan what to pass for fileName while calling the function `getFilePathInDocuments ` –  Jan 17 '18 at 09:18
  • fileName means that imageName you gave while write it to document directory. – Sharad Chauhan Jan 17 '18 at 09:20
  • and will the completionhandler be null? –  Jan 17 '18 at 09:21
  • no, check for Bool value, if its false then file not found otherwise use the String value as filepath of that file. – Sharad Chauhan Jan 17 '18 at 09:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163309/discussion-between-sharad-chauhan-and-bvt). – Sharad Chauhan Jan 17 '18 at 09:23
0

This is not an issue. You are fetching the NSData which is an image, hence its printing the bytes in the image data which are the numbers you are talking about. Also this code is executing in the main thread, hence your app is unresponsive.

As the other answer pointed out save your image in document directory and save the relative path of the imagename in core data. This way you can fetch the name of the imagepath(relative mind you, as full document directory URL can change in app launch), and load the image from the document directory.

Also when saving the image in document directory, please do so in a background queue, using GCD or NSOperation/Operation, as if this image is large it can again block the main thread, as you are operating this in the main thread.

Saheb Roy
  • 5,661
  • 2
  • 18
  • 34
0

My suggestion is that convert image data to base64 string, and store it to CoreData. Later when you get back image, you can convert it back to NSData. Please refer this for base64 string conversion:

convert base64 decoded NSData to NSString

dduyduong
  • 124
  • 1
  • 5