2012-09-17 29 views
12

नहीं भेज रहा है मेरे ऐप को पृष्ठभूमि में उपयोगकर्ताओं के स्थान को ट्रैक करने की आवश्यकता है लेकिन यह 'get' अनुरोध भेजने में विफल रहा है। जब ऐप अग्रभूमि में आता है तो http अनुरोध तत्काल भेजा जाता है। मैं अपने सभी नेटवर्क अनुरोधों के लिए RestKit का उपयोग कर रहा हूं और मैंने अपनी पृष्ठभूमि स्थान सेवा सेट अप करने के लिए this tutorial का पालन किया। मेरी applicationDidEnterBackgroundआईओएस पृष्ठभूमि स्थान http अनुरोध

-(void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    self.bgLocationManager = [[CLLocationManager alloc] init]; 
    self.bgLocationManager.delegate = self; 
    [self.bgLocationManager startMonitoringSignificantLocationChanges]; 
    NSLog(@"Entered Background"); 
} 

में और मैं अपने applicationDidBecomeActive प्रतिनिधि में stopMonitoringSignificantLocationChange

यह मेरा locationManager प्रतिनिधि जहां मैं नए अपडेट किए गए स्थान को स्वीकार करने और

-(void) locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
    NSLog(@"I am in the background"); 
    bgTask = [[UIApplication sharedApplication] 
       beginBackgroundTaskWithExpirationHandler: 
       ^{ 
         [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 
       }]; 
       // ANY CODE WE PUT HERE IS OUR BACKGROUND TASK 

    NSString *currentLatitude = [[NSString alloc] 
            initWithFormat:@"%g", 
            newLocation.coordinate.latitude]; 
    NSString *currentLongitude = [[NSString alloc] 
            initWithFormat:@"%g", 
            newLocation.coordinate.longitude]; 
    NSString *webToken = [[NSUserDefaults standardUserDefaults] stringForKey:@"userWebToken"]; 
    NSLog(@"I am in the bgTask, my lat %@", currentLatitude); 

    NSDictionary *queryParams; 
    queryParams = [NSDictionary dictionaryWithObjectsAndKeys:webToken, @"auth_token", currentLongitude, @"lng", currentLatitude, @"lat", nil]; 
    RKRequest* request = [[RKClient sharedClient] post:@"/api/locations/background_update" params:queryParams delegate:self]; 
    //default is RKRequestBackgroundPolicyNone 
    request.backgroundPolicy = RKRequestBackgroundPolicyContinue; 

    // AFTER ALL THE UPDATES, close the task 

    if (bgTask != UIBackgroundTaskInvalid) 
    { 
     [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
    } 
} 

नेटवर्क काम करता है का अनुरोध करता है अपने सर्वर पर भेज है योजना के रूप में लेकिन यह पृष्ठभूमि में नहीं बुलाया जाएगा। क्या मुझे कोई अतिरिक्त कदम चाहिए? मेरी info.plist में मेरे पास आवश्यक पृष्ठभूमि मोड कुंजी और स्थान-सेवाएं मान के रूप में हैं।

संपादित

मैं भी this past SO answer करने के लिए भेजा। मैंने पूरे अपडेटेट टोलोकेशन कॉल में लॉग डालने के साथ कुछ परीक्षण चलाए और उन्हें सभी को बुलाया गया लेकिन 'प्राप्त' अनुरोध नहीं भेजा गया था। इसके बजाय जब मैंने अंततः अग्रभूमि में ऐप लॉन्च किया तो उसने सभी नेटवर्क अनुरोधों (10 से अधिक) भेजे।

EDIT (2) मैंने अपने अनुरोध के लिए आरकेआरक्वेटबैकग्राउंड पॉलिसीकंटिन को जोड़ा लेकिन यह मेरे नतीजे नहीं बदले। (जैसा कि आप रीस्टकिट के लिए पृष्ठभूमि अपलोड/डाउनलोड में here देख सकते हैं)। मुझे लगता है कि रेस्टकिट होस्ट को प्रारंभ करता है लेकिन ऐप सक्रिय होने तक अनुरोध भेजने में विफल रहता है।

उत्तर

RestKit कुछ है कि पृष्ठभूमि में निषिद्ध है कर रही होगी। NSURLRequest का उपयोग पूरी तरह से काम करता है।

NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com/api/locations/background_update"]]; 
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
[urlRequest setHTTPMethod:@"POST"]; 
[urlRequest setHTTPBody:jsonData]; 

NSHTTPURLResponse *response = nil; 
[NSURLConnection sendSynchronousRequest:urlRequest 
         returningResponse:&response 
            error:&error]; 

यह इससे पहले कि आप में प्रवेश के बाद से वहाँ पृष्ठभूमि कार्य के साथ बाधित करने के लिए कोई यूआई है एक तुल्यकालिक अनुरोध का उपयोग करने के

+0

क्या आपके बाकी की जगहों को स्टॉक सिंक्रोनस NSURLConnection के साथ बदलने का प्रयास करें? – dklt

+0

मैं डीकेएलटी के सवाल से सहमत हूं, क्योंकि ऐसा लगता है कि '[[आरके क्लाइंट साझा क्लाइंट] पोस्ट पर कॉल: पैराम्स: प्रतिनिधि:]' ऐसा कुछ होने का कारण बन रहा है जो दृश्यों के पीछे जीसीडी-कतार पर हो सकता है जो कवर नहीं है आपकी पृष्ठभूमि टास्क ब्रैकेटिंग ... और आपके डेटा को प्राप्त करने के लिए सिंक्रोनस कॉल पृष्ठभूमि कार्य में अनुरोध भेजे जाने पर अनुरोध कर सकते हैं। हां, RKRequestBackgroundPolicyContinue इसका ख्याल रखने के लिए हो सकता है, लेकिन आप पोस्ट करने के बाद कॉलिंग के बाद इसे वास्तव में सेट नहीं कर रहे हैं: पैराम्स: प्रतिनिधि:, और उस बिंदु तक, यह बहुत देर हो सकती है। –

+0

@dklt मैं इसे NSRLConnection अनुरोध के साथ काम करने में सक्षम था, सुझाव के लिए धन्यवाद। यदि आप उत्तर देते हैं तो मैं इसे स्वीकार करूंगा। –

उत्तर

3

फिर से बनाने का उत्तर

के रूप में मूल सुझाव आपके restKit की जगह अपने कोशिश है एक शेयर तुल्यकालिक NSURLConnection के साथ कहता है? - डीकेएलटी 20 सितंबर

-1

जब आप आवेदन पृष्ठभूमि में चल रहा हो तो आप एक HTTP अनुरोध आप आरंभ समाप्त कर सकते हैं ठीक है पृष्ठभूमि लेकिन आप नया अनुरोध शुरू नहीं कर सकते हैं। पृष्ठभूमि (वीओआईपी, न्यूजस्टैंड) में आप केवल certain network operations शुरू कर सकते हैं।

+0

आपके उत्तर के लिए धन्यवाद, मैं अभी भी इस विषय पर विवादित जानकारी देख रहा हूं। इस पिछले SO उत्तर को देखें, http://stackoverflow.com/questions/5394880/can-iphone-app-woken-in-background-for-ignificant-location-change-do-network-ac –

+0

@KyleC वह क्या है कह रहा है, अगर आपको अपना HTTP अनुरोध (जिसे आपने अग्रभूमि में शुरू किया था) आपके ऐप को समाप्त होने से पहले समाप्त नहीं होता है, तो आपको शुरुआत बैकग्राउंड टास्कविथ एक्स्पेरेशन हैंडलर: विधि का उपयोग करके अनुरोध को पूरा करने के लिए अतिरिक्त समय का अनुरोध करना चाहिए। यह विधि अतिरिक्त समय की अनुमति देती है जब आपके द्वारा शुरू किए गए किसी भी कार्य को पूरा करने के लिए पृष्ठभूमि में प्रवेश करना और समाप्त करना चाहते हैं, लेकिन आप इस स्थिति में नए HTTP अनुरोधों को प्रारंभ नहीं कर सकते हैं, मुझे यह समय 5 सेकंड से कहीं भी दूरी पर मिला है 10 मिनटों। – Shizam

+2

मैं उस भाग को समझता हूं और मुझे पता है कि विधि शुरू होती है बैकग्राउंड टास्कविथ एक्स्पेरेशन हैंडलर: जब आपका ऐप पृष्ठभूमि में जाता है तो समाप्त होने के लिए लंबे समय तक चलने वाले कार्यों के लिए उपयोग किया जाता है। हालांकि, उनके उत्तर से पता चलता है कि पृष्ठभूमि ऐप में महत्वपूर्ण स्थान परिवर्तन द्वारा आपके ऐप को जागृत किया गया है और पृष्ठभूमि में सभी http अनुरोध को पूरा करने के लिए प्रारंभ बैकग्राउंड टास्कविथ एक्स्पेरेशन हैंडलर का उपयोग कर सकते हैं। –

2

मैं आपके जैसा बिल्कुल कोड का उपयोग कर रहा हूं और यह मेरे लिए RestKit में काम करता है। एकमात्र तरीका यह है कि मैं इसे काम कर सकता हूं, यह एक सिंक्रोनस अनुरोध बना रहा है (यह किसी भी तरह से इस संदर्भ में असीमित रूप से ऐसा करने के लिए बहुत समझ में नहीं आता है!)। इस कोड की जांच करें और हमें बताएं कि क्या यह काम करता है:

// REMEMBER. We are running in the background if this is being executed. 
// We can't assume normal network access. 
// bgTask is defined as an instance variable of type UIBackgroundTaskIdentifier 

// Note that the expiration handler block simply ends the task. It is important that we always 
// end tasks that we have started. 

_bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: 
      ^{ 
       [[UIApplication sharedApplication] endBackgroundTask:_bgTask]; 
      }]; 

