10

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>
Community
  • 1
  • 1
Kent
  • 1,374
  • 1
  • 15
  • 29
  • 1
    What does your source XML look like? Does it have , and all as nested tags? – Steven Hepting Aug 19 '12 at 01:52
  • @Steven Hepting - I have edited the question to add a sample of the xml file. Thank you for asking! – Kent Aug 20 '12 at 03:21
  • How are you deleting things? can you add that code? probably one call is being overwritten. Check my response so you can debug the behavior of core data. – clopez Aug 23 '12 at 14:07
  • @clopez - If I remove one of the xml elements - say, one of the 's. And add a few new ones. The new ones are added, but the removed one is still in core data. – Kent Aug 24 '12 at 14:11

1 Answers1

2

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!

clopez
  • 4,372
  • 3
  • 28
  • 42
  • I have the log message output. I do not delete from the code. When I edit the xml and remove an element, at next update the elements should be removed. It does work for the last `mappingProvider`. The only blocks I am using are in the above in the `withFetchRequestBlock`. I'll look into the mapping for key approach and get back on the results. Thank you. – Kent Aug 24 '12 at 14:17
  • And what is the output of the core data log when you do such operations? – clopez Aug 24 '12 at 14:57