Cornelius
Cornelius

Reputation: 4264

AFIncrementalStore handling non-rest response with relationships

I am using AFIncrementalStore to fetch data from a webservice and persist it in a SQLite database through app launches.

The webservice doesn't follow REST standards, so I can't use AFRestClient but have a subclass of AFHTTPClient that implements AFIncrementalStoreHTTPClient.

All works well for the first level of data, but the response I am handling also contains arrays with other objects:

[
{
    "PID": 6,
    "Actors": [
        {
            "PID": 0,
            "Name": "Kiefer Sutherland"
        },
        {
            "PID": 0,
            "Name": "Carlos Bernard"
        },
        {
            "PID": 0,
            "Name": "Mary Lynn Rajskub"
        },
        {
            "PID": 0,
            "Name": "Jude Ciccolella"
        },
        {
            "PID": 0,
            "Name": "Glenn Morshower"
        },
        {
            "PID": 0,
            "Name": "Tanya Wright"
        },
        {
            "PID": 0,
            "Name": "Alberta Watson"
        },
        {
            "PID": 0,
            "Name": "Eric Balfour"
        },
        {
            "PID": 0,
            "Name": "Regina King"
        },
        {
            "PID": 0,
            "Name": "Peter MacNicol"
        },
        {
            "PID": 0,
            "Name": "Marisol Nichols"
        },
        {
            "PID": 0,
            "Name": "Jayne Atkinson"
        },
        {
            "PID": 0,
            "Name": "Carlo Rota"
        },
        {
            "PID": 0,
            "Name": "Janeane Garofalo"
        },
        {
            "PID": 0,
            "Name": "Rhys Coiro"
        },
        {
            "PID": 0,
            "Name": "Jeffrey R. Nordling"
        },
        {
            "PID": 0,
            "Name": "Bob Gunton"
        },
        {
            "PID": 0,
            "Name": "Colm Feore"
        },
        {
            "PID": 0,
            "Name": "Annie Wersching"
        },
        {
            "PID": 0,
            "Name": "Cherry Jones"
        },
        {
            "PID": 0,
            "Name": "D.B. Woodside"
        },
        {
            "PID": 0,
            "Name": "James Morrison"
        },
        {
            "PID": 0,
            "Name": "Gregory Itzin"
        },
        {
            "PID": 0,
            "Name": "Jean Smart"
        },
        {
            "PID": 0,
            "Name": "Louis Lombardi"
        },
        {
            "PID": 0,
            "Name": "Sarah Clarke"
        },
        {
            "PID": 0,
            "Name": "Roger R. Cross"
        },
        {
            "PID": 0,
            "Name": "Reiko Aylesworth"
        },
        {
            "PID": 0,
            "Name": "Elisha Cuthbert"
        },
        {
            "PID": 0,
            "Name": "Lana Parrilla"
        },
        {
            "PID": 0,
            "Name": "Kim Raver"
        },
        {
            "PID": 0,
            "Name": "Dennis Haysbert"
        },
        {
            "PID": 0,
            "Name": "Leslie Hope"
        },
        {
            "PID": 0,
            "Name": "Xander Berkeley"
        },
        {
            "PID": 0,
            "Name": "James Badge Dale"
        },
        {
            "PID": 0,
            "Name": "Penny Johnson Jerald"
        },
        {
            "PID": 0,
            "Name": "Sarah Wynter"
        },
        {
            "PID": 0,
            "Name": "Shohreh Aghdashloo"
        },
        {
            "PID": 0,
            "Name": "Laura Harris"
        },
        {
            "PID": 0,
            "Name": "David Anders"
        },
        {
            "PID": 0,
            "Name": "Katee Sackhoff"
        },
        {
            "PID": 0,
            "Name": "Mykelti Williamson"
        },
        {
            "PID": 0,
            "Name": "Anil Kapoor"
        },
        {
            "PID": 0,
            "Name": "Chris Diamantopoulos"
        },
        {
            "PID": 0,
            "Name": "John Boyd"
        },
        {
            "PID": 0,
            "Name": "Freddie Prinze Jr."
        }
    ],
    "Artwork": [
        {
            "Filetype": "jpg",
            "Id": "291317649",
            "Offset": 0,
            "Rating": 1,
            "Type": 2
        },
        {
            "Filetype": "jpg",
            "Id": "-419936433",
            "Offset": 1,
            "Rating": 1,
            "Type": 2
        },
        {
            "Filetype": "jpg",
            "Id": "-431274161",
            "Offset": 2,
            "Rating": 1,
            "Type": 2
        },
        {
            "Filetype": "jpg",
            "Id": "117154410",
            "Offset": 0,
            "Rating": 1,
            "Type": 3
        },
        {
            "Filetype": "jpg",
            "Id": "1179197275",
            "Offset": 1,
            "Rating": 1,
            "Type": 3
        },
        {
            "Filetype": "jpg",
            "Id": "-1912564655",
            "Offset": 2,
            "Rating": 1,
            "Type": 3
        },
        {
            "Filetype": "jpg",
            "Id": "885093068",
            "Offset": 0,
            "Rating": 1,
            "Type": 1
        }
    ],
    "ContentRating": "TV-14",
    "DateAdded": "/Date(-3600000+0100)/",
    "EpisodeCount": 192,
    "ExternalId": [
        {
            "Id": "76290",
            "Site": "TVDB"
        },
        {
            "Id": "tt0285331",
            "Site": "IMDB"
        }
    ],
    "Genres": [
        "Action and Adventure",
        "Drama"
    ],
    "Id": "76290",
    "IsProtected": false,
    "Rating": 8.9,
    "Title": "24",
    "UnwatchedEpisodeCount": 0,
    "Year": 2001
}
]

