2011-04-30 12 views
6

मैं अपने मानचित्र दृश्य को रीफ्रेश करने का प्रयास कर रहा हूं और डिवाइस को उपयोगकर्ता स्थान प्राप्त करते समय सर्वर से नया डेटा लोड करने का प्रयास कर रहा हूं। यहाँ मैं क्या कर रहा है:उपयोगकर्ता स्थान को अद्यतन या डिफ़ॉल्ट मानों का उपयोग करते समय MKMapView को रीफ्रेश करना

- (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 is to avoid frequent updates, I just need one position and don't need to continuously track the 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]; 
} 

मैं भी एक है - (शून्य) कनेक्शन: (NSURLConnection *) कनेक्शन didReceiveData: (NSData *) डेटा, बना सकते हैं और टिप्पणियां जोड़ने के लिए।

यहां क्या होता है: कभी-कभी मुझे थोड़ी देर बाद स्थान मिलता है, इसलिए मैंने पहले से ही डिफ़ॉल्ट स्थान के करीब डेटा लोड किया है। फिर मुझे स्थान मिलता है और पुरानी टिप्पणियां हटाएं और नए जोड़ें, इसके बजाय मैं पुरानी एनोटेशन देख रहा हूं और नए भी जोड़े गए हैं (मान लें कि मुझे हर बार 10 एनोटेशन प्राप्त होते हैं, इसलिए इसका मतलब है कि मैं मेरे पास 20 है जब मेरे पास 10 होना चाहिए)।

मैं क्या गलत कर रहा हूं?

+0

रीफ्रेश मैप में, निकालें लाइन से पहले, जांचें कि self.mapView शून्य है या नहीं। – Anna

+0

यह शून्य नहीं है, यह मुझे मिलता है: > मैं ठीक से परीक्षण भी नहीं कर सकता क्योंकि मुझे केवल वास्तविक समस्या पर यह समस्या दिखाई देती है, सिम्युलेटर में नहीं ... क्या कोड तर्कसंगत रूप से सही है? – koichirose

+0

मुझे कोई स्पष्ट समस्या नहीं दिख रही है। शायद यह कुछ है कि एनोटेशन कैसे जोड़े गए हैं या देखने के लिए फॉरऑनोटेशन। – Anna

उत्तर

0

ठीक है यह थोड़ा लंबा हो सकता है लेकिन यह मेरे लिए काम करता है और मुझे उम्मीद है कि यह आपकी मदद करेगा। यह एक ऐप से है जिसका उपयोग ड्राइवरों के बीच विभिन्न ट्रैफ़िक स्थिति रिपोर्ट साझा करने के लिए किया जाता है।

मुझे यह समस्या भी थी, मैंने सर्वर से एनोटेशन लोड करने का प्रयास किया, फिर उन्हें हटाएं और हर बार जब उपयोगकर्ता सर्वर पर एनोटेशन भेजता है तो उसे एनोटेशन सरणी को फिर से लोड करें/प्रत्येक "ताज़ा करें" बटन दबाएं 1.5 मिनट - ताकि वह हमेशा चालू सेट रखे।

तो मैंने सोचा कि यह समय अंतराल के साथ कुछ करने के लिए हो सकता है जो सर्वर से नई एनोटेशन लोड करने के लिए होता है, या सरणी के साथ, बाद में मुझे एहसास हुआ कि यह पूरे कोड के तरीके से भी जुड़ा हो सकता है संगठित और शायद कुछ चीजें दूसरों के रास्ते/समय में मिल गईं।

मैंने जो किया है वह मूल रूप से [self.map addAnnotations:AN ARRAY OF ANNOTATIONS] कमांड को मुख्य धागे और पूरी लोडिंग प्रक्रिया को पीछे की तरफ ले जा रहा है, मैंने वर्तमान एनोटेशन को हटाने के लिए "self.map.annotations" के बजाय एक temp सरणी भी उपयोग की है, यह ठीक काम करता है बाद में तो मैं सिर्फ इतना है कि :) की तरह छोड़ दिया है, हालांकि मैं एक विश्व स्तरीय विशेषज्ञ नहीं (यहां तक ​​कि बंद नहीं) कर रहा हूँ और मुझे यकीन है कि दूसरों के लिए एक और अधिक पेशेवर और कुशल समाधान, कोड नमूना हो सकता है कर रहा हूँ:

//this is in viewDidLoad, it kicks off the whole process 

    [self performSelectorInBackground:@selector(retrieveAnnotationsDataFromServer) withObject:self]; 

//this is the method for loading data 

    -(void)retrieveAnnotationsDataFromServer 
    { 
     NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init]; 
     //code for 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 the parser delegate i take each element of the report and store it in a mutable array so that i could create the annotations later (report title, report description/subtitle, report location longitude and report location latitude) 

     [pool drain]; 
     NSLog(@"retrieveannotatinsdatafromserver pool drained"); 
    } 

    //Now, in this case the last thing that will happen before the pool is drained is that the parser`s "didEndDocument" method gonna be called, so this is where I delayed the loading like this: 

    - (void)parserDidEndDocument:(NSXMLParser *)parser 
    { 
     NSLog(@"parser - document ended, creating annotationsArray"); 
     NSLog(@"this is the size of RA Array:%d",[self.recievedTitles count]); 
     for (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" is an array i use to always hold the most current set retrieved from the server   
    [self.AnnotationsArray addObject:RA]; 
      [RA autorelease]; 
      NSLog(@"RA %d inserted",i); 
     } 
     NSLog(@"Data retrieving ended, loading annotations to map"); 
     [self performSelectorOnMainThread:@selector(addAnnotations) withObject:self waitUntilDone:NO]; 

    } 

    //this method was only defined so that i could apply it in the main thread instead of in the background like the whole loading process.. I'm sure it can be done better. 

    -(void)addAnnotations 
    { 
     [self.Map addAnnotations:self.AnnotationsArray]; 
     NSLog(@"annotations loaded to Map"); 
    } 

    //now we have retrieved them from the server for the first time, the reloading and refreshing part comes next, this method is called any time the user press refresh, sends a report to the 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]; 
    } 

कृपया मेरे उत्तर पर टिप्पणी करें क्योंकि मैं इस मामले को हल करने का एक कम जटिल तरीका सीखने में भी बहुत खुश हूं।

मुझे लगता है कि अगर पृष्ठभूमि थ्रेड का उपयोग करते समय "पूरा होने तक प्रतीक्षा करें" का कोई तरीका था, तो अब इनमें से अधिकतर समस्याओं का समाधान किया जाएगा, क्योंकि अब क्या होता है कि कोड डाउनलोड करने की पूरी प्रक्रिया से पहले आगे बढ़ना जारी रखता है -पर्सिंग-निर्माण मानचित्र प्रक्रिया में एनोटेशन-लोडिंग वास्तव में समाप्त हो गई है।

संबंधित मुद्दे