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

How to utilise Apollo with background session configuration #77

Closed
attheodo opened this issue Apr 6, 2017 · 5 comments
Closed

How to utilise Apollo with background session configuration #77

attheodo opened this issue Apr 6, 2017 · 5 comments
Labels
enhancement Issues outlining new things we want to do or things that will make our lives as devs easier
Milestone

Comments

@attheodo
Copy link

attheodo commented Apr 6, 2017

Hello, I have an operation that I want to continue running in the background.
I am creating the Apollo client using let sessionConfig = URLSessionConfiguration.background(withIdentifier: Bundle.main.bundleIdentifier! + ".apolloBackground") passed in the HTTPNetworkTransport object.

However when I am trying to test how the request behaves in the background, I am getting:

2017-04-06 12:10:25.885 Waldo Dev[14754:6295257] *** 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                      0x00000001074d8b0b __exceptionPreprocess + 171
	1   libobjc.A.dylib                     0x0000000106bd4141 objc_exception_throw + 48
	2   CFNetwork                           0x0000000109f37e45 -[__NSURLBackgroundSession validateSerializabilityForRequest:completion:] + 172
	3   CFNetwork                           0x0000000109f384fe -[__NSURLBackgroundSession _onqueue_dataTaskForRequest:completion:] + 43
	4   CFNetwork                           0x0000000109f3841d __58-[__NSURLBackgroundSession dataTaskForRequest:completion:]_block_invoke + 34
	5   CFNetwork                           0x0000000109f381ec __68-[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:]_block_invoke + 67
	6   libdispatch.dylib                   0x0000000109a2c05c _dispatch_client_callout + 8
	7   libdispatch.dylib                   0x0000000109a09de6 _dispatch_barrier_sync_f_invoke + 346
	8   CFNetwork                           0x0000000109f38155 -[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:] + 166
	9   CFNetwork                           0x0000000109f3838c -[__NSURLBackgroundSession dataTaskForRequest:completion:] + 211
	10  Apollo                              0x0000000103468626 _TFC6Apollo20HTTPNetworkTransport4senduRxS_16GraphQLOperationrfT9operationx17completionHandlerFTGSqGCS_15GraphQLResponsex__GSqPs5Error___T__PS_11Cancellable_ + 1126
	11  Apollo                              0x000000010346932f _TTWC6Apollo20HTTPNetworkTransportS_16NetworkTransportS_FS1_4senduRd__S_16GraphQLOperationrfT9operationqd__17completionHandlerFTGSqGCS_15GraphQLResponseqd____GSqPs5Error___T__PS_11Cancellable_ + 95
	12  Apollo                              0x000000010343a6b9 _TFC6Apollo12ApolloClientP33_5F19D33E96514915F6F483642855496F4senduRxS_16GraphQLOperationrfT9operationx7contextGSqSv_12handlerQueueCSo13DispatchQueue13resultHandlerGSqFTGSqGVS_13GraphQLResultwx4Data__GSqPs5Error___T___PS_11Cancellable_ + 409
	13  Apollo                              0x000000010343a4d8 _TFC6Apollo12ApolloClient8_performuRxS_15GraphQLMutationrfT8mutationx7contextGSqSv_5queueCSo13DispatchQueue13resultHandlerGSqFTGSqGVS_13GraphQLResultwx4Data__GSqPs5Error___T___PS_11Cancellable_ + 200
	14  Apollo                              0x000000010343a378 _TFC6Apollo12ApolloClient7performuRxS_15GraphQLMutationrfT8mutationx5queueCSo13DispatchQueue13resultHandlerGSqFTGSqGVS_13GraphQLResultwx4Data__GSqPs5Error___T___PS_11Cancellable_ + 200
	15  Waldo Dev                           0x00000001023ed677 _TFC9Waldo_Dev10APIService16addPhotosToAlbumfT8photoIdsGSaSS_7albumIdSS_T_ + 3607
	16  Waldo Dev                           0x0000000102421a25 _TFFFC9Waldo_Dev20PhotoUploadOperation4mainFT_T_U_FTGSqV10Foundation4Data_GSqSS__T_U_FGSqPs5Error__T_ + 709
	17  Waldo Dev                           0x0000000102425f64 _TPA__TFFFC9Waldo_Dev20PhotoUploadOperation4mainFT_T_U_FTGSqV10Foundation4Data_GSqSS__T_U_FGSqPs5Error__T_ + 164
	18  Waldo Dev                           0x0000000102422b2c _TFFC9Waldo_Dev20PhotoUploadOperationP33_61AF4F22A4A02F23B011EB588A9C2D1013performUploadFT4dataV10Foundation4Data8filenameSS8mimeTypeSS9uploadURLSS17completionHandlerFGSqPs5Error__T__T_U_FV9Alamofire19DefaultDataResponseT_ + 588
	19  Alamofire                           0x00000001032c1fce _TFFFC9Alamofire11DataRequest8responseFT5queueGSqCSo13DispatchQueue_17completionHandlerFVS_19DefaultDataResponseT__DS0_U_FT_T_U_FT_T_ + 830
	20  Alamofire                           0x000000010328a527 _TTRXFo___XFdCb___ + 39
	21  libdispatch.dylib                   0x0000000109a034a6 _dispatch_call_block_and_release + 12
	22  libdispatch.dylib                   0x0000000109a2c05c _dispatch_client_callout + 8
	23  libdispatch.dylib                   0x0000000109a0d40b _dispatch_main_queue_callback_4CF + 411
	24  CoreFoundation                      0x000000010749d909 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
	25  CoreFoundation                      0x0000000107463ae4 __CFRunLoopRun + 2164
	26  CoreFoundation                      0x0000000107463016 CFRunLoopRunSpecific + 406
	27  GraphicsServices                    0x000000010dae4a24 GSEventRunModal + 62
	28  UIKit                               0x0000000104e3d0d4 UIApplicationMain + 159
	29  Waldo Dev                           0x000000010245e017 main + 55
	30  libdyld.dylib                       0x0000000109a7865d start + 1
	31  ???                                 0x0000000000000003 0x0 + 3

