Open lucatorella opened 8 years ago
It sounds like your app is being suspended, and I believe this is expected behavior. On an actual iOS device you will be subject to the application execution states, and you'll need to grant permission to allow the application to continue to run in the background.
From Apples "App Programming Guide for iOS"
For tasks that require more execution time to implement, you must request specific permissions to run them in the background without their being suspended. In iOS, only specific app types are allowed to run in the background:
- Apps that play audible content to the user while in the background, such as a music player app
- Apps that record audio content while in the background
- Apps that keep users informed of their location at all times, such as a navigation app
- Apps that support Voice over Internet Protocol (VoIP)
- Apps that need to download and process new content regularly
- Apps that receive regular updates from external accessories
Apps that implement these services must declare the services they support and use system frameworks to implement the relevant aspects of those services. Declaring the services lets the system know which services you use, but in some cases it is the system frameworks that actually prevent your application from being suspended.
An always running server on your phone isn't explicitly permitted, as it would have severe battery life consequences.
I think #42 is tracking this
I'm not expecting the server to run when the app is in background mode, I'm expecting the server to resume (and not to stop) once the app is back in the foreground.
Oh sorry, I misunderstood. Isn't this still up to the developer to manage the server within the UIApplicationDelegate? When the applicationWillResignActive delegate is called, server.stop() should be executed. Likewise the developer should execute server.start() on the applicationDidBecomeActive delegate.
Thanks @swimbyterun I'll try that. Anyway it would be great if the library could suspend and resume the server automatically as GCDWebServer does.
And yes it is related to https://github.com/glock45/swifter/issues/42
I tried the workaround and it's working, thanks. Unfortunately I'm getting, from time to time, and apparently only on iOS 8 the following crash:
EXC_GUARD 0x08fd4dbfade2dead
the crash happens at the line: try server.start(UInt16(port))
inside the method responsible for UIApplicationDidBecomeActiveNotification
notification.
Did you mean try server.stop(UInt16(port))
instead? UIApplicationDidEnterBackgroundNotification
is called when your application is about to be suspended
Sorry copied that wrong notification, and I corrected my previous comment. I meant it crashes at the line try server.start(UInt16(port))
. Here is an extract of my code:
init(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("applicationDidBecomeActiveNotification"), name: UIApplicationDidBecomeActiveNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("applicationDidEnterBackgroundNotification"), name: UIApplicationDidEnterBackgroundNotification, object: nil)
}
@objc func applicationDidBecomeActiveNotification() {
do {
try server?.start(UInt16(port))
} catch let error as NSError {
print("AssetsServer.applicationDidBecomeActiveNotification: \(error.localizedDescription)")
}
}
@objc func applicationDidEnterBackgroundNotification() {
server?.stop()
}
I'm seeing quite often these EXC_GUARD 0x08fd4dbfade2dead
crashes.
Here is the trace:
Thread : Crashed: com.apple.root.background-qos
0 libsystem_kernel.dylib 0x1824d2830 close + 8
1 Swifter 0x1012c1514 _TFC7Swifter12HttpServerIO4stopfS0_FT_T_ + 52
2 Swifter 0x1012c3730 _TFFC7Swifter12HttpServerIO5startFS0_FzTVSs6UInt16_T_U_FT_T_ + 572
3 libdispatch.dylib 0x18239d630 _dispatch_call_block_and_release + 24
4 libdispatch.dylib 0x18239d5f0 _dispatch_client_callout + 16
5 libdispatch.dylib 0x1823aba88 _dispatch_root_queue_drain + 2140
6 libdispatch.dylib 0x1823ab224 _dispatch_worker_thread3 + 112
7 libsystem_pthread.dylib 0x1825b1470 _pthread_wqthread + 1092
8 libsystem_pthread.dylib 0x1825b1020 start_wqthread + 4
also, restarting the server when receiving the UIApplicationDidBecomeActiveNotification
sometimes wasn't restarting the server. Temporarily I fix it by using a dispatch_after
of half a second before trying to restart the server.
@lucatorella this answer explains what's happening - http://stackoverflow.com/questions/32429431/exc-guard-exception. I am going to check this in the evening.
If I lock the iPhone (the actual device and not the simulator), when I unlock it after at least ~1 minute (so that the app is suspended), the server stops. In particular the
acceptClientSocket()
function, called by the while loop running the server, throws an exception. Because of that the server stop working.This issue is quite easy to reproduce and I included a simple snippet to reproduce it. Just create a new project (I used the Simple app template), and paste the following code in the
ViewController.swift
file:Note: it's important to use an actual device. Just lock the phone, wait, and unlock. Boom the
SocketError.AcceptFailed
exception will be raised and as a consequence thestopServer
function is called.