2016-02-17 8 views
6

पर ट्रिगर नहीं करता है, मैं महत्वपूर्ण स्थान परिवर्तन निगरानी का उपयोग कर रहा हूं। जब मैं सिम्युलेटर में कोड चलाता हूं और फ्रीवे विकल्प की जांच करता हूं तो मुझे आवधिक स्थान अपडेट मिलते हैं। मैं इन अद्यतनों को पकड़ता हूं और उन्हें NSUserDefaults में सहेजता हूं और प्रत्येक 10s में टेबलव्यू अपडेट करने की तुलना में, इसलिए मैं देख सकता हूं कि मुझे कोई अपडेट मिला है या नहीं। यदि मैं एक असली डिवाइस पर ऐप चलाता हूं, तो मुझे शून्य अपडेट मिलते हैं। मैंने फोन को अपनी जेब में रखा और 80 किमी से अधिक की यात्रा की, 2 शहरों में। शून्य अपडेट यकीन नहीं है कि अगर मैंने कुछ गड़बड़ कर ली है। मैं कोड संलग्न कर रहा हूँ। कोड कॉपी पेस्ट है, परीक्षण करने के लिए स्वतंत्र महसूस करें। बस स्टोरीबोर्ड में TableViewController का उपयोग करना सुनिश्चित करें और आईडी आईडी को आईडी पर सेट करें। मैं क्या खो रहा हूँ? मैं iphone पर परीक्षण कर रहा हूँ 5.महत्वपूर्ण स्थान परिवर्तन डिवाइस

Info.plist:

enter image description here

संपादित करें: सेब डॉक्स में मिला था। क्या मुझे locationManager अलग-अलग बनाया जाना चाहिए?

किसी एप्लिकेशन को स्थान अपडेट, लांच विकल्प आपके आवेदन करने के लिए पारित कर दिया शब्दकोश की वजह से फिर से लॉन्च किया गया है: willFinishLaunchingWithOptions: या आवेदन: didFinishLaunchingWithOptions: विधि UIApplicationLaunchOptionsLocationKey कुंजी है। उस कुंजी संकेतों की उपस्थिति सिग्नल करती है कि नया स्थान डेटा आपके ऐप पर पहुंचने का इंतजार कर रहा है। उस डेटा को प्राप्त करने के लिए, आपको एक नया CLLocationManager ऑब्जेक्ट बनाना होगा और आपके ऐप की समाप्ति से पहले चल रहे स्थान सेवाओं को पुनरारंभ करना होगा। जब आप उन सेवाओं को पुनरारंभ करते हैं, तो स्थान प्रबंधक अपने प्रतिनिधि को सभी लंबित स्थान अपडेट प्रदान करता है।

EDIT2:

इस के आधार पर, स्थान कम से कम हर 15 मिनट अद्यतन किया जाना चाहिए। मेरे कोड में बग पुष्टि की।

तो जीपीएस-स्तरीय सटीकता अपने अनुप्रयोग के लिए गंभीर नहीं है और आप निरंतर ट्रैकिंग की जरूरत नहीं है, आप महत्वपूर्ण परिवर्तन स्थान सेवा का उपयोग कर सकते हैं। यह महत्वपूर्ण है कि आप महत्वपूर्ण परिवर्तन स्थान सेवा का सही ढंग से उपयोग करें, क्योंकि यह प्रत्येक 15 मिनट में सिस्टम और आपके ऐप को कम से कम बनाता है, भले ही कोई स्थान परिवर्तन न हो, और इसे तब तक जारी रखता है जब तक आप इसे रोक नहीं देते।

संपादित 3: यह कोड ऐपडिलेगेट didFinishLaunchingWithOptions: पर यह कोड देखने के लिए जोड़ा गया कि ऐप जागृत हो गया है या नहीं। यह जागृत नहीं होता है- मुझे तालिका दृश्य में 200 200 प्रविष्टि दिखाई नहीं देती है। कुछ ख़राब चल रहा है।

if let options = launchOptions { 
      print("options") 
      if (launchOptions![UIApplicationLaunchOptionsLocationKey] != nil){ 
       locationManager.startUpdatingLocation() 
       self.lat.append(Double(200)) 
       self.lon.append(Double(200)) 
       self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle)) 
       NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat") 
       NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon") 
       NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time") 
      } 

कोड: // AppDelegate:

