如何将imageData保存到NSManagedObject属性

时间:2018-01-23 02:51:35

标签: ios swift core-data grand-central-dispatch

我的应用程序从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方法。

我认为这可能是后台和主要队列问题的问题,但我不确定如何解决它。

1 个答案:

答案 0 :(得分:0)

如果存储了图像数据,您是否检查了sqlite数据库?如果您正在使用模拟器,则可以使用DB Browser for SQLite。 你真的需要将你的图像存储在coredata中,更好的方法是只存储coredata中的图像路径/元数据和文件系统上的普通图像。

反正。如果没有数据写入sqlite数据库,您可以尝试使用UIImageJPEGRepresentation转换图像并保存转换后的数据

let imgData = UIImageJPEGRepresentation(img!, 1)