2012-08-22 7 views
37

में पहले से चल रहे कार्य के लिए startBackgroundTaskWithExpirationHandler का उपयोग कैसे करें मेरे ऐप में, मैं आईफोन से सर्वर पर छवियां अपलोड कर रहा हूं। सिंक करते समय उपयोगकर्ता होम बटन दबाएगा, ऐप बंद हो जाएगा।आईओएस

मुझे ऐप को सिंक खत्म होने तक पृष्ठभूमि में चलाना चाहिए।

मेरा प्रश्न है: मैं वर्तमान में "beginBackgroundTaskWithExpirationHandler" के साथ कैसे चल रहा कार्य जोड़ सकता हूं?

कृपया अपने विचार साझा करें।

उत्तर

13

मैं पृष्ठभूमि कार्य हैंडलर के लिए नीचे दिए गए कोड का प्रयोग किया:

__block UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 

    NSLog(@"Background Time:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]); 

    [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier]; 

    backgroundTaskIdentifier = UIBackgroundTaskInvalid; 
}]; 
+1

[self endBackgroundTask] विधि क्या करती है? स्वयं क्या है – ozgur

+0

@ozgurv: अपडेट किया गया कोड। धन्यवाद – Vardhan

1

आपको beginBackgroundTaskWithExpirationHandler के बाद अपना कार्य चलाना चाहिए या एप्लिकेशन को ऐप की स्थिति पृष्ठभूमि में बदलते समय अधिसूचना कैप्चर करना चाहिए और फिर अपना वर्तमान कार्य रद्द करें और beginBackgroundTaskWithExpirationHandler के साथ फिर से चलाएं।

95

इसके नाम के बावजूद, beginBackgroundTaskWithExpirationHandler: वास्तव में एक कार्य शुरू नहीं करता है। यह "शुरूआत" के बजाय "रजिस्टर ..." के बारे में बेहतर विचार हो सकता है। आप बस सिस्टम को बता रहे हैं कि आप ऐसा कुछ करने के बीच में हैं जो ठीक है अगर यह ठीक करना है।

कई अंक:

  • लगभग सभी मामलों में, आप beginBackgroundTaskWithExpirationHandler: कॉल करने के लिए जब आप बात आप क्या करना चाहते शुरू कर चाहते हैं और फिर endBackgroundTask: आपका काम पूरा हो। आप लगभग इस बिंदु पर कभी भी कॉल नहीं करते हैं कि उपयोगकर्ता होम बटन दबाता है (जब तक कि आप कार्य शुरू नहीं करते हैं, जैसे कि सर्वर को कुछ सहेजना)।

  • आपके पास एक समय में खुले होने के रूप में कई "पृष्ठभूमि कार्य" हो सकते हैं। उन्हें कुछ भी लागत नहीं है। वे गिनती की तरह हैं। जब तक आपके पास अभी भी एक खुला है (एक "प्रारंभ" जो इसके "अंत" तक नहीं पहुंचता), तो सिस्टम अधिक समय के लिए अनुरोध पर विचार करेगा। "प्रारंभ" और "अंत" विधियों को कॉल करने के लिए बहुत कम लागत है, इसलिए इन्हें किसी भी चीज़ को ब्रैकेट करने के लिए उपयोग करें जिसे आप समाप्त करने के लिए अतिरिक्त समय चाहते हैं।

  • यह सुनिश्चित करने का कोई तरीका नहीं है कि आप अपना सिंक पूरा कर लेंगे। ये विधियां सिर्फ एक अनुरोध करें। ओएस अभी भी उस अनुरोध को अस्वीकार कर सकता है। ओएस अभी भी आपको मार सकता है जब भी इसे कुछ अतिरिक्त संसाधनों की आवश्यकता होती है। ओएस असीम रोगी नहीं है; यदि आप बहुत अधिक समय लेते हैं (आमतौर पर लगभग 10 मिनट), तो यह आपके समाप्ति हैंडलर को कॉल करने के बाद भी आपको मार देगा। ओएस आपको मार सकता है क्योंकि फोन बंद हो रहा है। आपका ऐप खत्म होने के साथ निपटने में सक्षम होना चाहिए। ओएस आपको यह क्षमता देता है ताकि आप उपयोगकर्ता अनुभव को बेहतर बना सकें।

