1

apollo setup

import Foundation
import Apollo

class Network {
    static let shared = Network()

    private(set) lazy var apollo = ApolloClient(url: URL(string: "http://localhost:4000/graphql")!)
}

querying data and storing in state

@State var user: UserQuery.Data.User?

func loadUser() {
   Network.shared.apollo.fetch(query: UserQuery(username: username)) { result in
            switch result {
            case .success(let graphQLResult):
                if let result = graphQLResult.data?.user {
                    user = result
                }
                
            case .failure(let error):
                print("Error: \(error)")
            }
        }
}

var body: some View {
        ScrollView(showsIndicators: false) {
            ...
        }
        .onAppear(perform: loadUser)
    }

function to perform follow mutation & update cache (is inside the scrollview above)

Button(user.followingUser ? "Unfollow" : "Follow") {
    Network.shared.apollo.perform(mutation: FollowUserMutation(userFollowingId: user.uuid)) { result in
            switch result {
            case .success(_):
                Network.shared.apollo.store.withinReadWriteTransaction({ transaction in
                    try transaction.update(query: UserQuery(username: user.username)) { (data: inout UserQuery.Data) in
                        if (data.user?.followingUser == true) {
                            data.user?.totalFollowers -= 1
                        } else {
                            data.user?.totalFollowers += 1
                        }
                        
                        data.user?.followingUser.toggle()
                    }
                })
                
            case .failure(let error):
                print("Error: \(error)")
            }
        }
}

on the user page I have a button to perform the follow/unfollow mutation & then update the local cache. mutation works as expected, and even the cache update works, but it only updates on the ui whenever i switch views, rather than immediatley when the button is pressed.

i'm new to both swift and apollo-ios so I have no idea why the cache update isnt working as it would in apollo-react, or if it's even possible

with apollo-ios v0.53.0

abesan
  • 11
  • 3
  • You’ve tagged SwiftUI, but there isn’t any here. Is your view in SwiftUI? How are you getting the “update” to it. I don’t see any ObservableObject here. – jnpdx Oct 15 '22 at 14:35
  • yeah, my bad, shouldn't have tagged swiftui, data being displayed is coming directly from the query, so when updating the cache the data displayed should be updated, or at least that's how it works in apollo-react – abesan Oct 15 '22 at 14:40
  • Well, since you aren’t showing any of the UI, it’s impossible to say why your UI may not be updating. – jnpdx Oct 15 '22 at 15:23
  • data is saved in state `@State var data: UserQuery.Data.User?` it comes from apollo query `Network.shared.apollo.fetch(query: UserQuery(username: username)) { result in` ... `data = result` ... – abesan Oct 15 '22 at 15:38
  • Well, `@State` *is* from SwiftUI, so maybe you did want to tag it? Can you please include a [mre] with all of the relevant code? It's become clear that there really isn't enough relevant information here to answer the question. – jnpdx Oct 15 '22 at 15:54
  • updated the post, but that's basically everything relevant, the rest is just ui – abesan Oct 15 '22 at 16:12
  • What you've posted isn't valid SwiftUI code -- you can't do a network request at the top level next to a `@State` variable. You'll have more luck getting an answer if you include a [mre]. Good luck! – jnpdx Oct 15 '22 at 16:17

1 Answers1

0

Well, to me it seems pretty obvious that your UI don't update because the only time you tell it to update is with .onAppear(perform: loadUser)

Try one of these two approaches when you get a success from FollowUserMutation:

  1. Call loadUser, which will fetch again and update your state which should update your UI.

  2. Set user.totalFollowers to whatever you are also updating in the cache, and since you are now updating the @State variable directly it should update your UI.

@State is not just automatically realizing that something in your Apollo cache updates, you need to update the state yourself, and then everything that uses the state will update its UI.

bjorn.lau
  • 774
  • 5
  • 16