Question

First of all I am running a Map page that just only show pins on map for every store. I was running only one pin on the map and it was fast after I put more than 25 pins it push very slow to the map page. What it is doing now at that process the app just load all data of the pin location (as I see in the target output) and then it push to the next screen. So please where would be my problem?

- (void)viewDidLoad
{

[super viewDidLoad];

self.title = @"";

self.navigationItem.title = @"Mek";

response = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://kalkatawi.com/mapLocation.php"]];

if(response!=nil) {

    NSError *parseError = nil;

    jsonArray = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&parseError];

    jsonArray1 = [[NSMutableArray alloc] init];
    jsonArray2 = [[NSMutableArray alloc] init];
    jsonArray3 = [[NSMutableArray alloc] init];

    for(int i=0;i<[jsonArray count];i++)
    {
        name = [[jsonArray objectAtIndex:i] objectForKey:@"name"];

        longitude = [[jsonArray objectAtIndex:i] objectForKey:@"longitude"];

        latitude = [[jsonArray objectAtIndex:i] objectForKey:@"latitude"];


        [jsonArray1 addObject:name];

        [jsonArray2 addObject:longitude];

        [jsonArray3 addObject:latitude];


        self.locationMap.delegate = self;  //set delegate before adding annotations

        CLLocationCoordinate2D annotationCoord;

        for (int i=0; i < [jsonArray count]; i++)
        {
            NSDictionary *annotationDictionary = [jsonArray objectAtIndex:i];

            name = [annotationDictionary objectForKey:@"name"];

            annotationCoord.latitude
            = [[annotationDictionary objectForKey:@"longitude"] doubleValue];
            annotationCoord.longitude
            = [[annotationDictionary objectForKey:@"latitude"] doubleValue];

            MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
            annotationPoint.coordinate = annotationCoord;
            annotationPoint.title = name;
            annotationPoint.subtitle = [NSString stringWithFormat:@"%f %f", annotationPoint.coordinate.latitude, annotationPoint.coordinate.longitude];


            [self.locationMap addAnnotation:annotationPoint];

            //------------------------//

            MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annotationPoint.coordinate, 50000, 50000);
            [self.locationMap setRegion:[self.locationMap regionThatFits:region] animated:YES];

            locationManager = [[CLLocationManager alloc] init];
            locationManager.distanceFilter = kCLDistanceFilterNone;
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
            [locationManager startUpdatingLocation];

            lat = locationManager.location.coordinate.latitude;
            lon = locationManager.location.coordinate.longitude;
        }


    }

}

else {

    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"You are not connected to internet" message:@"Please check the internet connection" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}
}

- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{

MKAnnotationView *pinView = nil;

if(annotation != locationMap.userLocation)
{
    static NSString *defaultPinID = @"myPin";

    pinView = (MKAnnotationView *)[locationMap dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
    if ( pinView == nil )
        pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];

    pinView.image = [UIImage imageNamed:@"pinpinpin.png"];
    pinView.canShowCallout = YES;
    pinView.enabled = YES;

    UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    pinView.rightCalloutAccessoryView = infoButton;
}

return pinView;
}
Was it helpful?

Solution

SImple way is load data in background thread, and then when data is fully load display it on the map. You can do this in any of view controller, means you can do it in parent view controller and when you got response then update on map view controller. Or on view did load method load data in background and update it when its load. This approach will not hold your UI. You can use blocks like this

dispatch_async(queue, ^{
 //load data from server

    dispatch_async(dispatch_get_main_queue(), ^{ 
        //Update map
    });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top