import UIKit 
import CoreLocation 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate { 

    var lat:[CLLocationDegrees]! 
    var lon:[CLLocationDegrees]! 
    var times:[String]! 
    var distances: [String]! 

    var window: UIWindow? 
    var locationManager: CLLocationManager! 


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

     locationManager=CLLocationManager() 
     locationManager.delegate=self 
     locationManager.requestAlwaysAuthorization() 

     let isFirstLaunch = NSUserDefaults.standardUserDefaults().objectForKey("lat") 
     if isFirstLaunch == nil{ 
      lat = [CLLocationDegrees]() 
      lon = [CLLocationDegrees]() 
      times = [String]() 
      NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat") 
      NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon") 
      NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time") 
     }else{ 
      lat = NSUserDefaults.standardUserDefaults().arrayForKey("lat") as! [CLLocationDegrees] 
      lon = NSUserDefaults.standardUserDefaults().arrayForKey("lon") as! [CLLocationDegrees] 
      times = NSUserDefaults.standardUserDefaults().objectForKey("time") as! [String] 
//   distances = NSUserDefaults.standardUserDefaults().objectForKey("distance") as! [String] 

     } 
     return true 
    } 



    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
     print("location updated") 

     self.lat.append(locations[0].coordinate.latitude) 
     self.lon.append(locations[0].coordinate.longitude) 
     self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle)) 

     NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat") 
     NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon") 
     NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time") 

     print("Location: \(locations[0].coordinate.latitude) \(locations[0].coordinate.longitude)") 
    } 

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 
     print("did change AS") 
     switch status { 
     case .AuthorizedWhenInUse: 
      locationManager.startMonitoringSignificantLocationChanges() 
     case .AuthorizedAlways: 
      print("to always") 
      locationManager.startMonitoringSignificantLocationChanges() 
      if lat.count==0{ 
       self.lat.append((locationManager.location?.coordinate.latitude)!) 
       self.lon.append((locationManager.location?.coordinate.longitude)!) 

       self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle)) 

       NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat") 
       NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon") 
       NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time") 


      } 

//   locationManager.startUpdatingLocation() 
      break 
     default: 
      locationManager.stopMonitoringSignificantLocationChanges() 
      break 
     } 
    } 
} 

// देखें नियंत्रक

import UIKit 

class TableViewController: UITableViewController { 

    let appDel = UIApplication.sharedApplication().delegate as! AppDelegate 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "updateTableView", userInfo: nil, repeats: true) 
    } 



    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     // #warning Incomplete implementation, return the number of sections 
     return 1 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     // #warning Incomplete implementation, return the number of rows 
     return appDel.lon.count 
    } 


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("ID", forIndexPath: indexPath) 
     cell.textLabel?.text = "\(appDel.lat[indexPath.row]) \(appDel.lon[indexPath.row]) \(appDel.times[indexPath.row])" 
     cell.textLabel?.font = UIFont.systemFontOfSize(9) 


     return cell 
    } 

    func updateTableView(){ 
    self.tableView.reloadData() 
    } 
} 
+0

क्या आप वास्तव में प्राधिकरण के लिए अनुरोध देखते हैं? यदि नहीं, तो क्या आपको अपने प्लिस्ट में NSLocationAlwaysUsageDescription मिला है? –

+0

हाँ अनुरोध पॉप आउट हो गया है।और हां, NSLocationAlwaysUsageDescription स्ट्रिंग info.plist में सेट है। – brumbrum

+0

क्या आप ऐप पर डबल बटन टैप करके ऐप पर स्वाइप करके ऐप को मार रहे हैं? यदि आप इस तरह से ऐप को मारते हैं, तो यह पृष्ठभूमि महत्वपूर्ण परिवर्तन सेवाओं को नहीं चलाएगा। – Rob

उत्तर

14

कोड के साथ कई समस्याएं हैं:

  1. स्थान अद्यतन शुरू नहीं कर रहे हैं जब एप्लिकेशन iOS द्वारा शुरू की है।
  2. पृष्ठभूमि स्थान अपडेट अनुरोध नहीं है।
  3. कोड प्राधिकरण स्थिति में परिवर्तन पर निर्भर करता है स्थान अद्यतन
  4. वहाँ didChangeAuthorizationStatus विधि में एक लापता तोड़ बयान है शुरू करने के लिए।

    पहला दस्तावेज एक स्थान प्रबंधक वस्तु पूरी तरह से कॉन्फ़िगर किया जाना चाहिए जब IOS अनुप्रयोग की शुरूआत का कहना है:

यहाँ प्रासंगिक दस्तावेज हैं इसलिए ऐप पर स्थान इवेंट डिलीवर किया जा सकता है।

पुन: लॉन्च करने पर, आपको अभी भी एक स्थान प्रबंधक ऑब्जेक्ट को कॉन्फ़िगर करना होगा और इस विधि को [प्रारंभ मॉनिटरिंग सिग्निफिशेंट लोकेशन चेंज] को स्थान ईवेंट प्राप्त करना जारी रखने के लिए कॉल करना होगा।

