NSURLSession - iOS kills application in background while communicating with server
Asked Answered
B

1

6

I am working on a BLE application that will always run in background. It gets health related data from the BLE peripheral and will upload the data to the server in realtime. I am using NSURLSession along with NSURLSessionUploadTask created using [NSURLSession uploadTaskWithRequest:myRequest fromFile:fileURL] to send data to the server.

Right now the application works as expected for 4-5 hours in background but after that iOS kills the application.

Here is the crash log.

Date/Time:           2014-04-02 19:32:11.694 -0700
OS Version:          iOS 7.0.4 (11B554a)
Report Version:      104

Exception Type:  00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread:  2

Application Specific Information:
MyApp[2548] has active assertions beyond permitted time: 
{(
    <BKProcessAssertion: 0x15d83310> identifier: Background Content Fetching (66) process: MyApp[2548] permittedBackgroundDuration: 30.000000 reason: backgroundContentFetching owner pid:33 preventSuspend  preventThrottleDownUI  preventIdleSleep  preventSuspendOnSleep 
)}

Elapsed total CPU time (seconds): 1.300 (user 1.300, system 0.000), 2% CPU 
Elapsed application CPU time (seconds): 0.029, 0% CPU

Thread 0:
0   libsystem_kernel.dylib          0x3bb18a8c mach_msg_trap + 20
1   libsystem_kernel.dylib          0x3bb18888 mach_msg + 44
2   CoreFoundation                  0x30c957be __CFRunLoopServiceMachPort + 150
3   CoreFoundation                  0x30c93f2a __CFRunLoopRun + 850
4   CoreFoundation                  0x30bfec22 CFRunLoopRunSpecific + 518
5   CoreFoundation                  0x30bfea06 CFRunLoopRunInMode + 102
6   GraphicsServices                0x358ff27e GSEventRunModal + 134
7   UIKit                           0x334a2044 UIApplicationMain + 1132
8   MyApp                           0x0007b8b8 main (main.m:16)
9   libdyld.dylib                   0x3ba74ab4 start + 0

Thread 1:
0   libsystem_kernel.dylib          0x3bb1883c kevent64 + 24
1   libdispatch.dylib               0x3ba59210 _dispatch_mgr_invoke + 228
2   libdispatch.dylib               0x3ba58f96 _dispatch_mgr_thread$VARIANT$mp + 34

Thread 2 name:  com.apple.NSURLConnectionLoader
Thread 2:
0   libsystem_kernel.dylib          0x3bb18a8c mach_msg_trap + 20
1   libsystem_kernel.dylib          0x3bb18888 mach_msg + 44
2   CoreFoundation                  0x30c957be __CFRunLoopServiceMachPort + 150
3   CoreFoundation                  0x30c93ee4 __CFRunLoopRun + 780
4   CoreFoundation                  0x30bfec22 CFRunLoopRunSpecific + 518
5   CoreFoundation                  0x30bfea06 CFRunLoopRunInMode + 102
6   Foundation                      0x316392f2 +[NSURLConnection(Loader) _resourceLoadLoop:] + 314
7   Foundation                      0x316aec82 __NSThread__main__ + 1058
8   libsystem_pthread.dylib         0x3bb93c1a _pthread_body + 138
9   libsystem_pthread.dylib         0x3bb93b8a _pthread_start + 98
10  libsystem_pthread.dylib         0x3bb91c8c thread_start + 4

Thread 3 name:  com.apple.CFSocket.private
Thread 3:
0   libsystem_kernel.dylib          0x3bb2b440 __select + 20
1   CoreFoundation                  0x30c99680 __CFSocketManager + 480
2   libsystem_pthread.dylib         0x3bb93c1a _pthread_body + 138
3   libsystem_pthread.dylib         0x3bb93b8a _pthread_start + 98
4   libsystem_pthread.dylib         0x3bb91c8c thread_start + 4

Thread 4:
0   libsystem_kernel.dylib          0x3bb2bc7c __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x3bb91dc6 _pthread_wqthread + 306
2   libsystem_pthread.dylib         0x3bb91c80 start_wqthread + 4

I have not implemented [UIApplicationDelegate application:performFetchWithCompletionHandler:] method in AppDelegate, because I think that is related to background download.

Why my application crashes though I am using NSURLSession with background configuration? is that some thing related to not implementing [UIApplicationDelegate application:performFetchWithCompletionHandler:]?

Thanks.

Brobdingnagian answered 8/4, 2014 at 5:35 Comment(6)
This seems related: #19623279Tachyphylaxis
I read above thread, but it does not help me. I am using NSURLSession with background configuration. So ideally it should not block main thread but still app crashes in background.Brobdingnagian
I don't think it's related to the main thread. I believe it's about not completing a fetch operation within the allowed 30 seconds. (That's why I mentioned the other thread with its reference to Apple docs and to checking how much background time remains.)Tachyphylaxis
I think what you are saying is related to fetching data on push notification arrival. In case of NSURLSession, I have not come across any document that suggest to complete download or upload in 30 seconds. In fact I have done some POCs to download large files using NSURLSession and I successfully downloaded files though it took 3-5 minutes based on file size and network.Brobdingnagian
OK. You know best what your tests showed…I was going by the error message saying: "permittedBackgroundDuration: 30.000000"Tachyphylaxis
My understanding is that performFetchWithCompletionHandler: is to be used in tandem with the backgroundFetchInterval (devices wakes up your app and gives it a small window of time to do some work. I believe this method is unrelated to background tasks that you queue up by other means.Picked
C
5

Philip Mills is actually correct. Just because it took 3-5 minutes to download a file, it has nothing to do with the amount of time spent within the application.

If your application is woken up by the OS in the background, you get 30 seconds. No questions. If you do not call the completionBlock within 30 seconds your app will crash in the background, no ifs or buts. I've tested this for weeks.

You are able to download files that take 3-5 minutes or even 3-5 hours because NSURLSession submits the download task to nsnetworkd which is the network daemon managed by iOS. nsnetworkd handles your network jobs, not your app. During the actual download your app is asleep. Only once it's complete does it wake your app for 30 seconds to post-process that file as you see fit -- but you only get 30 seconds.

Catchpole answered 18/4, 2014 at 16:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.