Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Handle requests in background from another iOS app running on the same device #544

Open
andyboyd opened this issue May 5, 2021 · 5 comments

Comments

@andyboyd
Copy link

andyboyd commented May 5, 2021

I'm trying to run a GCDWebServer in an app running on an iOS device, and connect to that server from another app, so that I can communicate between the two of them. Is this supported? The server is starting successfully, but it doesn't seem to receive any connections.

My server initialisation code is:

server.addHandler { method, url, headers, path, query in
            return GCDWebServerDataRequest(method: method, url: url, headers: headers, path: path, query: query)
        } processBlock: { req in
            return GCDWebServerDataResponse(data: encodePlaceholderJSONBody()), contentType: "application/json")
        }

        server.delegate = self
        do {
            try server.start(
                options: [
                    GCDWebServerOption_Port: 8080,
                    GCDWebServerOption_AutomaticallySuspendInBackground: false,
                    GCDWebServerOption_ConnectedStateCoalescingInterval: 5
                ]
            )
        } catch {
            print(error)
        }

And I'm getting the following in the console:

[DEBUG] Did open IPv4 listening socket 3
[DEBUG] Did open IPv6 listening socket 4
[INFO] GCDWebServer started on port 8080 and reachable at http://192.168.0.62:8080/
started

Then my client is sending this request:

var request = URLRequest(url: URL(string: "http://192.168.0.62:8080/")!)
    request.httpMethod = "POST"
    request.httpBody = encodedRequestBody()
    request.timeoutInterval = 5
    URLSession.shared.dataTask(with: request) { data, response, error in
      if let error = error {
        self.response = error.localizedDescription
      } else if let data = data {
        guard let body = decodeResponseBody(from: data) else {
          self.response = "Couldn't decode"
          return
        }
        self.response = body.echoedString
      }
    }
    .resume()

I'm not seeing anything further in the logs on the server (I've implemented the GCDWEbServerDelegate to log out when connections are received etc), and the client never receives a response.

@andyboyd
Copy link
Author

andyboyd commented May 5, 2021

Oh, it's iOS 14.5 by the way.

@andyboyd
Copy link
Author

andyboyd commented May 5, 2021

OK, I've actually got the two apps talking to each other now, but the server, while it stays awake in the background, does not actually process any requests until it gets foregrounded. IS there a way to make it handle the requests in the background, or is this a limitation of iOS multitasking?

@andyboyd andyboyd changed the title Connect to server on same iOS device Handle requests in background from another iOS app running on the same device May 5, 2021
@andyboyd
Copy link
Author

andyboyd commented May 6, 2021

Latest on the above...

I've got it talking in the background, but only for about 30 seconds. Then it logs out:

[WARNING] Application is being suspended while GCDWebServer is still connected
[DEBUG] Did end background task

Once more, just to confirm, I started the server with GCDWebServerOption_AutomaticallySuspendInBackground set to false, and I've been tweaking the value given to GCDWebServerOption_ConnectedStateCoalescingInterval, currently it's set to 300, but seems to have no effect.

I do notice that GCDWebServer is not using the new(ish) BackgroundTasks framework, released in iOS 13. Instead, it uses the older UIApplication.beginBackgroundTaskWithExpirationHandler: to queue up its background operation, and the docs for that state:

This method requests additional background execution time for your app. Call this method when leaving a task unfinished might be detrimental to your app’s user experience. For example, call this method before writing data to a file to prevent the system from suspending your app while the operation is in progress. For background tasks requiring more time, use Background Tasks.

I'm wondering if that mechanism will only ever allow 30 seconds of background execution, and BackgroundTasks is required to get any more than that?

@maebeam
Copy link

maebeam commented May 6, 2021

Looks like the time may have been decreased to 30 seconds in iOS 13

https://developer.apple.com/forums/thread/125162
https://developer.apple.com/forums/thread/85066

@nicksaintjohn
Copy link

I do notice that GCDWebServer is not using the new(ish) BackgroundTasks framework, released in iOS 13. Instead, it uses the older UIApplication.beginBackgroundTaskWithExpirationHandler: to queue up its background operation...

On this point, I'm working on a project that uses GCDWS within an app extension. Since updating to XC 12.5, I'm now getting compile errors about the use of beginBackgroundTaskWithExpirationHandler (use of sharedApplication is no longer supported in app extensions). Is there any hope that this will be updated any time soon, or is there perhaps another fix that someone here could suggest?

I'm worried I will need to switch to an alternative (assuming one exists), as I currently can't compile without stripping out key functionality. Compile errors are as follows (5 of them)

Showing Recent Messages Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.m:214:39: 'sharedApplication' is unavailable: not available on tvOS (App Extension) - Use view controller based solutions where appropriate instead.

Sorry if this is slightly off topic, but this seemed close enough to negate posting a new issue. Thanks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants