ios स्वास्थ्यकैट पृष्ठभूमि डिलीवरी जब ऐप नहीं चल रहा है




swift background-process (3)

परीक्षण का पूरा दिन (आईओएस 9.2) के बाद मैं पुष्टि कर सकता हूं कि HealthKit पृष्ठभूमि की डिलीवरी निम्नलिखित सभी अनुप्रयोगों में काम करती है:

  • पृष्ठभूमि (पृष्ठभूमि और कार्यान्वित कोड में),
  • निलंबित (पृष्ठभूमि में लेकिन कोड निष्पादित नहीं),
  • समाप्त (उपयोगकर्ता द्वारा बल-मारे गए या सिस्टम द्वारा शुद्ध किया गया)

ध्यान रखें : भाग 1

कुछ HealthKit डेटा प्रकारों में HKUpdateFrequencyHourly फ्रीक्वेंसी का न्यूनतम अपडेट आवृत्ति है। उसने कहा, भले ही आप आवृत्ति HKUpdateFrequencyImmediate साथ एक पृष्ठभूमि डिलीवरी सेट अप HKUpdateFrequencyImmediate , तो आप प्रत्येक घंटे या उससे अधिक की तुलना में अधिक बार अपडेट नहीं प्राप्त करेंगे।

दुर्भाग्य से, डेटा प्रकार के अनुसार न्यूनतम आवृत्तियों के बारे में दस्तावेज़ीकरण में कोई जानकारी नहीं है, लेकिन Fitness types साथ मेरा अनुभव इस Fitness types था:

  • सक्रिय ऊर्जा: प्रति घंटा ,
  • सायक्लिंग दूरी: तत्काल ,
  • उड़ानें चढ़ गए: तत्काल ,
  • नाइकेफ्यूएल: तत्काल ,
  • कदम: प्रति घंटा ,
  • चलना + रनिंग दूरी: प्रति घंटा ,
  • कार्यवाही: तत्काल

नोट : immediate मतलब वास्तविक समय नहीं है बल्कि गतिविधि डेटा के नमूनों को "कुछ समय बाद ही कुछ समय बाद ही HealthKit डेटाबेस / स्टोर पर लिखा गया है"

ध्यान रखें : भाग 2

यदि डिवाइस को पासकोड के साथ लॉक किया गया है, तो आप में से कोई भी पृष्ठभूमि वितरण पर्यवेक्षकों को नहीं बुलाया जाएगा। यह गोपनीयता की चिंताओं के कारण जानबूझकर है (अधिक पढ़ें: https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Framework/ )

उस ने कहा, जैसे ही उपयोगकर्ता डिवाइस को अनलॉक कर देता है, आपके HealthKit पृष्ठभूमि वितरण पर्यवेक्षकों को बुलाया जाएगा (यदि न्यूनतम आवृत्ति समय बीत चुका है तो)।

नमूना कोड :

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

क्या स्वास्थ्यकिट पृष्ठभूमि वितरण आवेदन शुरू नहीं कर सकता है यदि नहीं चल रहा है? विशेष रूप से एक समाप्त राज्य में?


आईओएस 8.1 में यह करता है आपको यह सुनिश्चित करने की आवश्यकता है कि आप अपने ऐप प्रतिनिधि के application:didFinishLaunchingWithOptions: में अपने पर्यवेक्षक प्रश्नों को पुन: बनाएँ application:didFinishLaunchingWithOptions: यद्यपि। 8.0 में एक बग स्वास्थ्यकिट की पृष्ठभूमि सूचना को बिल्कुल भी काम करने से रोकता है।

संपादित करें:

अपने AppDelegate में :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //create/get your HKHealthStore instance (called healthStore here)
    //get permission to read the data types you need.
    //define type, frequency, and predicate (called type, frequency, and predicate here, appropriately)

    UIBackgroundTaskIdentifier __block taskID = [application beginBackgroundTaskWithExpirationHandler:^{
        if (taskID != UIBackgroundTaskInvalid) {
            [application endBackgroundTask:taskID];
            taskID = UIBackgroundTaskInvalid;
        }
    }];
    [healthStore enableBackgroundDeliveryForType:type frequency:frequency withCompletion:^(BOOL success, NSError *error) {}];
    HKQuery *query = [[HKObserverQuery alloc] initWithSampleType:healthType predicate:predicate updateHandler:
        ^void(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error)
        {
            //If we don't call the completion handler right away, Apple gets mad. They'll try sending us the same notification here 3 times on a back-off algorithm.  The preferred method is we just call the completion handler.  Makes me wonder why they even HAVE a completionHandler if we're expected to just call it right away...
            if (completionHandler) {
                completionHandler();
            }
            //HANDLE DATA HERE
            if (taskID != UIBackgroundTaskInvalid) {
                [application endBackgroundTask:taskID];
                taskID = UIBackgroundTaskInvalid;
            }
        }];
    [healthStore executeQuery:query];
}

