Updating Environment Variables

Has anyone else come across a need to update environment variables? For example, I have an apiService: ServiceType that is responsible for making all of my network calls. Pre-TCA, I had a login function that would accept a sessionToken, which would then be sent along with each request.

Since the Environment is passed into each reducer as a constant, I don't think it's possible to keep doing that. I'm curious if this is a challenge that anyone else has run into or if I need to change my thinking with this architecture.

One option would be to keep the sessionToken in one of the reducer's states and then pass that along with each request, but that would be a bit tedious and it feels like there is a better way. I just haven't found it yet.

1 Like

I'm not sure modifying the environment is a good idea, but as far as I know, nothing stops you from declaring it a class instead of a struct, or declaring it a struct with a property that references a class.

In a recent project, I added a user defaults client to the Environment and use that to get access to the session token in the reducer.

While passing the sessionToken in to each service call is a little tedious it does mean that the compiler can check if you have one when you make the call. If you keep the state in the environment then you run the risk of creating code paths that make api calls when the sessionToken isn't available yet.

A pattern that's worked well for us is for the "live" implementation of a dependency to manage some fileprivate, mutable state. If your app only has to worry about a single session token, this could be held onto in a single var:

// LiveClient.swift

// Token used to authenticate logged-in requests
private var token: String?

// Helper function to create effects for API requests
private func request<T>(
  for path: String
) -> Effect<T, ClientError> where T: Decodable {
  // use `token` to authenticate requests here

extension Client {
  // "Live" client, which provides APIs for setting this
  // token and uses the `request` helper above
  public static let live = Client(
    authenticate: { token = $0 },
1 Like

Can you put this into a case study? I can't get my head around how exactly it should work.

Imagine I have a LiveClient which is previously intialise without the token and embedded in the Environment. How can I replace the client inside the Envirionment with the new live one?

1 Like

I would also love to hear more about your approach @stephencelis...

How does the token get set? Do you pass it around as state?

1 Like
Terms of Service

Privacy Policy

Cookie Policy