In my datamodel I have an entity TVShow that has properties for the id, rating, title, unwatched episodes, episode count and the year. I am mapping those in my HTTPClient in attributesForRepresentation:ofEntity:fromResponse: like this:

if ([entity.name isEqualToString:@"TVShow"]) {
    [mutableAttributes setValue:[representation valueForKey:@"Id"] forKey:@"showId"];
    [mutableAttributes setValue:[representation valueForKey:@"Title"] forKey:@"title"];
    [mutableAttributes setValue:[NSNumber numberWithInteger:[[representation valueForKey:@"Year"] integerValue]] forKey:@"year"];
    [mutableAttributes setValue:[NSNumber numberWithInteger:[[representation valueForKey:@"EpisodeCount"] integerValue]] forKey:@"episodeCount"];
    [mutableAttributes setValue:[NSNumber numberWithInteger:[[representation valueForKey:@"UnwatchedEpisodeCount"] integerValue]] forKey:@"unwatchedEpisodeCount"];
}

My thought was that I could add another entity Artwork with an one-to-many relationship between TVShow and Artwork, but I don't know how to map and define that. All my tries in the last days resulted in crashes (probably due to a lack of understanding of CoreData).

Any help with that would be greatly appreciated, as I would really like to use AFIS in my app.

Thanks!

Upvotes: 2

Views: 641

Answers (1)

Daniel Eggert
Daniel Eggert

Reputation: 6715

(1st part isn't really an answer)

I would discourage using the NSIncrementalStore unless you know Core Data very well. It is far easier and way less error prone to simply pull JSON over the wire with e.g. AFNetwork and then insert those objects into a normal Core Data stack backed by an SQLite store. You'll probably find that a more feasible solution.

(2nd part)

That said, you can get it to work, but you'd have to do some tricks, since you don't have any id or other unique identifier for the Artwork objects. You'd have to put the into the cache (the 2nd Core Data stack that AFIncrementalStore is using) and then put the NSManagedObjectIDs for those objects into the TVShow's values for that relationship.

Upvotes: 1

Related Questions