Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8461213
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T13:49:05+00:00 2026-06-10T13:49:05+00:00

I expect once clicking the toolbar button like cafe, cafes will show in the

  • 0

I expect once clicking the toolbar button like “cafe”, cafes will show in the visible map region. Data are fetched from Google Places API. Everything works fine except pins don’t display after clicking the button.

A latency is expected here for sure. Yet i do the fetch in a background queue and puts up a spinning wheel while waiting, and the spinning wheel hides when fetching and parsing is done. So I am quite sure the data is there at the moment that spinning wheel disappears. But the pins don’t show up until I scroll the map.

I figure that scrolling map only triggers mapView:regionDidChangeAnimated:. But I can’t figure out how it relates the problem. Can anyone help?

The source code of ViewController.m, where pretty much everything happens.

#import "ViewController.h"
#import "MapPoint.h"
#import "MBProgressHUD.h"

#define kGOOGLE_API_KEY @"AIzaSyCHqbAoY7WCL3l7x188ZM4ciiTixejzQ4Y"
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)



@interface ViewController () <CLLocationManagerDelegate, MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property int currentDist;
@property CLLocationCoordinate2D currentCentre;
@end

@implementation ViewController
@synthesize mapView = _mapView;
@synthesize locationManager = _locationManager;
@synthesize currentDist = _currentDist;
@synthesize currentCentre = _currentCentre;

- (void)viewDidLoad{
    [super viewDidLoad];
}


- (void)viewDidUnload{
    [self setMapView:nil];
    [super viewDidUnload];
}

// set the map region after launching
-(void)viewWillAppear:(BOOL)animated
{
    //Instantiate a location object.
    self.locationManager = [[CLLocationManager alloc] init];

    //Make this controller the delegate for the location manager.
    self.locationManager.delegate = self;

    //Set some parameters for the location object.
    [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    // order: latitude(纬度), longitude(经度)
    CLLocationCoordinate2D center = self.locationManager.location.coordinate;

    // 单位是degree
    MKCoordinateSpan span = MKCoordinateSpanMake(0.03, 0.03);

    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);

    [self.mapView setRegion:region animated:YES];

    // NSLog(@"currentCentre is (%f , %f)", self.currentCentre.latitude, self.currentCentre.longitude);
}

// Get place tpye from button title
// All buttons share this one method
- (IBAction)toolbarButtonPressed:(id)sender
{
    UIBarButtonItem *button = (UIBarButtonItem *)sender;
    NSString *buttonTitle = [button.title lowercaseString];

    //Use this title text to build the URL query and get the data from Google.
    [self queryGooglePlaces:buttonTitle];

}

// Parse response JSON data
-(void)parseData:(NSData *)responseData {

    NSError* error;
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
                                                         options:kNilOptions
                                                        error:&error];

    //The results from Google will be an array obtained from the NSDictionary object with the key "results".
    NSArray* places = [json objectForKey:@"results"];
    [self plotPositions:places];
    NSLog(@"Plot is done");
}

// Format query string
-(void) queryGooglePlaces: (NSString *) googleType {

    // query string
    NSString *url = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=%@&types=%@&sensor=true&key=%@", self.currentCentre.latitude, self.currentCentre.longitude, [NSString stringWithFormat:@"%i", _currentDist], googleType, kGOOGLE_API_KEY];

    //string to URL 
    NSURL *googleRequestURL=[NSURL URLWithString:url];

    // Retrieve data from the query URL by GCD
    dispatch_async(kBgQueue, ^{
        NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
        [self parseData:data];
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    });

    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.labelText = @"Please Wait..";
}

#pragma mark - Map View Delegate

// called many times when map scrolling or zooming
// Use this to get currentCentre and currentDist (radius)

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    //Get the east and west points on the map so you can calculate the distance (zoom level) of the current map view.
    MKMapRect mRect = self.mapView.visibleMapRect;
    MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect));
    MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));

    //Set your current distance instance variable.
    self.currentDist = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint);

    //Set your current center point on the map instance variable.
    self.currentCentre = self.mapView.centerCoordinate;

   // NSLog(@"currentCentre is (%f , %f)", self.currentCentre.latitude, self.currentCentre.longitude);

}

// Setup annotation objects
-(void)plotPositions:(NSArray *)data {
    // 1 - Remove any existing custom annotations but not the user location blue dot.

    for (id<MKAnnotation> annotation in self.mapView.annotations) {
        if ([annotation isKindOfClass:[MapPoint class]]) {
            [self.mapView removeAnnotation:annotation];
        }
    }
    // 2 - Loop through the array of places returned from the Google API.
    for (int i=0; i<[data count]; i++) {
        //Retrieve the NSDictionary object in each index of the array.
        NSDictionary* place = [data objectAtIndex:i];
        // 3 - There is a specific NSDictionary object that gives us the location info.
        NSDictionary *geo = [place objectForKey:@"geometry"];
        // Get the lat and long for the location.
        NSDictionary *loc = [geo objectForKey:@"location"];
        // 4 - Get your name and address info for adding to a pin.
        NSString *name=[place objectForKey:@"name"];
        NSString *vicinity=[place objectForKey:@"vicinity"];
        // Create a special variable to hold this coordinate info.
        CLLocationCoordinate2D placeCoord;
        // Set the lat and long.
        placeCoord.latitude=[[loc objectForKey:@"lat"] doubleValue];
        placeCoord.longitude=[[loc objectForKey:@"lng"] doubleValue];

        // 5 - Create a new annotation.
        MapPoint *placeObject = [[MapPoint alloc] initWithName:name address:vicinity coordinate:placeCoord];
        [self.mapView addAnnotation:placeObject];
    }
    NSLog(@"addAnnotation is done");

}

// Setup annotation view
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    // Define your reuse identifier.
    static NSString *identifier = @"MapPoint";

    if ([annotation isKindOfClass:[MapPoint class]]) {
        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];

        if (annotationView == nil) {
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.animatesDrop = YES;


        // NSLog(@"annotation view is added");

        return annotationView;

    }
    return nil;
}

@end
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T13:49:07+00:00Added an answer on June 10, 2026 at 1:49 pm

    A couple of things:

    Move your removeAnnotation and addAnnotation code to run on the UI thread, e.g.:

    dispatch_async (dispatch_get_main_queye(), ^
    {
     [self.mapView addAnnotation:placeObject]; 
    });
    

    Move your viewWillAppear initialization code to viewDidLoad. viewWillAppear may be called multiple times during the lifetime of your view controller

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I expect that framework level updates (such as async) will not be able to
Via Google Mock's Return() you can return what value will be returned once a
I expect LastNumberWeeks NumericUpDown to be disabled on form load but it isn't. Once
I have a page that post data to another page once a form has
I expect this FQL query to return a non-empty array, because there are comments
My expect code does this: It does a ssh connect to another machine, sends
I expect this might get some downvotes / closevotes but I'm going to ask
I expect the answer to this is already here someplace, but I was not
I expect the following code to unload a javascipt jqgrid, then load another grid
Can I expect the keys() to remain in the same order? I plan to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.