Objective-C - 根据用户输入的查询

时间:2015-05-26 14:47:23

标签: objective-c xcode cllocation mklocalsearch

我想允许用户搜索街道名称并将结果显示在UITableView中。 目前该地区并不重要,它可以来自任何地区。

我在搜索中找不到任何相关示例,我不知道是否应该使用CLLocation或MKLocalSearch。

基于docs,我应该使用MKLocalSearch:

  

虽然本地搜索和地理编码类似,但他们支持   不同的用例。如果要在两者之间进行转换,请使用地理编码   地图坐标和结构化地址,例如地址簿   地址。如果要查找一组位置,请使用本地搜索   与用户的输入相匹配。

但是我尝试了两种方法,它只给了我一个结果(即使 - 虽然有一个NSArray返回。

这是CLGeocoder方法:

CLGeocoder *geocoding = [[CLGeocoder alloc] init];
[geocoding geocodeAddressString:theTextField.text completionHandler:^(NSArray *placemarks, NSError *error) {
    if (error) {
        NSLog(@"%@", error);
    } else {
        NSLog(@"%i", [placemarks count]);
        for(CLPlacemark *myStr in placemarks) {
            NSLog(@"%@", myStr);
    }
    }
}];

这是我的MKLocalSearch尝试:

MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = theTextField.text;
request.region = self.region;

localSearch = [[MKLocalSearch alloc] initWithRequest:request];

[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error){

    if (error != nil) {
        [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Map Error",nil)
                                    message:[error localizedDescription]
                                   delegate:nil
                          cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
        return;
    }

    if ([response.mapItems count] == 0) {
        [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No Results",nil)
                                    message:nil
                                   delegate:nil
                          cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
        return;
    }
    self.streets = response;
    [self.streetsTableView reloadData];
}];

在某些情况下,MKLocalSearch似乎会返回超过1个响应,但这些与非街道名称搜索的地方有关。

提前致谢。

3 个答案:

答案 0 :(得分:4)

这是我能得到的最接近的。这涉及使用google places API Web Service

注意:您可以使用他们的Google Maps API等。我相信还有其他方法可以从各种Google API获取此信息。

 NSURL *googlePlacesURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%@&location=%f,%f&sensor=true&key=API_KEY", formattedSearchText, location.coordinate.latitude,
                                                   location.coordinate.longitude]];

响应是一个JSON对象。将其转换为字典。

 NSDictionary *response = [NSJSONSerialization JSONObjectWithData:_googlePlacesResponse
                                                                    options:NSJSONReadingMutableContainers error:&error];

if([[response objectForKey:@"status"] isEqualToString:@"OK"])
{
    NSArray *predictions = [response objectForKey:@"predictions"];
    for(NSDictionary *prediction in predictions)
    {
        NSArray *addressTypes = [prediction objectForKey:@"types"];
        if([addressTypes containsObject:@"route"])
        {
            //This search result contains a street name. 
            //Now get the street name.
            NSArray *terms = [prediction objectForKey:@"terms"];
            NSDictionary *streetNameKeyValuePair = [terms objectAtIndex:0];
            NSLog(@"%@",[streetNameKeyValuePair objectForKey@"value"]);
        }
    }
}

可能types似乎是

  • 路线 - >街道名称
  • 地点 - >城市/位置名称
  • 政治 - >国家等
  • 地理编码 - > lat / long available
  • 您可以使用包含predictions作为地址类型的route填充表格视图。这可行。

    答案 1 :(得分:2)

    CLGeocoder只返回地址格式。 在你的代码中将其打包并使用mapitems的内容

    MKLocalSearchRequest *request = [MKLocalSearchRequest new];
    request.naturalLanguageQuery = @"Pizza";
    request.region = MKCoordinateRegionMake(location.coordinate, MKCoordinateSpanMake(.01, .01));
    MKLocalSearch *search = [[MKLocalSearch alloc]initWithRequest:request];
    [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
        NSArray *mapItems = response.mapItems;
        for (MKMapItem *mapItem in mapItems) {
            MKPointAnnotation *point = [MKPointAnnotation new];
            point.coordinate = mapItem.placemark.coordinate;`
        }
    }];
    

    答案 2 :(得分:1)

    返回的数组包含str = "172.0.254.1.22.33.44.55" tadip str #=> IPAddr::InvalidAddressError: invalid address ip str #=> 12394185455143300151 ,您可以迭代数组以提取所有mapItems,如下所示:

    mapItems

    每个myMatchingItems = [[NSMutableArray alloc] init]; for (MKMapItem *item in response.mapItems){ [myMatchingItems addObject:item]; } 都包含找到的位置的街道。