1

我从服务器加载对象列表并使用 ObjectMapper 将它们保存到 Realm。每个对象都包含一个 url,该 url 定义了为对象加载图像的位置。我加载图像并将图像数据保存在领域对象中,这样我就不需要每次都重新加载它。但不幸的是,如果我重新加载数据,图像数据就会丢失。

我使用主键,我的想法是当 JSON. 我担心 ObjectMapper 不会更新 Realm 中的现有对象,而是会覆盖它们。所以图像数据为零,必须从服务器重新获取。我能做些什么来防止这种情况发生吗?

这是我简化的 ObjectMapping 文件:

import Foundation
import ObjectMapper
import RealmSwift

class OverviewItem: PersistentObject {

    override var hashValue : Int {
        get {
            return self.overviewID.hashValue
        }
    }

    dynamic var overviewID: Int = 0
    dynamic var titleDe: String = ""
    dynamic var imageUrl: String = ""
    dynamic var imageData: NSData?

    required convenience init?(_ map: Map) {
        self.init()
    }

    //computed properties
    dynamic var image: UIImage? {
        get {
            return  self.imageData == nil ? nil : UIImage(data: self.imageData!)
        }
        set(newImage){
            if let newImage = newImage, data = UIImagePNGRepresentation(newImage){
                self.imageData = data
            }
            else{
                self.imageData = nil
            }
        }
    }

    //image is a computed property and should be ignored by realm
    override class func ignoredProperties() -> [String] {
        return ["image"]
    }

    override func mapping(map: Map) {
        overviewID <- map["infoid"]
        titleDe <- map["titleDe"]
        imageUrl <- map["imageurl"]
    }

    override class func primaryKey() -> String {
        return "overviewID"
    } 
}

在这里我如何获取图像并更新对象:

 func fetchImage(item: OverviewItem, successHandler: UIImage? ->(), errorHandler: (ErrorType?) -> ()){

        AlamofireManager.Configured
            .request(.GET, item.imageUrl)
            .responseData({ (response: Response<NSData, NSError>) in

                if let error = response.result.error{
                    logger.error("Error: \(error.localizedDescription)")
                    errorHandler(error)
                    return
                }

                if let imageData = response.result.value{

                    successHandler(UIImage(data: imageData))

                    let overviewID = item.overviewID  
                    let queue = NSOperationQueue()
                    let blockOperation = NSBlockOperation {

                        let writeRealm = try! Realm()
                        do{
                            if let itemForUpdate = writeRealm.objects(OverviewItem).filter("overviewID = \(overviewID)").first{
                                try writeRealm.write{
                                    itemForUpdate.imageData = imageData
                                    writeRealm.add(itemForUpdate, update: true)
                                }
                            }
                        }
                        catch let err as NSError {
                            logger.error("Error with realm: " + err.localizedDescription)
                        }  
                    }
                    queue.addOperation(blockOperation)
                }
            })
    }
4

1 回答 1

1

在将对象添加/插入到领域之前,您需要通过主键提取现有图像数据。例如,您可以在一个方法中做到这一点,该方法抽象了 ObjectMapper 的映射,但仍允许提供 Realm 实例。

但总的来说,我不建议为此目的将图像存储在 Realm 本身中。有一些非常好的 图像 缓存框架,它们允许您在磁盘和内存中缓存图像。除了按大小组织缓存外,它们还允许您快速解压缩,并允许您管理到期时间。

于 2016-02-29T14:43:31.253 回答