6

मेरे पास इस विषय के साथ एक बड़ा सिरदर्द है। मैं एक ऐसे एप्लिकेशन पर काम कर रहा हूं जिसे नए डेटा की जांच करने के लिए नियमित रूप से वेबसर्वर को मतदान करने की आवश्यकता है। लौटाई गई जानकारी के आधार पर, मैं उपयोगकर्ता को स्थानीय अधिसूचना को धक्का देना चाहता हूं।setKeepAliveTimeout और BackgroundTasks

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

मैंने देखा कि ऐप्पल अनुप्रयोगों के लिए जागने और सॉकेट कनेक्शन खोलने का अवसर प्रदान करता है (यानी एक वीओआईपी आवेदन)।

तो, मैंने इस तरह से जांच शुरू कर दी। plist में आवश्यक जानकारी जोड़ा गया, मैं अपने आवेदन "जाग" करने में सक्षम हूँ, मेरे AppDelegate में कुछ इस तरह का उपयोग कर:

[[UIApplication sharedApplication] setKeepAliveTimeout:1200 handler:^{ 
    NSLog(@"startingKeepAliveTimeout"); 
    [self contentViewLog:@"startingKeepAliveTimeout"]; 
    MyPushOperation *op = [[MyPushOperation alloc] initWithNotificationFlag:0 andDataSource:nil]; 
    [queue addOperation:op]; 
    [op release]; 
}]; 

NSOperation, उसके बाद निम्न ब्लॉक कोड का उपयोग कर एक पृष्ठभूमि कार्य शुरू होता है:

#pragma mark SyncRequests 
-(void) main { 
    NSLog(@"startSyncRequest"); 
    [self contentViewLog:@"startSyncRequest"]; 
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
     NSLog(@"exipiration handler triggered"); 
     [app endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
     [self cancel]; 
    }]; 


     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      NSMutableURLRequest *anURLRequest; 
      NSURLResponse *outResponse; 
      NSError *exitError; 
      NSString *username; 
      NSString *password; 

      NSLog(@"FirstLogin"); 
      anURLRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:webserverLogin, username, password]]]; 
      [anURLRequest setHTTPMethod:@"GET"]; 
      [anURLRequest setTimeoutInterval:120.00]; 
      [anURLRequest setCachePolicy:NSURLRequestReloadIgnoringCacheData]; 

      exitError = nil; 
      NSData *tmpData = [NSURLConnection sendSynchronousRequest:anURLRequest returningResponse:&outResponse error:&exitError]; 
      [anURLRequest setTimeoutInterval:120.00]; 
      if(exitError != nil) { //somethings goes wrong 
       NSLog(@"somethings goes wrong"); 
       [app endBackgroundTask:bgTask]; 
       bgTask = UIBackgroundTaskInvalid; 
       [self cancel]; 
       return; 
      } 

      //do some stuff with NSData and prompt the user with a UILocalNotification 

      NSLog(@"AlltasksCompleted"); 
      [app endBackgroundTask:bgTask]; 
      bgTask = UIBackgroundTaskInvalid; 
      [self cancel]; 
     }); 
    } 
} 

ऊपर कोड काम करने के लिए (कभी कभी) लगता है, लेकिन कई अन्य इसे अपने आवेदन दुर्घटनाओं, निम्नलिखित लॉग जानकारी के साथ:

Exception Type: 00000020 
Exception Codes: 0x8badf00d 
Highlighted Thread: 3 

Application Specific Information: 
DemoBackApp[5977] has active assertions beyond permitted time: 
{(
    <SBProcessAssertion: 0xa9da0b0> identifier: UIKitBackgroundCompletionTask process: DemoBackApp[5977] permittedBackgroundDuration: 600.000000 reason: finishTask owner pid:5977 preventSuspend preventIdleSleep 
)} 

Elapsed total CPU time (seconds): 0.010 (user 0.010, system 0.000), 100% CPU 
Elapsed application CPU time (seconds): 0.000, 0% CPU 

जो पूछना के लिए, हाँ। मैंने Async NSURLConnection दृष्टिकोण भी कोशिश की है। कोई बात नहीं। यह वही दुर्घटनाग्रस्त है, भले ही मैं टाइमआउट हैंडलर के साथ एसिंक दृष्टिकोण का उपयोग करता हूं और कियाफिशिश लोडिंग: WithError।

मैं अटक गया हूँ। किसी भी संकेत की सराहना की जाती है।

उत्तर

7

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

वीओआईपी कॉलबैक के साथ, आपको बस नेटवर्क कनेक्शन को जीवंत रखने के लिए आपको जो भी पिंग पैकेट भेजना होगा, उसे समय-समय पर भेजना होगा -बाहर। 30 सेकंड के बाद, नए पृष्ठभूमि कार्यों को शुरू करने के बावजूद, यदि आपका एप्लिकेशन अभी भी निष्पादित है, तो आपको समाप्त कर दिया जाएगा।

