排序的本地化数据的领域查询问题

时间:2018-11-11 22:25:59

标签: swift database-design localization realm

考虑以下Realm模型:

class Fruit: Object {
    @objc dynamic var name = ""
    let localizations = List<Localization>()

    /** 
        Returns the localized name of the fruit matching the preferred language of the app 
        or self.name if the fruit does not have a localization matching the user preferred language codes. 
    */
    var localizedName: String? {
        guard !Locale.isPreferredLanguageDefaultAppLanguage else { return self.name }

        let preferredLanguagesCodes = Locale.preferredLanguagesCodes
        let localizations = preferredLanguagesCodes.compactMap({ languageCode in Array(self.localizations).filter({ $0.languageCode == languageCode }).first })
        return localizations.first?.localizedName ?? self.name
    }
}

class Localization: Object {
    @objc dynamic var localizedName: String = ""
    @objc dynamic var languageCode: String = ""
}

假设我的数据库中有2个水果(为简单起见,以JSON格式表示):

[
    {
        "name": "Apple",
        "localizations": [
            {
                "localizedName": "Pomme",
                "languageCode": "fr"
            }
        ]
    },
    {
        "name": "Banana",
        "localizations": [
            {
                "localizedName": "Banane",
                "languageCode": "fr"
            }
        ]
    }
]

现在,我想获取数据库中的所有水果,并按其localizedName的字母顺序对其进行排序。

var localizedNameSortingBlock: ((Fruit, Fruit) -> Bool) = {
    guard let localizedNameA = $0.localizedName, let localizedNameB = $1.localizedName else { return false }
    return localizedNameA.diacriticInsensitive < localizedNameB.diacriticInsensitive
}

let sortedFruits = Array(Realm().objects(Fruit.self)).sorted(by: localizedNameSortingBlock)

如果我的设备的首选首选语言是“英语”,我会得到:

  1. 苹果
  2. 香蕉

如果将其设置为“法语”:

  1. 香蕉烷
  2. Pomme

这很简单,但是此解决方案有一个很大的不便之处:

通过将Results<Fruit>集合转换为数组,我失去了通过Realm的通知令牌系统获取实时更新的能力。

问题是,我无法直接在Results集合上使用NSPredicate进行排序,因为localizedName属性是计算属性,因此被Realm忽略。

我考虑过将localizedName的值直接写入name对象的Fruit属性中,但是这样做需要遍历所有水果并在用户更改名称时更改其名称。首选语言。必须有更好的方法。

所以我的问题是:

是否有一种方法可以检索数据库中的所有水果,并按其localizedName对其进行排序,而又不会失去从Realm接收批量更新的功能?

0 个答案:

没有答案