我的应用程序从 Flickr 下载图像并将其显示在 CollectionViewController 中,并将图像保留在 Core Data 中。我试图将 imageData 保存到我的 NSManagedObject 上下文中,但我可以看出我没有正确执行此操作,因为我从未到达 cellForRowAt 函数中逻辑的“else”部分。在哪里以及如何使用 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 方法。
我相信这可能是后台和主队列问题,但我不确定如何解决它。
最佳答案
您是否检查过您的 sqlite 数据库是否存储了图像数据?您可以使用DB Browser for SQLite如果您正在使用模拟器。 您真的需要将图像存储在 coredata 中吗?更好的方法是仅将图像路径/元数据存储在 coredata 中,并将纯图像存储在文件系统中。
无论如何。如果没有数据写入sqlite数据库,您可以尝试使用UIImageJPEGRepresentation
转换图像并保存转换后的数据
let imgData = UIImageJPEGRepresentation(img!, 1)
关于ios - 如何将 imageData 保存到 NSManagedObject 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48393453/