// ANY CODE WE PUT HERE IS OUR BACKGROUND TASK 

// For example, I can do a series of SYNCHRONOUS network methods (we're in the background, there is 
// no UI to block so synchronous is the correct approach here). 

NSNumber *latNumber = [NSNumber numberWithDouble:location.coordinate.latitude]; 
NSNumber *lngNumber = [NSNumber numberWithDouble:location.coordinate.longitude]; 
NSNumber *accuracyNumber = [NSNumber numberWithDouble:location.horizontalAccuracy]; 
NSDictionary *params = [NSDictionary dictionaryWithKeysAndObjects:@"lat",latNumber,@"lng",lngNumber,@"accuracy",accuracyNumber, nil]; 
RKURL *URL = [RKURL URLWithBaseURL:[NSURL URLWithString:SERVER_URL] resourcePath:@"/user/location/update" queryParameters:params]; 
RKRequest *request = [RKRequest requestWithURL:URL]; 
request.method = RKRequestMethodGET; 
NSLog(@"Sending location to the server"); 
RKResponse *response = [request sendSynchronously]; 
if (response.isFailure) 
    NSLog(@"Unable to send background location, failure: %@", response.failureErrorDescription); 
else { 
    NSError *error = nil; 
    NSDictionary *parsedBody = [response parsedBody:&error]; 
    if (YES == [[parsedBody objectForKey:@"result"] boolValue]){ 
     NSLog(@"Background location sent to server"); 
    } 
    else { 
     //Something went bad 
     NSLog(@"Failed to send background location"); 
    } 
} 
// AFTER ALL THE UPDATES, close the task 

if (_bgTask != UIBackgroundTaskInvalid) 
{ 
    [[UIApplication sharedApplication] endBackgroundTask:_bgTask]; 
    _bgTask = UIBackgroundTaskInvalid; 
} 

मैं लगभग यकीन है कि नया थ्रेड अपने RKClient अनुरोध के लिए पैदा की यह लागू करने के बाद स्वचालित रूप से मार दिया जाता है कर रहा हूँ।

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