IOS, finding a remote server using RestKit

I am working on an application where I want to do a remote search on a server. I want RestKit to store the received data in a database. First I do a local search (which currently works), then I want to do a remote search, and then update the table view with the new results.

I am having two problems: 1. What my mapping should look like and 2. json returns an array with two different types of objects.

The url is as follows:

search.json?search=[search string]

The returned JSON looks like this:

[
  {
    "event": {
      "id": 2,
      [...]
  },
  {
    "news": {
      "id": 16,
      [...]
  }

Where events and news are two types of objects.

In my application, I have three models: Post (abstract object and superclass) NewsPost (subclass for publication) and event (subclass for publication).

My mappings are as follows:

RKManagedObjectMapping* newsMapping = [RKManagedObjectMapping mappingForClass:[NewsPost class] inManagedObjectStore:objectManager.objectStore];   
newsMapping.primaryKeyAttribute = @"newsId";
newsMapping.rootKeyPath = @"news";
[newsMapping mapKeyPath:@"id" toAttribute:@"newsId"];

RKManagedObjectMapping *eventMapping = [RKManagedObjectMapping mappingForClass:[CalendarEvent class] inManagedObjectStore:objectManager.objectStore];
eventMapping.primaryKeyAttribute = @"calendarId";
eventMapping.rootKeyPath = @"calendars";
[eventMapping mapKeyPath:@"id" toAttribute:@"calendarId"];

// These two works. 
[objectManager.mappingProvider setObjectMapping:newsMapping forResourcePathPattern:@"/package_components/1/news"];
[objectManager.mappingProvider setObjectMapping:eventMapping forResourcePathPattern:@"/package_components/1/calendars"];

// I don't know how these should look/work. 
// Since the search word can change
[objectManager.mappingProvider setObjectMapping:eventMapping forResourcePathPattern:@"/package_components/1/search\\.json?search="];
[objectManager.mappingProvider setObjectMapping:newsMapping forResourcePathPattern:@"/package_components/1/search\\.json?search="];

( ):

- (void)setUpSearch
{
    if (self.searchField.text != nil) {

        [self.posts removeAllObjects];
        [self.events removeAllObjects];
        [self.news removeAllObjects];

        // Search predicates.
        // Performs local search.
        NSPredicate *contactNamePredicate = [NSPredicate predicateWithFormat:@"contactName contains[cd] %@", self.searchField.text];
        NSPredicate *contactDepartmentPredicate = [NSPredicate predicateWithFormat:@"contactDepartment contains[cd] %@", self.searchField.text];
        [...]

        NSArray *predicatesArray = [NSArray arrayWithObjects:contactNamePredicate, contactDepartmentPredicate, contactEmailPredicate, contactPhonePredicate, linkPredicate, titlePredicate, nil];

        NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicatesArray];

        self.posts = [[Post findAllWithPredicate:predicate] mutableCopy];

        if (self.posts.count != 0) {
            self.noResultsLabel.hidden = YES;
            for (int i = 0; i < self.posts.count; i++) {
                Post * post = [self.posts objectAtIndex:i];
                if (post.calendarEvent == YES) {
                    [self.events addObject:post];
                } else {
                    [self.news addObject:post];
                }
            }
        } 

        // reload the table view
        [self.tableView reloadData];

        [self performRemoteSearch];
    }
}

- (void)search
{    
    [self setUpSearch];
    [self hideKeyboard];
    [self performRemoteSearch];
}


- (void)performRemoteSearch
{
    // Should load the objects from JSON    
    // Note that the searchPath can vary depending on search text. 
    NSString *searchPath = [NSString stringWithFormat:@"/package_components/1/search.json?search=%@", self.searchField.text];
    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    [objectManager loadObjectsAtResourcePath:searchPath delegate:self];
}

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects
{
    // This never gets called. 

    // Should update my arrays and then update the tableview, but it never gets called. 
    // Instead I get Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "Could not find an object mapping for keyPath: ''
}

, , .

+5
2

Managed Objects, , , restkit , , . p >

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

, JSON, , , . , :

RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"author" toAttribute:@"author"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];

[[RKObjectManager sharedManager].mappingProvider setMapping:articleMapping forKeyPath:@"articles"];

, :

- (void)loadArticles {
    [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/articles" delegate:self];
}

- , RestKit , .

- , , .

+3

, =)

1.

. ? ?

2. json .

(.. , ) ? , dynamic nesting.

(.. ) ( ), dynamic object mapping .

JSON, , RestKit.

- , JSON root_key_ .

googling RestKit json , rootKeyPaths. JSON , :

{
  "news" : [
    {
      "id" : 1,
      "title" : "Mohawk guy quits"
    },
    {
      "id" : 2,
      "title" : "Obama gets mohawk"
    }
  ],
  "events" : [
    {
      "id" : 1,
      "name" : "testing"
    },
    {
      "id" : 2,
      "name" : "testing again"
    }
  ]
}

, 100% . , API , , .

-

// Make a NS dictionary and use stringByAppendingQueryParameters

NSDictionary *searchParams = [NSDictionary dictionaryWithKeysAndObjects:
                                @"query",@"myQuery", 
                                @"location",@"1.394168,103.895473",
                                nil];

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:[@"/path/to/resource.json"  stringByAppendingQueryParameters:searchParams] delegate:objectLoaderDelegate];

- "" objectLoader

, Coredata. , NSPredicate, .

, RestKit loadObjects... , . "". NSPredicates.

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { 
  // Do some processing here on the array of returned objects or cede control to a method that 
  // you've built for the search, like the above method.
}

, , , /, Coredata. .

, .

+1

All Articles