इसके अलावा, यह ध्यान देना महत्वपूर्ण है कि अगर आप अपने एप्लिकेशन यदि आप वीओआइपी कॉलबैक खिड़की है कि अपने नेटवर्क कनेक्शन खुला रखने से संबंधित नहीं है के दौरान कुछ भी वास्तव में नहीं एक वीओआइपी आवेदन या कर रहे हैं, होगा हो ऐप स्टोर से खारिज कर दिया गया। जब आप किसी भी जीवित सक्रिय झंडे (वीओआईपी, पृष्ठभूमि संगीत, नेविगेशन) सेट करते हैं, तो वे यह सुनिश्चित करने के लिए बहुत कठोर परीक्षण करते हैं कि केवल पृष्ठभूमि में होने पर इसे फ़्लैग करने के लिए फ़्लैग किया जाता है। किसी भी तरह का HTTP GET अनुरोध करना और वापस आने के लिए कुछ बड़े डेटा अपडेट की प्रतीक्षा करना लगभग आपके ऐप को अस्वीकार करने की गारंटी है।

संपादित करें: जैसा कि टिप्पणियों में पैट्रिक ने उल्लेख किया है, निष्पादन के लिए ब्लॉक को दिया गया वर्तमान समय आईओएस 5 के साथ 30 सेकंड से 10 सेकंड तक घटा दिया गया है।जब भी आप एसडीके के नए संस्करण के लिए अपने आवेदन को फिर से लिंक करते हैं, तो इन समय पर नजर रखना एक अच्छा विचार है, हमेशा कम से कम तुरंत अपडेट किए जाने पर दस्तावेज़ों की जांच करें (आईओएस 6 आने के साथ, यह संख्या हो सकती है फिर से tweaked)।

+0

आपके उत्तर के लिए बहुत धन्यवाद। सबसे पहले, अस्वीकार कोई मुद्दा नहीं है, क्योंकि ऐप ऐपस्टोर के लिए एक निजी ऐप नहीं है। 30secs के टाइमआउट के बारे में, मैंने इसके बारे में पढ़ा, लेकिन मुझे समझ में नहीं आ रहा है कि क्रैश लॉग मुझे 600.00secs टाइमआउट के बारे में बताता है, न कि 30.00secs। इसके अलावा, कभी-कभी विधियां काम करती हैं, अन्य वे नहीं करते हैं। – valvoline

+0

@valvoline: जिस बार यह काम नहीं करता है, आप पृष्ठभूमि कार्य स्पष्ट रूप से बहुत अधिक समय ले रहे हैं। दस्तावेज़ 30 सेकंड कहते हैं, लेकिन शायद यह नरम संख्या है और ओएस वास्तव में आपको 10 मिनट देता है, मुझे यकीन नहीं है। हम जानते हैं कि, कुछ बिंदु पर कुछ अवरुद्ध हो रहा है और आपकी बात पूरी नहीं हो सकती है, और चूंकि VIOP को त्वरित जांच के लिए डिज़ाइन किया गया था, इसलिए यह संभव है कि ओएस से होने वाली त्रुटि उलझन में है (जैसे कि आपके रद्दीकरण ब्लॉक या कुछ को कॉल न करें) । –

+0

@ जेसन: क्या आपके पास इस वीओआईपी विंडो में क्या आवश्यक है इसके बारे में कोई विशिष्ट जानकारी है? क्या यह कहता है कि कहीं भी सार्वजनिक? –

3

ऐसा लगता है कि आप जीवित टाइमआउट हैंडलर को संयोजित करने में सक्षम हो सकते हैं जब आप कॉल करते समय सीमित पृष्ठभूमि कार्य निष्पादन के लिए अनुरोध करते हैं। जब भी वीओआईपी जीवित हैंडलर को बुलाया जाता है तो यह आपको 10 मिनट पूर्ण करने की अनुमति देगा (सामान्य 10-30 सेकंड के विपरीत)।

अभी भी उतनी ही समस्या है - इसमें आपको अपनी प्लेलिस्ट में वीओआईपी ध्वज की आवश्यकता है, और यदि आपके पास वह ध्वज है और वास्तव में वीओआईपी आवेदन नहीं है, तो ऐप्पल आपके आवेदन को स्वीकार करने की संभावना नहीं है, लेकिन आंतरिक के लिए वितरण (उद्यम या अन्यथा), इस समाधान को आपको पृष्ठभूमि समय देने के लिए ठीक काम करना चाहिए।

मेरे परीक्षणों में, 10 मिनट सीमित निष्पादन टाइमर हर बार वीओआईपी हैंडलर कहलाता है (चाहे उपयोगकर्ता ने तब से आवेदन को सामने लाया हो) या फिर इसका मतलब यह हो कि आप अपने सर्वर को मतदान कर सकते हैं अनिश्चित काल तक पृष्ठभूमि में जबकि हर 600 सेकंड (10 मिनट) में और सोने की प्रक्रिया में सोने की प्रक्रिया में 10 मिनट तक का समय लग सकता है (जिसका मतलब है कि यदि आप की आवश्यकता होती है तो लगभग स्थिर पृष्ठभूमि ऑपरेशन)।

