2016-09-22 83 views
1

我的應用程序中有太多時間需要獲取數據(超過25秒)的航班搜索功能。如果應用程序進入後臺或進入睡眠模式,則互聯網連接斷開。使用NSURLSessionDataTask的iOS後臺任務

我寫下面的邏輯使用蘋果的例子,使API請求繼續下去,即使應用程序去背景,但它不工作。下面

self.session = [self backgroundSession]; 
self.mutableData = [NSMutableData data]; 

NSURL *downloadURL = [NSURL URLWithString:@"http://jsonplaceholder.typicode.com/photos"]; 
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL]; 
self.dataTask = [self.session dataTaskWithRequest:request]; 
[self.dataTask resume]; 

- (NSURLSession *)backgroundSession 
{ 
    static NSURLSession *session = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"]; 
     session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; 
    }); 
    return session; 
} 

是委託方法

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
didReceiveResponse:(NSURLResponse *)response 
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { 
NSLog(@"response: %@", response.debugDescription); 
NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; 
    if (completionHandler) { 
     completionHandler(disposition); 
    } 
} 

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
    didReceiveData:(NSData *)data { 
    [self.mutableData appendData:data]; 
} 


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error 
{ 
    BLog(); 

    if (error == nil) 
    { 
     NSData *data = nil; 
     if (self.mutableData) { 
      data = [self.mutableData copy]; 
      self.mutableData = nil; 
     } 

     NSError* error; 
     NSArray* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
     if (!json) { 
      NSLog(@"Error parsing JSON: %@", error); 
     } else { 
      NSLog(@"Data: %@", json); 
     } 
    } 
    else 
    { 
     NSLog(@"Task: %@ completed with error: %@", task, [error localizedDescription]); 
    } 

    double progress = (double)task.countOfBytesReceived/(double)task.countOfBytesExpectedToReceive; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.progressView.progress = progress; 
    }); 

    self.dataTask =nil; 
} 

一切正常,當應用程序在前臺,但只要我把應用程序在後臺收到以下錯誤消息。

Completed with error: Lost connection to background transfer service

+0

您是否嘗試過從目標「功能」選項卡添加後臺抓取功能? – Nailer

+0

一次在後臺模式中啓用後臺提取選項。 xcode - 功能 - 後臺模式 – Sanju

+0

是的,我做到了,但仍然收到相同的錯誤信息。 – Jay

回答

4

您不能將數據任務用於後臺傳輸。

Download tasks retrieve data in the form of a file, and support background downloads while the app is not running.

這在蘋果公司的documentation解釋:那些必須使用下載任務來完成。

此外,一定要檢查他們的background transfer considerations

With background sessions, because the actual transfer is performed by a separate process and because restarting your app’s process is relatively expensive, a few features are unavailable, resulting in the following limitations...

的這裏的關鍵是,它是在一個單獨的進程無法訪問您保存在內存中的數據運行。它必須通過文件路由。

我收集了大量有關iOS上背景傳輸的信息(長)blog post

+0

謝謝克魯梅爾!我用下載任務修改了代碼,它工作正常。 – Jay

+0

當downloadTask請求後互聯網斷開連接時,didCompleteWithError委託方法不會被調用。一旦互聯網連接回來,它會自動恢復。有沒有辦法讓互聯網斷開的錯誤信息。 – Jay

+0

閱讀apple文檔後,看起來像downloadTask執行時無法找到互聯網連接狀態。添加下面的代碼超時sessionConfig.timeoutIntervalForRequest = 30.0; sessionConfig.timeoutIntervalForResource = 60.0; – Jay