इस प्रकार मैं यह सुनिश्चित करने के लिए आमतौर पर ऐसा करता हूं कि आइकन प्रबंधक या आईओएस द्वारा लॉन्च किया गया था (माफ करना मैं ऑब्जेक्टिव सी का उपयोग करता हूं)।

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
// Override point for customization after application launch. 

    NSLog(@"app launching"); 
    bgTask = UIBackgroundTaskInvalid; 

    locationMgr = [[CLLocationManager alloc] init]; 
    [locationMgr setDelegate:self]; 
    if([locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
    [locationMgr setAllowsBackgroundLocationUpdates:YES]; 
    CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
    NSLog(@"relaunching because of significant location change - restarting SLC"); 
    [locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else 
    { 
    if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
     NSLog(@"launching with authorization to always use location - starting SLC"); 
     [locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else 
    { 
     NSLog(@"launching with no authorization to always use location - requesting authorization"); 
     if([locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) 
      [locationMgr requestAlwaysAuthorization]; 
    } 
    } 

    return YES; 
} 

सूचना setAllowsBackgroundLocationUpdates करने के लिए कॉल। यह आईओएस 9 में नया है और यदि आप पृष्ठभूमि में स्थान अपडेट प्राप्त करना चाहते हैं तो ऐप शुरू होने पर हर बार किया जाना चाहिए। (यह एक "मैं मजाक नहीं कर रहा हूं, मुझे पता है कि मैंने पृष्ठभूमि मोड में उनसे पूछा है, लेकिन मैं वास्तव में उन्हें चाहता हूं")।

निलंबित होने पर स्थान अपडेट प्राप्त करना चाहते हैं, तो अपने ऐप की Info.plist फ़ाइल में UIBackgroundModes कुंजी (स्थान मान के साथ) शामिल होना चाहिए और इस प्रॉपर्टी का मान YES पर सेट करना चाहिए।

अंत में आप भरोसा नहीं कर सकते didChangeAuthorizationStatus पर बुलाया जा रहा है। आप प्राधिकरण kCLAuthorizationStatusAuthorizedAlways तो बुला है, तो [locationMgr requestAlwaysAuthorization] प्राधिकरण स्थिति में बदलाव, इसलिए didChangeAuthorizationStatus नहीं कहा जाता है में परिणाम नहीं करता है।

अगर प्राधिकरण स्थिति पहले से ही ज्ञात है जब आप अनुरोध कॉल करते हैं WENInUseAuthorization या requestAlwaysAuthorization विधि, स्थान प्रबंधक इस विधि को वर्तमान प्राधिकरण स्थिति की रिपोर्ट नहीं करता है।

+0

महोदय, आप लाखों वोटों के लायक हैं। धन्यवाद! – brumbrum

+0

कोई समस्या नहीं - ऐप्पल ने आईओएस की हर रिलीज के साथ कोरलोकेशन को सही ढंग से उपयोग करना अधिक कठिन बना दिया है। मुझे लगता है कि यह आईओएस 6 के आसपास बिल्कुल सही था, अब यह सिर्फ आर्केन है। आपकी परियोजना के लिए शुभकामनाएं। – BitByteDog

+1

इसके साथ बहस नहीं कर सकता। एक और बात। मैं अब कुछ दिनों के लिए खेल रहा हूं। ऐप्पल विज्ञापन करता है कि वास्तविक स्थान परिवर्तन के बावजूद, उस महत्वपूर्ण स्थान को कम से कम प्रत्येक 15min ट्रिगर किया जाएगा। अगर मैं हिल नहीं रहा हूं तो मुझे कोई अपडेट नहीं मिल रहा है। क्या आप हर 15 मिनट में अपने ऐप्स में स्थान अपडेट देख रहे हैं, भले ही आप आगे नहीं बढ़ रहे हों? – brumbrum

0

मुझे लगता है कि आप startUpdatingLocation को परवाह किए बिना है? क्या आपने ब्रेकपॉइंट्स डालने का प्रयास किया है यह देखने के लिए कि आप कहां जाते हैं?

+0

अगर मैं startUpdatingLocation को सत्य पर सेट करता हूं तो मुझे प्रति सेकंड 3 अपडेट मिलते हैं। मुझे लगता है कि यह मानक स्थान सेवाओं के लिए केवल मीनी है। मेरे पास नहीं है, क्योंकि यह सिम्युलेटर पर बहुत अच्छा काम करता है। – brumbrum

+0

पृष्ठभूमि में निलंबित ऐप पर ब्रेकपॉइंट्स का उपयोग करना संभव है? – brumbrum

+0

@ krompir2 - नहीं, आप इस मामले में ब्रेकपॉइंट्स का उपयोग नहीं कर सकते हैं। मैं आम तौर पर 'एनएसएलओजी' संदेश (इसलिए मैं कंसोल देख सकता हूं)। मुझे कुछ लगातार स्टोरेज में संदेशों को लॉग इन करने के लिए भी उपयोगी पाया गया है और फिर जब मैं ऐप को अग्रभूमि में लाता हूं, तो इन सहेजे गए संदेशों को टेबल व्यू या कुछ ऐसा दिखाएं, इसलिए मैं निदान कर सकता हूं कि ऐप में क्या नहीं था अग्रभूमि। – Rob

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

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