+16

आपका उत्तर पूरी तरह से भयानक, thanx आदमी है। बस एक अपडेट: आईओएस 7 के बाद से आपके पास पृष्ठभूमि कार्यों के लिए केवल 3 मिनट हैं, अब 10 नहीं। –

+0

क्या ऐप पृष्ठभूमि पर ब्लूटूथ डिवाइस स्कैनिंग के साथ startBackgroundTaskWithExpirationHandler का उपयोग करने की सलाह दी जाती है? – theFool

+0

ब्लूटूथ पृष्ठभूमि स्कैनिंग आमतौर पर पृष्ठभूमि मोड ब्लूटूथ-सेंट्रल के साथ पंजीकरण करके बेहतर किया जाता है। आम तौर पर स्कैनिंग "इस" शिविर को खत्म करने के लिए थोड़ा और समय चाहिए "में नहीं आती है। –

8

यहाँ कैसे मैं beginBackgroundTaskWithExpirationHandler इस्तेमाल किया, विधि करने के लिए कॉल पृष्ठभूमि में किया जाना भी शामिल है। इसमें नया एसिंक कार्य शुरू करने के लिए कोड शामिल है। तो सवाल में बिल्कुल क्या नहीं पूछा जाता है। नीचे दिए गए कोड को जोड़ने, किसी सोच इस परिदृश्य की तलाश में हो सकता है:

- (void)didReceiveObjList:(CFDataRef)message 
{ 
    // Received Object List. Processing the list can take a few seconds. 
    // So doing it in separate thread with expiration handler to ensure it gets some time to do  the task even if the app goes to background. 

    UIApplication *application = [UIApplication sharedApplication]; 
    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ 
    [application endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [self processObjList:message]; 

    [application endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
    }); 

    NSLog(@"Main Thread proceeding..."); 

} 
5

इस पेज पर एक नजर डालें, एप्पल आईओएस कैसे आवेदन रखने के लिए निलंबित नहीं, पृष्ठभूमि में है का वर्णन। Apple Documentation

और यहाँ मैं क्या इसलिए लगाए गए हैं:

UIBackgroundTaskIdentifier bgTask; 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
    NSLog(@"=== DID ENTER BACKGROUND ==="); 
    bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 
     NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'"); 
     // [self askToRunMoreBackgroundTask]; This code seems to be unnecessary. I'll verify it. 
    }]; 

    if (bgTask == UIBackgroundTaskInvalid) { 
     NSLog(@"This application does not support background mode"); 
    } else { 
     //if application supports background mode, we'll see this log. 
     NSLog(@"Application will continue to run in background"); 
    } 
} 

/* 

- (void)askToRunMoreBackgroundTask 
{ 
    [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 
    NSLog(@"restart background long-running task"); 
    bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 
     NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'"); 
     [self askToRunMoreBackgroundTask]; 
    }]; 

} 

*/ 

- (void)applicationWillEnterForeground:(UIApplication *)application 
{ 
    NSLog(@"=== GOING BACK FROM IDLE MODE ==="); 
    //it’s important to stop background task when we do not need it anymore 
    [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid]; 
} 
3

यहाँ अन्य उत्तर जो मैं जब एप्लिकेशन को पृष्ठभूमि करने जा रहा है उपयोग कर रहा हूँ पर थोड़ा अंतर है और मैं पर कुछ करने की ज़रूरत है मुख्य धागा:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    UIApplication *app = [UIApplication sharedApplication]; 

    // Register auto expiring background task 
    __block UIBackgroundTaskIdentifier bgTaskId = 
     [app beginBackgroundTaskWithExpirationHandler:^{ 
     [app endBackgroundTask:bgTaskId]; 
     bgTaskId = UIBackgroundTaskInvalid; 
    }]; 

    // Execute background task on the main thread 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // ------------------ 
     // DO SOMETHING INVOLVING THE WEBVIEW - WHICH MUST OCCUR ON THE MAIN THREAD! 
     // ------------------ 
     [app endBackgroundTask:bgTaskId]; 
     bgTaskId = UIBackgroundTaskInvalid; 
    }); 
}