2012-09-10 5 views
7

यदि ऐप चल रहा है और CLLocationManagerDelegate क्लास अग्रभूमि (यानी दृश्यमान) है तो didEnterRegions ट्रिगर करता है और मुझे NSLog और AlertView दोनों मिलते हैं। हालांकि, जब ऐप पृष्ठभूमि में होता है या अनिवार्य रूप से, यदि स्क्रीन कुछ भी दिखा रही है तो प्रतिनिधि वर्ग के अलावा मुझे कुछ भी नहीं मिलता है।didEnterRegion अग्रभूमि में काम करता है लेकिन पृष्ठभूमि या अन्य वीसी

मैंने प्लेस्ट में "आवश्यक पृष्ठभूमि मोड" के तहत "स्थान अपडेट के लिए ऐप रजिस्ट्रार" सेट किया है, हालांकि मुझे यकीन नहीं है कि यह भी आवश्यक है।

यहां मुझे लगता है कि प्रासंगिक कोड है हालांकि मैं गलत हो सकता हूं (और खुशी से और जोड़ दूंगा)। मुझे ध्यान रखना चाहिए कि देखने में सबकुछ डीडलोड को एक में लपेटा गया है, जो जांचता है कि क्षेत्र की निगरानी उपलब्ध है या सक्षम है या नहीं।

- (void)viewDidLoad 
{ 
    NSLog(@"MapViewController - viewDidLoad"); 
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; 
    self.locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;  
    self.locationManager.delegate = self; 
    [self.locationManager startMonitoringSignificantLocationChanges]; 
} 

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 
{ 
    NSLog(@"MapViewController - didEnterRegion"); 
    NSLog(@"MVC - didEnterRegion - region.radius = %f", region.radius); 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"entered region..." message:@"You have Entered the Location." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 
    alert.tag = 2; 
    [alert show]; 
} 
यहाँ

वह जगह है जहाँ मैं क्षेत्रों की सूची पर नजर रखी जा मिलता है, AppDelegate.m में:

- (void)doneButtonTapped { 
    NSLog(@"doneButtonTapped"); 

    if (self.locationIdentifier) { 
     if ([CLLocationManager regionMonitoringEnabled] && [CLLocationManager regionMonitoringAvailable]) { 

      // core data setup 
      NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
      NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"LocationReminder" inManagedObjectContext:self.managedObjectContext]; 
      fetchRequest.entity = entityDescription; 
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"locationIdentifier == %@", self.locationIdentifier]; 
      fetchRequest.predicate = predicate; 
      NSError *error; 
      NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
      if (results) { 

       // get the LocationReminder 
       LocationReminder *retrievedReminder = [results objectAtIndex:0]; 
       retrievedReminder.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString]; 
       retrievedReminder.userRecording = nil; 

       // start monitoring it's region 
       NSArray *coordinateArray = [retrievedReminder.locationIdentifier componentsSeparatedByString:@", "]; 
       CLLocationCoordinate2D coordinate = {[[coordinateArray objectAtIndex:0] doubleValue], [[coordinateArray objectAtIndex:1] doubleValue]}; 
       CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coordinate radius:250.0 identifier:retrievedReminder.locationIdentifier]; 
       NSLog(@"about to monitor region with radius: %f", newRegion.radius); 
       [self.locationManager startMonitoringForRegion:newRegion desiredAccuracy:kCLLocationAccuracyBest]; 

       // save the LocationReminder 
       if (![self.managedObjectContext save:&error]) { 
        NSLog(@"hmm. no managed object context. must be something space-time going on"); 
       } else { 
        NSLog(@"saved locationReminder, locationIdentifier = %@", retrievedReminder.locationIdentifier); 
       } 
      } else { 
       NSLog(@"ERROR: no LocationReminder retreived for predicate: %@", predicate); 
      } 
     } 

     // get the mapview controller off of the navigation stack 
     for (UIViewController *viewController in self.navigationController.viewControllers) { 
      if ([viewController isKindOfClass:[MapViewController class]]) { 
       MapViewController *mapVC = (MapViewController *)viewController; 
       mapVC.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString]; 
       [self.navigationController popToViewController:mapVC animated:YES]; 
      } 
     } 
} 

और क्योंकि:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 

// other code 

NSLog(@"LISTING ALL REGIONS MONITORED"); 
    NSArray *regions = [self.locationManager.monitoredRegions allObjects]; 
    if (!regions) { 
     NSLog(@"no regions found"); 
    } else { 
     NSLog(@"got %d monitored regions", [regions count]); 
     for (int i = 0; i < [regions count]; i++) { 
      CLRegion *region = [regions objectAtIndex:i]; 
      NSLog(@"region %d's identifier = %@", i, region.identifier); 
      NSLog(@"region: radius: %@", region.radius); 
     } 
    } 

