5

Arka planda yavaş bir arka plana gelindiğinde ve arka plan yapılandırmasıyla veri indirirken sorun yaşıyorum.NSURLSessionDownloadTask, Arka Plan Yapılandırması'nı kullanırken yeniden denemeye devam ediyor

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier]; 
_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; 
NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithURL:URL]; 
[downloadTask resume]; 

bağlantı astablished ama bir zaman aşımı oluştuğunda veri geri göndermek için 60'dan fazla saniye sürer ise. Bu iyi. Ancak, yaşadığım davranış, bir Hata alamıyorum. Oturum sadece yeni bir istek gönderir. "Verileri tekrar ver". Bunun nerede olduğu hakkında hiçbir fikrim yok. Benim kodumda değil ve farkında olduğum delege yöntemleri deniyor. Sadece sunucu kayıtlarına erişebiliyorum. Verileri geri göndermek için sunucuyu yaklaşık olarak 68 saniye sürüyor, ancak uygulama yeni isteği beklediği için bunu göz ardı ediyor.

Bir çözüm, zaman aşımı değerini artırmaktır. Ama ben hoşlanmıyorum ve sadece iOS 7 için çalışıyor. Not iOS 8.

sessionConfig.timeoutIntervalForRequest = 10 * 60.0; 

Bu konuda herhangi bir fikir sahibi olan var mı? Bu link about timeout issue for background session numaralı dosyayı stackoverflow üzerinde buldum. 10 aylık ama çözüm yok, sadece insanlar kabul ediyor.

cevap

3

Bunu çözmeyi başardım. Benim çözümümün çözümü olduğunu söylemiyorum ama bir çözümü.

Yaşadığım davranış, iOS 7 ve iOS 8'in özellikleri farklı şekilde önceliklendirmesidir. Bu zaman aşımı özelliklerini ayarlamak için iki yerim var, NSURLSessionConfiguration ve NSMutableURLRequest. iOS 7, istek özelliği hakkında daha az ilgilenemedi ve iOS 8, yapılandırma özelliği hakkında daha az ilgilenemedi. Şu anda benim çözüm şöyle görünür: Bir sadece systemVersion denetimlerini yapmak ve aynı değere hem özellikleri ayarlamak olamazdı sanırım

NSURLSessionConfiguration *sessionConfig; 
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { 
    sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier]; 
} 
else { 
    sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier]; 
} 
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { 
    sessionConfig.timeoutIntervalForRequest = 5 * 60.0; 
} 
_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { 
    request.timeoutInterval = 5 * 60.0; 
} 
NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithRequest:request]; 

. Daha az kodun daha fazla olduğuna inanıyorum ki, etkilemesine gerek olmayan durumları etkilemede daha güçlü olduğuna inanıyorum. Ancak halkları duymak isterim görüşleri. Ve eğer birisi daha iyi bir çözüme sahipse lütfen paylaşımını.

Oh bir şey daha. Yeniden deneme bölümü, zaman aşımı süresine göre 7 günlük varsayılan değerine ulaşana kadar devam edecektir. Bunu 10 dakikaya düşürdüm.

Değiştirilmem gerektiğini söylemiyorum. Bu, belirli ortam kurulumumuz için yaptığımız bir karardır.



Güncelleme Biz 7 gün varsayılan değerine geri timeoutIntervalForResource değiştirdi. Örneğin Çin'de müşterilerimiz var ve bazılarının gerçekten zayıf bağlantıları var. 10 dakikalık bir ana limit sadece aptaldı.

Daha iyi bir kod kalitesi için Sunkas answer'a baktığınızdan emin olun. Ancak kod snippet'im farklı sınıflara yayılıyor, bu yüzden bu yaklaşımı% 100 tekrar kullanamıyorum.

+0

Soru: Neden sonuçta iOS 8 ve iOS 7 arasında ayrım yapmak mı? Hem timeoutIntervalForRequest hem de timeoutInterval'ı ayarlayamadınız mı? – dlinsin

6

kendime engel olamazdı, burada biraz refactored Cevabınız :) sunucu yanıt vermemesi durumunda

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 
NSURLSessionConfiguration *sessionConfig; 
float timeout = 5 * 60.0f; 

BOOL iOS8OrNewer = [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0; 
if (iOS8OrNewer) { 
    sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier]; 
    request.timeoutInterval = timeout; 
} 
else { 
    sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier]; 
    sessionConfig.timeoutIntervalForRequest = timeout; 
} 

_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; 

NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithRequest:request]; 
+2

Çok güzel ve okunması kolay, teşekkürler! Kod snippet'im aslında iki ayrı sınıfa yayılmış olsa da, elimden geleni uygulayacağım :) –

3

iOS8 yana, arka plan modunda NSUrlSession bu temsilci yöntemi çağırmaz olduğunu. -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error İndirme/yükleme süresiz olarak boşta kalır. Sunucu yanıt vermediğinde bu temsilci iOS7'de bir hatayla çağrılır. Tel üzerinde bir şeyler yanlış giderse, bir NSURLSession arka plan oturumu genel olarak bir görev başarısız olmaz. Bunun yerine, isteği yürütmek ve o anda yeniden denemek için iyi bir zaman aramaya devam ediyor. Bu, kaynak zaman aşımı sona erene kadar devam eder (yani, oturumu oluşturmak için kullandığınız NSURLSessionConfiguration nesnesindeki timeoutIntervalForResource özelliğinin değeri). Bu değer için geçerli varsayılan değer bir hafta! Başka bir deyişle, iOS7'de zaman aşımı için başarısız olma davranışı yanlıştı. Bir arka plan oturumu bağlamında, ağ sorunları nedeniyle hemen başarısız olmamak daha ilginçtir. Böylece iOS8'den beri, zaman aşımları ve ağ kaybıyla karşılaşsa bile NSURLSession görevi devam eder. Ancak timeoutIntervalForResource'a ulaşılana kadar devam eder.

Temel olarak timeoutIntervalForRequest, Background oturumunda çalışmayacak, ancak timeoutIntervalForResource yapacak.

Kaynak: Apple Forum

İlgili konular