यह जवाब कुछ देर है लेकिन मुझे उम्मीद है कि यह लोगों को समझने में मदद करता है कि HKObserverQuery

सबसे पहले HKObserverQuery पृष्ठभूमि मोड में ठीक काम करता है और जब ऐप बिल्कुल बंद होता है । लेकिन आपको कुछ विकल्प पहले सेट करने की आवश्यकता है ताकि सभी को ठीक काम मिल सके।

  1. आपको अपने ऐप की क्षमताओं में पृष्ठभूमि मोड सेट करना होगा। चित्र नीचे देखें:

  1. उसके बाद आपको निम्न जानकारी के रूप में अपनी Required Background Modes में Required Background Modes जोड़ना होगा:

  1. आपको निम्नलिखित तरीके से Background Fetch करने की आवश्यकता है:

    3.1। योजना टूलबार मेनू से, एक आईओएस सिम्युलेटर या डिवाइस चुनें।

    3.2। एक ही मेनू से, योजना को संपादित करें चुनें।

    3.3। बाएं कॉलम में, भागो चुनें।

    3.4। विकल्प टैब का चयन करें

    3.5। पृष्ठभूमि प्राप्त करें चेकबॉक्स का चयन करें और बंद करें पर क्लिक करें।

तब आप सूचनाओं को प्राप्त कर सकते हैं जब ऐप पृष्ठभूमि में है या निम्न कोड का उपयोग करके बंद किया गया है:

import UIKit
import HealthKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

   var window: UIWindow?

   let healthKitStore:HKHealthStore = HKHealthStore()

   func startObservingHeightChanges() {

       let sampleType =  HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)

       var query: HKObserverQuery = HKObserverQuery(sampleType: sampleType, predicate: nil, updateHandler: self.heightChangedHandler)

       healthKitStore.executeQuery(query)
       healthKitStore.enableBackgroundDeliveryForType(sampleType, frequency: .Immediate, withCompletion: {(succeeded: Bool, error: NSError!) in

           if succeeded{
               println("Enabled background delivery of weight changes")
           } else {
               if let theError = error{
                   print("Failed to enable background delivery of weight changes. ")
                   println("Error = \(theError)")
               }
           }
       })
   }


   func heightChangedHandler(query: HKObserverQuery!, completionHandler: HKObserverQueryCompletionHandler!, error: NSError!) {        

       // Here you need to call a function to query the height change

       // Send the notification to the user
       var notification = UILocalNotification()
       notification.alertBody = "Changed height in Health App"
       notification.alertAction = "open"        
       notification.soundName = UILocalNotificationDefaultSoundName   

       UIApplication.sharedApplication().scheduleLocalNotification(notification)

       completionHandler()
   }

   func authorizeHealthKit(completion: ((success:Bool, error:NSError!) -> Void)!) {

       // 1. Set the types you want to read from HK Store
       let healthKitTypesToRead = [
        HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth),
        HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBloodType),
        HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex),
        HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass),
        HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight),
        HKObjectType.workoutType()
       ]

       // 2. Set the types you want to write to HK Store
       let healthKitTypesToWrite = [
        HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex),
        HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned),
        HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning),
        HKQuantityType.workoutType()
       ]

       // 3. If the store is not available (for instance, iPad) return an error and don't go on.
       if !HKHealthStore.isHealthDataAvailable() {
           let error = NSError(domain: "any.domain.com", code: 2, userInfo: [NSLocalizedDescriptionKey:"HealthKit is not available in this Device"])

           if( completion != nil ) {                
               completion(success:false, error:error)
           }
           return;
       }

       // 4.  Request HealthKit authorization
       healthKitStore.requestAuthorizationToShareTypes(Set(healthKitTypesToWrite), readTypes: Set(healthKitTypesToRead)) { (success, error) -> Void in
           if( completion != nil ) {

               dispatch_async(dispatch_get_main_queue(), self.startObservingHeightChanges)
               completion(success:success,error:error)
           }
       }
   }   

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

       application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Badge | .Sound, categories: nil))

       self.authorizeHealthKit { (authorized,  error) -> Void in
           if authorized {
               println("HealthKit authorization received.")
           }
           else {
               println("HealthKit authorization denied!")
               if error != nil {
                   println("\(error)")
               }
           }
       }

       return true
   }      


   //Rest of the defaults methods of AppDelegate.swift   

}

उपरोक्त विधि में HKObserver सक्रिय होता है अगर स्वास्थ्यकिट प्राधिकरण उपयोगकर्ता द्वारा प्रदान किया जाता है और फिर सूचनाओं को सक्रिय करता है।

उम्मीद है इससे आपको मदद होगी।







health-kit