फिर से, ऐप स्टोर के लिए वास्तव में एक विकल्प नहीं है जबतक कि आप उन्हें मनाने में सक्षम नहीं हैं आप वीओआईपी हैं।

+0

क्या आप निष्पादन टाइमर को मैन्युअल रूप से अपनेसेट में रीपेट कर रहे हैं KeepAliveTimeout 'हैंडलर? क्या आप इसके लिए कुछ उदाहरण कोड प्रदान कर सकते हैं? मैं एक ही स्थिति में हूं, वीओआईपी का उपयोग कर (ऐपस्टोर में जमा नहीं होने वाला)। मेरा निष्पादन टाइमर स्वचालित रूप से सेट नहीं हो रहा है जब ऐप कोKKAliveTimeout द्वारा जगाया जाता है। ऐसा लगता है कि मैं इसे एक नया पृष्ठभूमि कार्य बनाकर इसे रीसेट कर सकता हूं जैसे कि मेरे 'एप्प्लिकेशनडिएन्टरबैकग्राउंड' में। – reekris

+0

हां, प्रत्येक बार सेटकिपअलीवटाइमआउट कहा जाता है, मैं एक नया परिमित पृष्ठभूमि कार्य बनाता हूं (जो कि चलाने के लिए ताजा 10 मिनट लग रहा है)। – BadPirate

8

यह एक पुराना धागा है, लेकिन एक अद्यतन वारंट कर सकता है।

iOS 6 के रूप में, इस व्यवहार के रूप में इस धागे में चर्चा मैं वीओआईपी टाइमर पृष्ठभूमि के तरीकों के साथ देख रहा हूँ है:

  • वीओआईपी BackgroundMode अभी भी सख्ती से अनुप्रयोग समीक्षा प्रक्रिया के माध्यम से
  • AppStore क्षुधा से प्रतिबंधित कर दिया गया है
  • न्यूनतम KeepAlive समय 600 सेकंड है; इससे कम कुछ भी हैडलर को स्थापित करने में विफल होने का कारण बनता है (और एनएसएलओजी को चेतावनी भेजी जाती है)
  • रखरखाव समय को 600 सेकंड से काफी बड़ा करने के लिए सेट करना आम तौर पर हैंडलर को हर समय की आवृत्ति के साथ निकाल दिया जाएगा/2 अंतराल। बोनस तथ्य: यह एसआईपी रजिस्ट्रार अनुरोध के अनुरूप है, जिसमें अनुशंसित पुन: पंजीकरण अंतराल है .5 * पुनः पंजीकरण समय।
    • आप के बारे में 10 सेकंड की "अग्रभूमि" निष्पादन समय, जिसमें शेष पृष्ठभूमि समय अनंत है (जैसा कि backgroundTimeRemaining द्वारा दिया) मिलती है:
    • जब आपके KeepAlive हैंडलर कहा जाता है, मैं निम्नलिखित मनाया
    • यदि आप KeepAlive हैंडलर के भीतर से एक beginBackgroundTask शुरू हुआ, मैं देखा है कि आप 60 सेकंड पृष्ठभूमि निष्पादन समय की मिल (के रूप में backgroundTimeRemaining द्वारा दिया)। यह 600 सेकंड से अलग है जब आप उपयोगकर्ता को अपने ऐप से पृष्ठभूमि में सक्रिय होने पर संक्रमण करते हैं। मैं (स्थान आदि जैसे अन्य चाल का उपयोग कर के बिना) इस समय का विस्तार करने के लिए किसी भी तरह नहीं मिला है

आशा है कि मदद करता है!

5

आईओएस 7 के लिए इस व्यवहार को अपडेट करने के लिए बस।

  • अपने अनुप्रयोग पहले पृष्ठभूमि में चला जाता है जब आप कार्य समय के 180 सेकंड के रूप में backgroundTimeRemaining द्वारा रिपोर्ट मिलता है। हालांकि, यह पृष्ठभूमि टाइमरेमेनिंग द्वारा रिपोर्ट किए गए 5 सेकंड पर प्रतिक्रिया देने से पहले को रोकता है।
  • जब KeepAlive कार्य को आग लगती है तो पृष्ठभूमि टाइममैनिंग 10 अग्रभूमि के सेकंड के बाद पृष्ठभूमि टाइमर के 60 सेकंड के बाद पृष्ठभूमि टाइमर द्वारा रिपोर्ट की गई के रूप में होती है। यह पृष्ठभूमि टाइममैनिंग द्वारा रिपोर्ट के अनुसार इस बार समाप्त होने से पहले 5 सेकंड पर प्रतिक्रिया देना बंद कर देता है।

तो आईओएस 7 पर आप हर 10 मिनट में 65 सेकंड प्रोसेसिंग समय प्राप्त कर सकते हैं।

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