2016-03-22 11 views
11

पर स्थान अपडेट करने के लिए पृष्ठभूमि में हमेशा के लिए एक स्विफ्ट 2.0 ऐप चलाएं मैंने नीचे दिया गया कोड लिखा है जिसमें एक टाइमर है जो प्रत्येक मिनट कॉलबैक फ़ंक्शन को कॉल करता है। जब ऐप पृष्ठभूमि में जाता है तो मैंने एक और टाइमर शुरू किया है जो एक ही कॉलबैक विधि को कॉल करता है, लेकिन पृष्ठभूमि टाइमर केवल तीन मिनट के लिए काम करता है।सर्वर

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

मैंने सीखा कि beginBackgroundTaskWithExpirationHandler का उपयोग किया जाना है, लेकिन मुझे नहीं पता कि मेरा कार्यान्वयन सही है या नहीं।

नोट: मेरे पास स्थान अपडेट के लिए plist toApp रजिस्टरों में आवश्यक पृष्ठभूमि मोड आवश्यक हैं।

कोई भी कामकाजी कोड या लिंक की बहुत सराहना की जाती है।

override func viewDidLoad() { 
    super.viewDidLoad() 

    timeInMinutes = 1 * 60 

    self.locationManager.requestAlwaysAuthorization() 

    self.locationManager.requestWhenInUseAuthorization() 

    if CLLocationManager.locationServicesEnabled() { 
     locationManager.delegate = self 
     locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters 
     locationManager.startUpdatingLocation() 
    } 

    var timer = NSTimer.scheduledTimerWithTimeInterval(timeInMinutes, target: self, selector: "updateLocation", userInfo: nil, repeats: true) 
} 

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){ 
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate 

    self.latitude = locValue.latitude 
    self.longitude = locValue.longitude 

    if UIApplication.sharedApplication().applicationState == .Active { 

    } else { 
     backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({() -> Void in 
      self.backgroundTimer.invalidate() 
      self.backgroundTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: "updateLocation", userInfo: nil, repeats: true) 
     }) 
    } 
} 

func updateLocation() { 
    txtlocationLabel.text = String(n) 
    self.n = self.n+1 

    var timeRemaining = UIApplication.sharedApplication().backgroundTimeRemaining 

    print(timeRemaining) 

    if timeRemaining > 60.0 { 
     self.GeoLogLocation(self.latitude,Longitude: self.longitude) { 
      results in 
      print("View Controller: \(results)") 
      self.CheckResult(String(results)) 
     } 
    } else { 
     if timeRemaining == 0 { 
      UIApplication.sharedApplication().endBackgroundTask(backgroundTaskIdentifier) 
     } 

     backgroundTaskIdentifier2 = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({() -> Void in 
      self.backgroundTimer.invalidate() 
      self.backgroundTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: "updateLocation", userInfo: nil, repeats: true) 
     }) 
    } 
} 

उत्तर

16

समय-समय पर स्थान अद्यतन थोड़ा IOS.There के एक अच्छा सूत्र में मुश्किल यह है कि इस पर चर्चा करता है, तो आप पढ़ सकते हैं कर रहे हैं और अधिक here

आईओएस कुछ ही मिनटों के बाद आपके ऐप को समाप्त कर देगा, भले ही कोई अपने टाइमर चल रहा है या नहीं। हालांकि इसके आसपास एक तरीका है, मुझे आयनिक ऐप लिखते समय कुछ ऐसा करना था ताकि आप इस here के लिए कोड देख सकें, उस लिंक में एक तेज श्रेणी है जो आईओएस में आवधिक स्थान अपडेट प्रबंधित करती है।

पृष्ठभूमि में आवधिक स्थान प्राप्त करने के लिए, और डिवाइस की बैटरी को निकालने के लिए, आपको स्थान रिकॉर्ड्स की सटीकता के साथ खेलने की आवश्यकता है, स्थान प्रबंधक की सटीकता को कम करने के लिए इसकी वांछितता केसीएलएलोकेशनएक्चुरिटी थ्रीकिलोमीटर, प्रत्येक 60 सेकंड में आपको सटीकता को KCLLocationAccuracyBest में बदलने की आवश्यकता होती है, इससे प्रतिनिधि को नया, सटीक स्थान अपडेट प्राप्त करने में सक्षम किया जाएगा, फिर सटीकता को वापस कम करें। अद्यतन प्राप्त होने पर टाइमर को आरंभ करने की आवश्यकता होती है।

उपयोगकर्ता द्वारा मारने के बाद पृष्ठभूमि में ऐप को जागने का एक तरीका भी है, ऐप प्रतिनिधि का उपयोग करें ताकि ऐप को मारने से पहले स्थान में महत्वपूर्ण बदलावों को सुन सके। यह पृष्ठभूमि में ऐप को जगाएगा जब उपयोगकर्ता का स्थान एक बड़ी छलांग बनाता है (लगभग 200ms हो सकता है)। जब ऐप जागता है, महत्वपूर्ण परिवर्तनों के लिए निगरानी रोकें और आवधिक अपडेट जारी रखने के लिए सामान्य रूप से स्थान सेवाओं को पुनरारंभ करें।

उम्मीद है कि इससे मदद मिलती है।

अद्यतन

स्विफ्ट 2 में आप भी आवश्यकता होगी:

self.locationManager.allowsBackgroundLocationUpdates = true 
+0

सहायता के लिए धन्यवाद ... मैं स्विफ्ट के लिए काफी नया हूं ... मैंने कहा कि मैंने हर 60 सेकंड में सटीकता मान को बदलने का प्रयास किया है ... मुझे अभी भी वही परिणाम मिल रहा है (यानी ऐप केवल रन और अपडेट करता है पृष्ठभूमि के तीन मिनट बाद) – Carey

+1

हैलो, माफ करना, मैं उल्लेख करना भूल गया, और मेरा मानना ​​है कि यह आपके कोड में गायब है, आपको अपने स्थान प्रबंधक में बैकग्राउंड स्थानों को भी सक्षम करना होगा, स्वयं। locationManager की तरह कुछ।अनुमति देता है बैकग्राउंडस्थान स्थान = सही –

+0

बहुत बहुत धन्यवाद। यह काम किया! – Carey

0

आप background location tracking के लिए पुस्तकालय का उपयोग कर सकते, उपयोग की उदाहरण:

var backgroundLocationManager = BackgroundLocationManager() 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { 

    backgroundLocationManager.startBackground() { result in 
      if case let .Success(location) = result { 
       LocationLogger().writeLocationToFile(location: location) 
      } 
    } 

    return true 
} 

यह काम कर रहा है जब अनुप्रयोग है मारे गए या निलंबित