Most probably due to the way Apollo perform method works using completion closures.

Any ideas on how to work around that?

@MrAlek
Copy link
Contributor

MrAlek commented Jun 29, 2017

Resurrecting this old issue but to give some direction to perhaps @attheodo and others, the solution we ultimately ended up using was to serialize our own URLRequests from GraphQLOperation and use a separate network stack just for background uploads/downloads.

Since in background, your app is not in control of the network sessions themselves, we found it hard to make a good fit with the NetworkTransport state machine in ApolloClient.

@MaxDesiatov
Copy link
Contributor

If you use Alamofire library in the app and/or don't mind having it as a dependency, I've just published a package that solves this problem: https://github.com/maxdesiatov/ApolloAlamofire

You can use it like this:

import ApolloAlamofire

let c = URLSessionConfiguration.background(withIdentifier: "your-id")
let u = URL(string: "http://localhost:8080/graphql")!
let s = SessionManager(configuration: c)
let t = AlamofireTransport(url: u, sessionManager: s)
let client = ApolloClient(networkTransport: t)

I've tested this extensively in an app that utilises background networking and it works perfectly well. The background network code itself is very minimal thanks to great support for background sessions in Alamofire.

@designatednerd designatednerd added the enhancement Issues outlining new things we want to do or things that will make our lives as devs easier label Jun 25, 2019
@designatednerd designatednerd modified the milestones: 0.14.0, 0.15.0 Jul 24, 2019
@designatednerd
Copy link
Contributor

As of 0.15.0, the HTTPNetworkTransport initializer now takes a URLSession directly rather than a URLSessionConfiguration, so you should now be able to pass in a background session directly to the initializer.

If you are still having problems after upgrading, please open a new issue. Thank you!

@ghost
Copy link

ghost commented Aug 29, 2019

Any suggestion after upgrading 0.15.0, how to add configuration in apollo client?

@designatednerd
Copy link
Contributor

There's some stuff with the delegate callbacks I missed that I need to deal with in order to make it fully functional 🤦‍♀

Please follow that issue for further updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Issues outlining new things we want to do or things that will make our lives as devs easier
Projects
None yet
Development

No branches or pull requests

4 participants