如何将 imageData 保存到 NSManagedObject 属性
Posted
技术标签:
【中文标题】如何将 imageData 保存到 NSManagedObject 属性【英文标题】:How to save imageData to NSManagedObject property 【发布时间】:2018-01-23 02:51:34 【问题描述】:我的应用程序从 Flickr 下载图像并将它们显示在 CollectionViewController 中,并将图像保存在 Core Data 中。我正在尝试将 imageData 保存到我的 NSManagedObject 上下文中,但我可以说我没有正确执行此操作,因为我从未在 cellForRowAt 函数中进入逻辑的“其他”部分。在哪里以及如何使用 imageData 属性更新我的“图像”NSManagedObject?
这是我的客户端类:
func getImagesFromFlickr(pin: Pin, context: NSManagedObjectContext, page: Any, completionHandlerForGetImages: @escaping (_ success: Bool, _ errorString: String?) -> Void)
let methodParameters = [
Constants.FlickrParameterKeys.Method: Constants.FlickrParameterValues.FlickrPhotosSearch,
Constants.FlickrParameterKeys.APIKey: Constants.FlickrParameterValues.APIKey,
Constants.FlickrParameterKeys.Format: Constants.FlickrParameterValues.ResponseFormat,
Constants.FlickrParameterKeys.Extras: Constants.FlickrParameterValues.MediumURL,
Constants.FlickrParameterKeys.NoJSONCallback: Constants.FlickrParameterValues.DisableJSONCallback,
Constants.FlickrParameterKeys.Lat: pin.latitude as Any,
Constants.FlickrParameterKeys.Lon: pin.longitude as Any,
Constants.FlickrParameterKeys.PerPage: Constants.FlickrParameterValues.PerPage,
Constants.FlickrParameterKeys.Page: page
]
taskForGetImages(methodParameters: methodParameters, latitude: pin.latitude, longitude: pin.longitude) (results, error) in
if let error = error
completionHandlerForGetImages(false, "There was an error getting the images: \(error)")
else
// Create a dictionary from the data:
/* GUARD: Are the "photos" and "photo" keys in our result? */
if let photosDictionary = results![Constants.FlickrResponseKeys.Photos] as? [String:AnyObject], let photoArray = photosDictionary[Constants.FlickrResponseKeys.Photo] as? [[String:AnyObject]]
for photo in photoArray
let image = Images(context: CoreDataStack.sharedInstance().context)
// GUARD: Does our photo have a key for 'url_m'?
guard let imageUrlString = photo[Constants.FlickrResponseKeys.MediumURL] as? String else
completionHandlerForGetImages(false, "Unable to find key '\(Constants.FlickrResponseKeys.MediumURL)' in \(photo)")
return
// Get metadata
let imageURL = URL(string: imageUrlString)!
let title = photo["title"] as? String ?? ""
// Assign the metadata to images NSManagedObject
image.imageURL = String(describing: imageURL)
image.pin = pin
image.title = title
CoreDataStack.sharedInstance().context.insert(image)
CoreDataStack.sharedInstance().saveContext()
completionHandlerForGetImages(true, nil)
func withBigImage(_ urlString: String?, completionHandler handler: @escaping (_ image:UIImage) -> Void)
DispatchQueue.global(qos: .userInitiated).async () -> Void in
if let url = URL(string: urlString!)
if let imgData = try? Data(contentsOf: url)
if let img = UIImage(data: imgData)
performUIUpdatesOnMain
let image = Images(context: CoreDataStack.sharedInstance().context)
image.imageData = imgData as NSData
CoreDataStack.sharedInstance().saveContext()
performUIUpdatesOnMain
handler(img)
还有我的 cellForItemAt 方法:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath as IndexPath) as! CollectionViewCell
cell.activityIndicator.hidesWhenStopped = true
cell.activityIndicator.activityIndicatorViewStyle = .whiteLarge
cell.activityIndicator.center = CGPoint(x: cell.frame.size.width/2, y: cell.frame.size.height/2)
performUIUpdatesOnMain
cell.activityIndicator.startAnimating()
let image = self.fetchedResultsController.object(at: indexPath)
if image.imageData == nil
print("Image data doesn't exist")
FlickrClient.sharedInstance().withBigImage(image.imageURL, completionHandler: (cellImage) in
performUIUpdatesOnMain
cell.imageView.image = cellImage
cell.activityIndicator.stopAnimating()
)
else
print("Image data exists")
performUIUpdatesOnMain
cell.imageView.image = image.image
cell.activityIndicator.stopAnimating()
if let _ = self.selectedIndexes.index(of: indexPath)
cell.imageView.alpha = 0.5
else
cell.imageView.alpha = 1.0
return cell
*注意: performUIUpdatesOnMain 是我的 GCD DispatchQueue.main.async 方法。
我认为这可能是后台和主队列问题的问题,但我不确定如何解决。
【问题讨论】:
【参考方案1】:如果图像数据被存储,您是否检查过您的 sqlite 数据库?如果您正在使用模拟器,则可以使用DB Browser for SQLite。 您真的需要将图像存储在 coredata 中吗,更好的方法是仅将图像路径/元数据存储在 coredata 中,并将纯图像存储在文件系统中。
无论如何。如果sqlite数据库没有数据写入,可以尝试使用UIImageJPEGRepresentation
转换图片并保存转换后的数据
let imgData = UIImageJPEGRepresentation(img!, 1)
【讨论】:
我正在为一个类制作这个应用程序,并将 imageData 保存在 Core Data 中是一项要求。实际上,我已经让它与除该功能之外的所有功能一起使用。我见过你上面提到的这种方法......是建议我应该下载imageData,将其转换为UIImage,然后将UIImage转回imageData以保存它?当我第一次从 URL 中提取 imageData 时,似乎我应该能够将 imageData 保存到 Core Data,不是吗?以上是关于如何将 imageData 保存到 NSManagedObject 属性的主要内容,如果未能解决你的问题,请参考以下文章
将UIImage转换为NSData并在Swift中转换回UIImage?