ios - Refreshing a MKMapView when the user location is updated or using default values -


i'm trying refresh map view , load new data server when device acquires user location. here's i'm doing:

- (void)viewdidload {     cgrect bounds = self.view.bounds;     mapview = [[mkmapview alloc] initwithframe:bounds];     mapview.showsuserlocation=yes;     mapview.delegate=self;     [self.view insertsubview:mapview atindex:0];     [self refreshmap]; }  - (void)mapview:(mkmapview *)themapview didupdateuserlocation:(mkuserlocation *)userlocation {     //this avoid frequent updates, need 1 position , don't need continuously track user's location     if (userlocation.location.horizontalaccuracy > self.myuserlocation.location.horizontalaccuracy) {         self.myuserlocation = userlocation;         cllocationcoordinate2d centercoord = { userlocation.location.coordinate.latitude, userlocation.location.coordinate.longitude };         [themapview setcentercoordinate:centercoord zoomlevel:10 animated:yes];         [self refreshmap];     } }  - (void)refreshmap {     [[uiapplication sharedapplication] setnetworkactivityindicatorvisible:yes];     [self.mapview removeannotations:self.mapview.annotations];     //default position     nsstring *lat = @"45.464161";     nsstring *lon = @"9.190336";     if (self.myuserlocation != nil) {         lat = [[nsnumber numberwithdouble:myuserlocation.coordinate.latitude] stringvalue];         lon = [[nsnumber numberwithdouble:myuserlocation.coordinate.longitude] stringvalue];     }     nsstring *url = [[nsstring alloc] initwithformat:@"http://myserver/geo_search.json?lat=%@&lon=%@", lat, lon];      nsurlrequest *therequest=[nsurlrequest requestwithurl:[nsurl urlwithstring:url] cachepolicy:nsurlrequestuseprotocolcachepolicy timeoutinterval:60.0];     [[nsurlconnection alloc] initwithrequest:therequest delegate:self];     [url release];     [[uiapplication sharedapplication] setnetworkactivityindicatorvisible:no]; } 

i have - (void)connection:(nsurlconnection *)connection didreceivedata:(nsdata *)data, create , add annotations.

here's happens: location after while, loaded data close default location. location , should remove old annotations , add new ones, instead keep seeing old annotations , new ones added anyway (let's receive 10 annotations each time, means have 20 on map when should have 10).

what doing wrong?

ok might little long worked me , hope you. app used share different traffic status reports between drivers.

i had problem also, tried load annotations server, delete them , reload annotations array map every time user sends annotation server himself/presses "refresh" button/every 1.5 minutes - have current set.

so thought might have time interval takes load new annotations server, or array itself, later realized might connected way entire code organized , maybe things got in way/timing of others.

what did moving [self.map addannotations:an array of annotations] command main thread , whole loading process back, used temp array instead of "self.map.annotations" delete current annotations, worked ok afterwards left :), though i'm not world-class expert (not close) , i'm sure others might have more professional , efficient solution, code sample:

//this in viewdidload, kicks off whole process      [self performselectorinbackground:@selector(retrieveannotationsdatafromserver) withobject:self];  //this method loading data      -(void)retrieveannotationsdatafromserver     {         nsautoreleasepool *pool=[[nsautoreleasepool alloc]init];         //code loading..         nsurl *url=[nsurl urlwithstring:@"http://your server name here"];         nsstring *result=[nsstring stringwithcontentsofurl:url encoding:4 error:nil];         nslog(@"%@",result);         nsdata *data = [nsdata datawithcontentsofurl:url];         nsxmlparser *parser = [[nsxmlparser alloc]initwithdata:data];         [parser setdelegate:self];         [parser parse];      //inside parser delegate take each element of report , store in mutable array create annotations later (report title, report description/subtitle, report location longitude , report location latitude)          [pool drain];         nslog(@"retrieveannotatinsdatafromserver pool drained");     }      //now, in case last thing happen before pool drained parser`s "didenddocument" method gonna called, delayed loading this:      - (void)parserdidenddocument:(nsxmlparser *)parser     {         nslog(@"parser - document ended, creating annotationsarray");         nslog(@"this size of ra array:%d",[self.recievedtitles count]);         (int i=0;i<[self.recievedtitles count];i++)         {             //rc=recieved coordinate             //ra=recieved annotation             cllocationcoordinate2d rc;             rc.latitude=[[self.recievedlatitude objectatindex:i] doublevalue];             rc.longitude=[[self.recievedlongitude objectatindex:i] doublevalue];             if([self.recievedtitles objectatindex:i]==nil)                 continue;             annotation *ra=[[annotation alloc]initwithcoordinate:rc andtitle:[self.recievedtitles objectatindex:i] andsubtitle:[self.recievedsubtitles objectatindex:i]];      //the "self.annotationsarray" array use hold current set retrieved server             [self.annotationsarray addobject:ra];             [ra autorelease];             nslog(@"ra %d inserted",i);         }          nslog(@"data retrieving ended, loading annotations map");         [self performselectoronmainthread:@selector(addannotations) withobject:self waituntildone:no];      }      //this method defined apply in main thread instead of in background whole loading process.. i'm sure can done better.      -(void)addannotations     {         [self.map addannotations:self.annotationsarray];         nslog(@"annotations loaded map");     }      //now have retrieved them server first time, reloading , refreshing part comes next, method called time user press refresh, sends report sever, or automatically every 1.5 minutes:      -(void)refreshmap     {         nsarray *annotationstodelete=[[nsarray alloc] initwitharray:self.annotationsarray];         [self.map removeannotations:annotationstodelete];         [annotationstodelete release];         [self performselectorinbackground:@selector(retrieveannotationsdatafromserver) withobject:self];     } 

please comment on answer since happy learn less complicated way of solving matter.

i think of these type of problems have been solved if there way "wait until done" when using background threads, because happens code continues run forward before whole process of downloading-parsing-creating annotation-loading map process finished.


Comments