Search code examples
ioscore-dataimportmagicalrecord

Importing relationships with Core Data and Magical Record


I am getting JSON data from a webservice and try to store that in Core Data with Magical Record. I read the great post (and only documentation?) "Importing data made easy" by Saul Mora but I still do not really understand what I need to do to get all data in my entities.

Here is the JSON the web service returns:

{
"ApiVersion": 4,
"AvailableFileSystemLibraries": [
    {
        "Id": 10,
        "Name": "Movie Shares",
        "Version": "0.5.4.0"
    },
    {
        "Id": 11,
        "Name": "Picture Shares",
        "Version": "0.5.4.0"
    },
    {
        "Id": 5,
        "Name": "Shares",
        "Version": "0.5.4.0"
    },
    {
        "Id": 9,
        "Name": "Music Shares",
        "Version": "0.5.4.0"
    }
],
"AvailableMovieLibraries": [
    {
        "Id": 3,
        "Name": "Moving Pictures",
        "Version": "0.5.4.0"
    },
    {
        "Id": 7,
        "Name": "MyVideo",
        "Version": "0.5.4.0"
    }
],
"AvailableMusicLibraries": [
    {
        "Id": 4,
        "Name": "MyMusic",
        "Version": "0.5.4.0"
    }
],
"AvailablePictureLibraries": [
    {
        "Id": 8,
        "Name": "Picture Shares",
        "Version": "0.5.4.0"
    }
],
"AvailableTvShowLibraries": [
    {
        "Id": 6,
        "Name": "MP-TVSeries",
        "Version": "0.5.4.0"
    }
],
"DefaultFileSystemLibrary": 5,
"DefaultMovieLibrary": 3,
"DefaultMusicLibrary": 4,
"DefaultPictureLibrary": 0,
"DefaultTvShowLibrary": 6,
"ServiceVersion": "0.5.4"
}

The entities I want to store that data in look like this:

Entities

There is also a Server entity with a 1:1 relationship to ServerInfo.

What I want to do:

  • Store basic data (ApiVersion, ...) in ServerInfo. This I already got to work.
  • Store each object in AvailableXYLibraries in BackendLibrary (1:n relationship from ServerInfo).
    • Set type based on the XY part of AvailableXYLibraries, for example "movie" for AvailableMovieLibraries.
    • Set defaultLibrary to true if this library is referenced by DefaultXYLibrary.
    • Set providerId to servername + LibraryId as there are multiple servers that can have BackendLibraries with the same numeric ID.

Is this possible with Magical Record? I guess I need to implement some of the import hooks and set some user info keys, but everything I read doesn't really tell me where to set what user info key or implement which method where and how.

I hope this made sense and that you can give me some hints :) Thanks!


Solution

  • The structure of this data is quite a bit different from your Core Data model. What you'll most likely have to do is iterate a bit on the dictionary. That is, there are various collections of library data, eg. FileSystemLibraries, AvailableMovieLibraries, etc. You'll have to get the array out of those keys, and then map your entities as I described in the article. In order to launch the process, you'll have to call

    [BackendLibrary importFromArray:arrayFromDownloadedDictionary];
    

    where the arrayFromDownloadedDictionary is each array in the example dictionary you've posted. Once you give the array to MagicalRecord, and provided the proper field mapping, MagicalRecord will then import and create all the entities for you at that point.

    Make sure you map "Id" to BackendLibary.id, "Name" to BackendLibrary.name, and "Version" to BackendLibrary.version