我的应用程序从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方法。
我认为这可能是后台和主要队列问题的问题,但我不确定如何解决它。
答案 0 :(得分:0)
如果存储了图像数据,您是否检查了sqlite数据库?如果您正在使用模拟器,则可以使用DB Browser for SQLite。 你真的需要将你的图像存储在coredata中,更好的方法是只存储coredata中的图像路径/元数据和文件系统上的普通图像。
反正。如果没有数据写入sqlite数据库,您可以尝试使用UIImageJPEGRepresentation
转换图像并保存转换后的数据
let imgData = UIImageJPEGRepresentation(img!, 1)