有没有直接的方法从JSON填充和更新Realm-Xamarin?

时间:2016-10-26 19:21:04

标签: xamarin realm

我正在尝试将带有Realm的Android应用程序移植到Xamarin,因此它也可用于iOS设备。在Android中,我有几个带有一些必要初始数据的JSON文件,例如: cities.json ,我在开头用realm.createOrUpdateAllFromJson(Class<E> clazz, InputStream in)方法导入它,如下所示:

private void loadInitialCities(Realm realm) {
    InputStream stream = context.getAssets().open("data/cities.json");
    realm.createOrUpdateAllFromJson(City.class, stream);
}

我还发现这种方法在以JSON形式从Web服务检索数据时非常有用。

现在使用Xamarin我没有看到任何等效的方法。有没有办法实现这个目标?或者至少是一个从C#中的JSON创建RealmObject的变通方法/工具?

1 个答案:

答案 0 :(得分:2)

我为此做了自己的扩展方法(是的,我也错过了内置的辅助方法)。

以下是我如何做的基本示例:

JSON模型:

[
    {
        "name": "Alabama",
        "abbreviation": "AL"
    },
    {
        "name": "Alaska",
        "abbreviation": "AK"
    },
    ~~~~
]

领域模型:

public class State : RealmObject
{
    public string name { get; set; }
    public string abbreviation { get; set; }
}

Xamarin.Android资产和Newtonsoft流媒体阅读器:

var config = RealmConfiguration.DefaultConfiguration;
config.SchemaVersion = 1;
using (var theRealm = Realm.GetInstance("StackOverflow.realm"))
using (var assetStream = Assets.Open("States.json"))
using (var streamReader = new StreamReader(assetStream))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
    var serializer = new JsonSerializer();
    if (!jsonTextReader.Read() || jsonTextReader.TokenType != JsonToken.StartArray)
        throw new Exception("Bad Json, start of array missing");
    while (jsonTextReader.Read())
    {
        if (jsonTextReader.TokenType == JsonToken.EndArray)
            break;
        var state = serializer.Deserialize<State>(jsonTextReader);
        theRealm.Write(() =>
        {
            var realmState = theRealm.CreateObject<State>();
            realmState.abbreviation = state.abbreviation;
            realmState.name = state.name;
        });
    }
}

更新:我的一种扩展方法:

扩展方法用法:

using (var theRealm = Realm.GetInstance("StackOverflow.realm"))
using (var assetStream = Assets.Open("States.json"))
{
    theRealm.JsonArrayToRealm<State>(assetStream);
}

扩展方法:

Note:这使用AutoMapper复制RealmObject并避免反思,也使用Newtonsoft.Json

public static class RealmDoesJson
{
    public static void JsonArrayToRealm<T>(this Realm realm, Stream stream) where T : RealmObject
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<T, T>();
        });
        using (var streamReader = new StreamReader(stream))
        using (var jsonTextReader = new JsonTextReader(streamReader))
        {
            var serializer = new JsonSerializer();
            if (!jsonTextReader.Read() || jsonTextReader.TokenType != JsonToken.StartArray)
                throw new Exception("MALFORMED JSON, Start of Array missing");
            while (jsonTextReader.Read())
            {
                if (jsonTextReader.TokenType == JsonToken.EndArray)
                    break;
                var jsonObject = serializer.Deserialize<T>(jsonTextReader);
                realm.Write(() => // inside while loop / single object transaction for memory manangement reasons...
                {
                    var realmObject = realm.CreateObject(typeof(T).Name);
                    Mapper.Map<T, T>(jsonObject, realmObject);
                });
            }
        }
    }
}