Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPNetworkTransport still using completion handler blocks #732

Closed
diegoventura opened this issue Aug 22, 2019 · 21 comments
Closed

HTTPNetworkTransport still using completion handler blocks #732

diegoventura opened this issue Aug 22, 2019 · 21 comments
Labels
bug Generally incorrect behavior networking-stack question Issues that have a question which should be addressed
Milestone

Comments

@diegoventura
Copy link

The latest release (0.15.0) introduced the ability to use a URLSession instead of a URLSessionConfiguration, this allows using a background session on the HTTPNetworkTransport.

However, HTTPNetworkTransport is still using completion handler blocks, which are not supported in a background session, instead of using a delegate for that.

Do you have any plans to change this behavior so HTTPNetworkTransport is always using a delegate instead of completion handler blocks?

@designatednerd
Copy link
Contributor

Remind me why a completion handler can't be used in a background session? I thought when you got the background wakeup call you got a completion block to fire when your action had completed.

@designatednerd designatednerd added the question Issues that have a question which should be addressed label Aug 23, 2019
@diegoventura
Copy link
Author

diegoventura commented Aug 24, 2019

I thought it too, but when I'm getting the following crash when fetching the query.

2019-08-24 10:05:34.535996+0200 BlahBlah[60902:3911842] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000110cac8db __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x000000011024fac5 objc_exception_throw + 48
	2   CFNetwork                           0x00000001135c179d -[__NSURLBackgroundSession validateSerializabilityForRequest:completion:] + 172
	3   CFNetwork                           0x00000001135c1f01 -[__NSURLBackgroundSession _onqueue_dataTaskForRequest:completion:] + 43
	4   CFNetwork                           0x00000001135c1e20 __58-[__NSURLBackgroundSession dataTaskForRequest:completion:]_block_invoke + 34
	5   CFNetwork                           0x00000001135c1bf0 __68-[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:]_block_invoke + 64
	6   libdispatch.dylib                   0x0000000112bbedb5 _dispatch_client_callout + 8
	7   libdispatch.dylib                   0x0000000112bccd08 _dispatch_lane_barrier_sync_invoke_and_complete + 132
	8   CFNetwork                           0x00000001135c1b58 -[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:] + 161
	9   CFNetwork                           0x00000001135c1d8d -[__NSURLBackgroundSession dataTaskForRequest:completion:] + 206
	10  Apollo                              0x0000000111ec71e2 lprofRestoreSigKill + 1154
	11  Apollo                              0x0000000111ec7fb1 lprofRestoreSigKill + 4689
	12  Apollo                              0x0000000111ec8a30 lprofRestoreSigKill + 7376
	13  Apollo                              0x0000000111f290ac block_copy_helper.94 + 7916

The reason I would say is that the completion handler blocks may have been deallocated while the app is in background

@designatednerd
Copy link
Contributor

Blargh. Will take a look when I get back.

@diegoventura
Copy link
Author

👋 any update on this?

@designatednerd
Copy link
Contributor

Not at the moment - I think we're probably going to have to add some additional protocol methods to make this work correctly, and I'm in the middle of about 14 other things. Would be more than happy to look at a pull request if you've got more time!

@kroussevrb
Copy link

This is very important, as Apple is going to reject apps that have a Share extension that starts uploads configured without a background session.

@designatednerd
Copy link
Contributor

@kroussevrb Thanks for the heads up - again, I'm swamped with a couple other things but would be more than happy to look at a PR if you have some time!

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Nov 9, 2019

TWIMC, I've just released ApolloAlamofire 0.6.0, which is updated for Apollo 0.19.0 and allows using an Alamofire delegate for the Apollo transport.

@kroussevrb
Copy link

This is great, now the only thing missing is a pure Apollo solution for those of us who can't afford to import Alamofire as a dependency. I am aware of the suggestion to submit a PR for that but I don't know if I will be able to get around to it (or even if I do, not sure it will be the best solution as I am not familiar with Apollo's source code)

@designatednerd designatednerd added the bug Generally incorrect behavior label Nov 19, 2019
@ethan021021
Copy link

Any update on this functionality? :)

@designatednerd
Copy link
Contributor

Gonna be a bit - I've been doing some exploration around this and some other restructuring of the networking stack for HTTP recently, but I need to get it more stable before I write up a CFP.

@ethan021021
Copy link

@designatednerd Right on! Thanks so much for the quick reply. Love this SDK and everything about Apollo!

@kroussevrb
Copy link

I rewrote the network transport to be able to handle this but my implementation is very specific to our project, so can't help out here.

@designatednerd
Copy link
Contributor

Hi folks, I finally got something that will work with a background session functional. Please check out #1163, I would love your feedback.

@designatednerd designatednerd added this to the 0.27.0 milestone Apr 28, 2020
@designatednerd
Copy link
Contributor

This has (finally) shipped with 0.27.0. Thanks to all for your patience!

@preetirani
Copy link

Hey Can anyone please share the right way of configuring apollo for the background task to work. earlier i was using 0.21.0 for all foreground tasks and now updated to 0.27.0 so as to hit api from background.
Any example would be helpful. I just want to know what all needs to be done for the background to work.

@designatednerd
Copy link
Contributor

Hi! You can pass the background session configuration you receive from the system into a URLSessionClient, since that takes a session configuration. Then, you pass that client into the initializer for HTTPNetworkTransport.

Does that help?

@diegoventura
Copy link
Author

diegoventura commented Jul 30, 2020 via email

@designatednerd
Copy link
Contributor

@diegoventura are you talking about the delegates on UIApplication? We cover a lot of delegate methods in URLSessionClient

@preetirani
Copy link

  import Foundation
  import Apollo

  // MARK: - Singleton Wrapper

 class Network {

static var cachedShared: Network?

static var shared: Network {
    guard cachedShared == nil else {
        return cachedShared!
    }

    cachedShared = Network()
    return cachedShared!
}

static func resetShared() {
    cachedShared = nil
}

var networkTransport: HTTPNetworkTransport {
    let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = [
            "Custom-Authorization": "Bearer \(AuthenticationToken.current?.token ?? "")",
            "IS-MOBILE-APP": "true"
        ]
    let url = URL(string: Constant.urlString)!
    let client = URLSessionClient(sessionConfiguration: configuration)
    return HTTPNetworkTransport(url: url, client: client)
}

// Use the configured network transport in your Apollo client.
private(set) lazy var apollo = ApolloClient(networkTransport: self.networkTransport)
 }

This is code I am using to instantiate apollo client.
@designatednerd how did we get background session from system ?

@designatednerd
Copy link
Contributor

Here's all of Apple's documentation about how to get a background session. You'll probably want to make your networkTransport var a function that takes the URLSessionConfiguration as a parameter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Generally incorrect behavior networking-stack question Issues that have a question which should be addressed
Projects
None yet
Development

No branches or pull requests

6 participants