Géocode par lots MKLocalSearchResponse

J'ai une configuration de search qui affiche la réponse d'un MKLocalSearchRequest dans UITableVIew

Je veux nettoyer toutes les réponses de la réponse de chaque search. Voici mon tir à accomplir jusqu'à présent, inspiré par ce post Multiple Locations sur la carte (en utilisant MKMapItem et CLGeocoder)

Voici mon code.

@interface ViewController () <UISearchBarDelegate,UISearchDisplayDelegate,UITextFieldDelegate> @property (nonatomic, strong) UISearchDisplayController *searchController; @property (nonatomic, strong) UISearchBar *searchBar; @property (nonatomic, strong) MKLocalSearch *localSearch; @property (nonatomic, strong) MKLocalSearchResponse *localSearchResponse; @property (nonatomic, strong) NSArray *dirtyResponseArray; @property (nonatomic, strong) NSMutableArray *geocodedResultsArray; @end @implementation ViewController -(void)startSearch:(NSSsortingng *)searchSsortingng { if (self.localSearch.searching) [self.localSearch cancel]; MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.naturalLanguageQuery = searchSsortingng; request.region = MKCoordinateRegionMake(self.currentLocation.coordinate, self.mapView.region.span); MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error){ if (error != nil) return; else { self.dirtyResponseArray = response.mapItems; [self operation]; [self.searchController.searchResultsTableView reloadData]; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; } [self.searchDisplayController.searchResultsTableView reloadData]; }; if (self.localSearch != nil) self.localSearch = nil; self.localSearch = [[MKLocalSearch alloc] initWithRequest:request]; [self.localSearch startWithCompletionHandler:completionHandler]; } -(void)operation { CLGeocoder *geocoder = [[CLGeocoder alloc]init]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSOperation *finalCompletionOperation = [NSBlockOperation blockOperationWithBlock:^{ [MKMapItem openMapsWithItems:self.geocodedResultsArray launchOptions:nil]; NSLog(@"Local Search Response To use in tableview =================== %@", self.geocodedResultsArray); }]; NSOperation *previousCompletionHandler = nil; //Issue is probably right here. How should I handle the MKMapItem in the array? //NSSsortingng *address = [self.dirtyResponseArray valueForKey:@"address"][@"formattedAddress"]; ?? for (NSSsortingng *address in self.dirtyResponseArray) { NSBlockOperation *geocodeRequest = [[NSBlockOperation alloc] init]; if (previousCompletionHandler) [geocodeRequest addDependency:previousCompletionHandler]; NSBlockOperation *geocodeCompletionHandler = [[NSBlockOperation alloc] init]; [finalCompletionOperation addDependency:geocodeCompletionHandler]; [geocodeRequest addExecutionBlock:^{ [geocoder geocodeAddressSsortingng:address completionHandler:^(NSArray *placemarks, NSError *error) { [geocodeCompletionHandler addExecutionBlock:^{ if (error) NSLog(@"%@", error); else if ([placemarks count] > 0) { CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0]; MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:geocodedPlacemark.location.coordinate addressDictionary:geocodedPlacemark.addressDictionary]; MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark]; [mapItem setName:geocodedPlacemark.name]; [self.geocodedResultsArray addObject:mapItem]; } }]; [queue addOperation:geocodeCompletionHandler]; }]; }]; [queue addOperation:geocodeRequest]; previousCompletionHandler = geocodeCompletionHandler; } [queue addOperation:finalCompletionOperation]; } @end 

Je ne suis pas sûr de savoir comment gérer chaque MKMapItem. En ce moment, il lance cette erreur

  -[MKMapItem length]: unrecognized selector sent to instance 0x7f813c9c6200 

La méthode CLGeocoder , geocodeAddressSsortingng , qui est référencée dans cette autre question, est conçue pour le géoencoding d'une adresse.

Mais vous effectuez un MKLocalSearch dans une région particulière, qui renvoie des objects MKMapItem qui sont déjà géocodés. Par conséquent, vous pouvez entièrement supprimer le code geocodeAddressSsortingng de votre exemple de code.

En fait, ceci explique la source de votre exception, que vous prenez le MKMapItem returnné par MKLocalSearch , et essayez de l'utiliser comme paramètre de string de search de la méthode geocodeAddressSsortingng (qui est seulement utilisée pour searchr des représentations de string d'adresses).

En bout de ligne, faire une search locale et montrer les résultats dans l'application Cartes est beaucoup plus facile que ce que vous avez envisagé ci-dessus. Tout ce que vous devez faire est:

 MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.naturalLanguageQuery = searchSsortingng; request.region = region; MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request]; [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { [MKMapItem openMapsWithItems:response.mapItems launchOptions:nil]; }]; 

Ou, si vous vouliez l'afficher sur votre propre MKMapView , vous pourriez faire quelque chose comme

 MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.naturalLanguageQuery = searchSsortingng; request.region = region; MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request]; [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { for (MKMapItem *item in response.mapItems) { [self.mapView addAnnotation:item.placemark]; } }]; 

En pratique, dans ce dernier exemple où vous affichez des résultats sur votre propre vue de carte, vous pouvez créer votre propre class d'annotations personnalisées afin de mieux contrôler le rendu de la vue d'annotation dans la méthode viewForAnnotation . Mais j'espère que cela illustre l'observation principale, que lorsque vous utilisez MKLocalSearch , vous ne devriez pas utiliser la méthode geocodeAddressSsortingng du tout.