// other code 
} 

मैं दो बार startMonitoringForRegion कहते हैं, यहाँ मुख्य जगह है मुझे यह महसूस हो रहा है कि यह महत्वपूर्ण हो सकता है, यहां स्थान के लिए गेटर है प्रबंधक:

- (CLLocationManager *)locationManager { 
    NSLog(@"MapViewController - locationManager"); 
    if (_locationManager) { 
     return _locationManager; 
    } else { 
     _locationManager = [[CLLocationManager alloc] init]; 
     return _locationManager; 
    } 
} 

अद्यतन 1: ऐप्पल मंचों (जहां मैंने क्रॉसपोस्ट किया) के माध्यम से किसी ने उल्लेख किया कि अलर्टव्यू केवल अग्रभूमि में दिखाएगा। फिर भी एनएसएलओजी आग नहीं लगाता है। मुझे लगता है कि काम करना चाहिए।

+0

क्या आप उस कोड को शामिल कर सकते हैं जहां आप startMonitoringForRegion को कॉल कर रहे हैं? अभी शामिल कोड यह नहीं दिखाता है और केवल महत्वपूर्ण स्थान परिवर्तन से संबंधित कॉलबैक विधियों को ट्रिगर करेगा। और उन घटनाओं को मेरे अनुभव में सिम्युलेटर से नहीं आग लग जाएगी। –

उत्तर

3

मेरे एक दोस्त ने भूगर्भीकरण का उपयोग करने पर एक अच्छा ट्यूटोरियल लिखा जो आपके कुछ मुद्दों को दूर करने में मदद कर सकता है।

Get started with geofencing

वहाँ उदाहरण के बहुत सारे इतने पर ऑनलाइन और यहाँ हैं। छोटे से शुरू करें और अपना रास्ता तैयार करें। एक बार जब आप अपनी कॉलबैक प्राप्त करना शुरू कर देते हैं, तो आप चीजों को अपने अन्य दृश्य नियंत्रकों तक विस्तारित करना शुरू कर सकते हैं।

अद्यतन

के रूप में टिप्पणी में समझाया अपने स्थान प्रबंधक और प्रतिनिधि तरीकों को नियंत्रित करने के लिए एक सिंगलटन वर्ग बनाने के लाभ। सिंगलटन का उपयोग करके, आप अपने प्रतिनिधि तरीकों से कई कॉल प्राप्त करने की संभावना को रोकते हैं। आप इसे सावधानीपूर्वक कोडिंग से रोक सकते हैं, लेकिन एक सिंगलटन का उपयोग करके यह आपके लिए करता है। यह आपके प्रतिनिधि तरीकों से किए जाने वाले सभी कार्यों को संभालने के लिए भी एक अच्छी कक्षा है।

+2

लिंक के लिए धन्यवाद। मुझे पूरा यकीन है कि मुझे उन सभी अड्डों को कवर किया गया है। इस बिंदु पर मुझे लगता है कि क्षेत्र निगरानी की तुलना में ऐप्स कैसे पृष्ठभूमि में और बाहर जाते हैं। असल में, यह मुझे उचित समझ में आता है कि यह केवल CLLocationManagerDelegate में काम करता है - एंटररेगियन को कैसे कहा जाता है? क्या आईओएस ऐप जागने और उचित वीसी को तुरंत चालू करने के लिए पर्याप्त जानता है? मैं सोच रहा हूं कि इसे UIAplplicationDelegate प्रोटोकॉल के साथ कुछ करना है या नहीं। –

+1

दूसरी ओर, स्थान जागरूकता प्रोग्रामिंग गाइड में UIAplplicationDelegate का उल्लेख नहीं किया गया है जो मुझे लगता है कि यह महत्वपूर्ण नहीं है। अभी भी उलझन में है कि ओएस को यह पता होना चाहिए कि एन्टररियन लागू किया गया है और यदि ऐप पृष्ठभूमि में है तो उस वर्ग तक कैसे पहुंचे ... –

+0

यह सुनिश्चित है कि यह CLLocationManagerDelegate के किसी भी वर्ग पर आधारित है। उस वर्ग को किसी भी कॉलबैक के बारे में अधिसूचित किया जाएगा। इस तरह मैंने अपना सेट अप किया है। मैंने कई कॉलबैक प्राप्त करने से बचने के लिए अपने स्थान प्रबंधक वर्ग के लिए सिंगलटन भी बनाया। –

