Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestKit delete old data from core data using setObjectMapping

I have reviewed the answer at RestKit Object Mapping: difficulty using setObjectMapping:forResourcePathPattern:withFetchRequestBlock and it is working, but only for the last mapping. Example:

RKManagedObjectMapping *audioSourcesMapping = [RKManagedObjectMapping mappingForEntityWithName:kEntityAudioSources inManagedObjectStore:objectStore];
[audioSourcesMapping mapKeyPath:@"icon" toAttribute:@"icon"];
[audioSourcesMapping mapKeyPath:@"name" toAttribute:@"name"];
[audioSourcesMapping mapKeyPath:@"notes" toAttribute:@"notes"];
[audioSourcesMapping mapKeyPath:@"section" toAttribute:@"section"];
[audioSourcesMapping mapKeyPath:@"url" toAttribute:@"url"];
audioSourcesMapping.primaryKeyAttribute = @"name";
[wsiObjectManager.mappingProvider registerMapping:audioSourcesMapping withRootKeyPath:@"winSystem.winSystemAudioSources.winSystemAudioSource"];


[wsiObjectManager.mappingProvider setObjectMapping:audioSourcesMapping forResourcePathPattern:kWinSystemInfoXml 
                             withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {
                                 return [AudioSources fetchRequest];
                             }];


RKManagedObjectMapping *eventsMapping = [RKManagedObjectMapping mappingForEntityWithName:kEntityEvents inManagedObjectStore:objectStore];
[eventsMapping mapKeyPath:@"contact" toAttribute:@"contact"];
[eventsMapping mapKeyPath:@"startDate" toAttribute:@"startDate"];
[eventsMapping mapKeyPath:@"endDate" toAttribute:@"endDate"];
[eventsMapping mapKeyPath:@"icon" toAttribute:@"icon"];
[eventsMapping mapKeyPath:@"location" toAttribute:@"location"];
[eventsMapping mapKeyPath:@"name" toAttribute:@"name"];
[eventsMapping mapKeyPath:@"notes" toAttribute:@"notes"];
[eventsMapping mapKeyPath:@"section" toAttribute:@"section"];
[eventsMapping mapKeyPath:@"url" toAttribute:@"url"];
eventsMapping.primaryKeyAttribute = @"name";
[wsiObjectManager.mappingProvider registerMapping:eventsMapping withRootKeyPath:@"winSystem.winSystemEvents.winSystemEvent"];    


[wsiObjectManager.mappingProvider setObjectMapping:eventsMapping forResourcePathPattern:kWinSystemInfoXml 
                             withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {
                                 return [Events fetchRequest];
                             }];

All the mappings are working great. When the source xml is updated, new records are created. When I delete a Event, it gets deleted. When I delete an AudioSource it does not get deleted.

If I remove the second setObjectMapping:forResourcePathPattern:withFetchRequestBlock then the AudioSource is deleted correctly, but the deleted Event is not. I have 4 mappings I am working with in this xml file.

It's like the last call to setObjectMapping:forResourcePathPattern:withFetchRequestBlock wins.

My workaround is to use the setObjectMapping:forResourcePathPattern:withFetchRequestBlock on the mapping that changes most often (in this case the Events), and add a button that invalidates cache, empty the database, and update. There must be something simple I am missing.

Xcode: 4.3.3 RestKit: 0.10.1

Sample xml file. This all loads fine, but only removes from core data the mapping using the last setObjectMapping:forResourcePathPattern:withFetchRequestBlock

    <?xml version="1.0" encoding="UTF-8"?>
    <winSystem>
        <winSystemAudioSources>
            <winSystemAudioSource
                icon="audio.png"
                name="Hub Audio"
                notes="Cleaner Sound. Audio is delayed by about 30 seconds. This is a great way to see if you are making into the WIN System."
                section=" WIN System"
                url="http://stream.winsystem.org:443/2560.mp3" />
        </winSystemAudioSources>
        <winSystemEvents>
            <winSystemEvent
                contact=""
                endDate=""
                icon="net.png"
                location="WIN System reflector 9100"
                name="Insomniac Trivia Net"
                notes="Every Night @ 23:00 PT - WIN System reflector 9100. Join the Yahoo! group: http://groups.yahoo.com/group/insomniac-net/join"
                section="Ham Nets"
                startDate=""
                url="http://www.thedeanfamily.com/WinSystem/InsomniacNet.htm" />
        </winSystemEvents>
        <winSystemLinks>
            <winSystemLink
                icon="winsystem.png"
                name=" WIN System Home Page"
                notes="The WIN System Home Page"
                section=" WIN System"
                type="web"
                url="http://www.winsystem.org/" />
        </winSystemLinks>
        <winSystemRepeaters>
            <winSystemRepeater
                callSign="K6JSI"
                freqOffsetPl="448.800* (-) 100.0"
                grouping="winsystem"
                latitudeDefault=""
                locationElevation="Shorty's house, 560' + 53'"
                longitudeDefault=""
                node="A 01330"
                repeaterId="1"
                serviceArea="Vista"
                serviceState="CA" />
        </winSystemRepeaters>
    </winSystem>
like image 880
Kent Avatar asked Jul 11 '12 20:07

Kent


1 Answers

I haven't used Managed Objects before but the first thing to do here is to activate the restkit log over object mapping, network request and core data so you can check what is restkit getting from the server, how the mapping is working and how is fetching things from CD, so try the following:

//This can be added in your app delegate
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
RKLogConfigureByName("RestKit/CoreData", RKLogLevelTrace);

Looking at your code, you are using the same Path for both mappings in here:

// forResourcePathPattern:kWinSystemInfoXml
[wsiObjectManager.mappingProvider setObjectMapping:audioSourcesMapping forResourcePathPattern:kWinSystemInfoXml 
                         withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {
                             return [AudioSources fetchRequest];
                         }];

// forResourcePathPattern:kWinSystemInfoXml
[wsiObjectManager.mappingProvider setObjectMapping:eventsMapping forResourcePathPattern:kWinSystemInfoXml 
                         withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {
                             return [Events fetchRequest];
                         }];

I think this can be causing a conflict, because RK choose one of both resources to be mapped to that path, so you should:

  1. Debug what is Core Data doing.
  2. Try to use a mapping for key path approach instead of resource path pattern, so RK doesn't get messed up, you need to define different ways to map each kind of object, right now I think the first one is being overwritten.

If that doesn't work you should post how are you deleting things in your code, maybe post all the code from your view controller. What can be happening is that the calls are being overwritten by your code somewhere. Are you using blocks?.

Hope that helps!

like image 149
clopez Avatar answered Sep 22 '22 23:09

clopez