0

जब आपने एंटररियन किया था तो आप स्थानीय अधिसूचना पोस्ट कर सकते हैं।

यह पृष्ठभूमि में होने पर भी एक चेतावनी जैसी पॉपअप दिखाएगा।

1) किसी भी यादृच्छिक संदेश के साथ अपने अनुप्रयोग प्रतिनिधि के अपने applicationDidEnterBackground अंदर एक स्थानीय अधिसूचना वस्तु बनाएँ, और तुरंत आग स्थानीय अधिसूचना बता:

आप एक साधारण परीक्षण कर सकते हैं।

2) जब आप ऐप को कम करते हैं, तो होम बटन दबाएं, आपको पॉपअप देखना चाहिए।

+0

सुझावों के लिए धन्यवाद - मैं UIAplplicationDelegate प्रोटोकॉल से परिचित नहीं था और अब मैं सोच रहा हूं कि यह समस्या नहीं है या नहीं। बिल बर्गेस को मेरी टिप्पणियों पर एक नज़र डालें। –

0

मुझे लगता है कि आपको अपने ऐप पर जाना होगा।plist

और आवश्यक पृष्ठभूमि मोड जोड़ें: जोड़ने itme अनुप्रयोग स्थान अद्यतन

और 1 के लिए पंजीकृत करता है। यदि आप ऐप पृष्ठभूमि में हैं, तो आप अभी भी शीर्ष

और 2, यदि ऐप मारे गए हैं, तो आप अभी भी शीर्ष पर एक खोखले तीर देख सकते हैं, आईओएस आपके लिए क्षेत्र की निगरानी करेगा, लेकिन 20 क्षेत्रों तक सीमित होगा

2

चीजें आप गलत कर रहे हैं:

  1. पृष्ठभूमि मोड - ऐप स्थान अपडेट के लिए पंजीकृत करता है। इसकी आवश्यकता नहीं है। जब आप स्थान आदि में महत्वपूर्ण परिवर्तनों के लिए जानकारी एकत्र करना चाहते हैं तो इसकी आवश्यकता होती है। इसलिए, लक्ष्य> अपने ऐप> कैपेबिलिट्स पर जाएं, और पृष्ठभूमि मोड के तहत वांछित विकल्प का चयन करें। यह स्वचालित रूप से आपके लिए प्लिस्ट अपडेट करेगा। अभी के लिए, इसे अक्षम करें।
  2. जब उपयोगकर्ता किसी क्षेत्र में प्रवेश करता है तो आप अलर्ट बनाने की कोशिश कर रहे हैं। ऐप काम करते समय काम करते समय, जब आपका ऐप पृष्ठभूमि में होता है तो एक चेतावनी का उपयोग नहीं किया जाता है। - बल्कि स्थानीय अधिसूचना या एपीआई कॉल को ट्रिगर करें।

उदाहरण के लिए। अधिसूचना:

-(void)triggerLocalNotification:(CLRegion *)region{ 
    UILocalNotification *notification = [[UILocalNotification alloc]init]; 
    [notification setAlertBody:[NSString stringWithFormat:@"Welcome to %@", [region identifier]]]; 
    [notification setRepeatInterval:0]; 
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:2]]; 
    [notification setTimeZone:[NSTimeZone defaultTimeZone]]; 
    [[UIApplication sharedApplication]scheduleLocalNotification:notification]; 
    NSLog(@"notification triggered with notification %@", notification); 
} 
+0

startMonitoringSignificantLocationChanges और startMonitoringForRegion पृष्ठभूमि मोड में काम कर रहा है? –

+0

यदि आप प्रारंभ कर रहे हैं मॉनिटरिंग सिग्निफिशेंट लोकेशन चेंज, तो हाँ आपको पृष्ठभूमि मोड की आवश्यकता है। जब स्थान महत्वपूर्ण रूप से बदलता है तो आपको जागने के लिए अपने ऐप की आवश्यकता होती है और आपको इसे अपने सिस्टम में बताने की आवश्यकता होती है। लेकिन आपको इसे शुरू करने के लिए इसकी आवश्यकता नहीं है मॉनिटरिंगफॉररियन। startMonitoringForRegion पृष्ठभूमि मोड के बावजूद didEnterRegion और didExitRegion को कॉल करेगा। –

+0

बहुत बहुत धन्यवाद, मैं न्यूनतम बैटरी खपत के साथ CLLocationManager का उपयोग करना चाहता हूं। –

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