Search code examples
iosswiftamazon-web-servicesgraphqlaws-amplify

The right workflow when editing class in GraphQL


I am on xcode 11.4 and swift4, and I currently am working with AWS GraphQL and learning the proper workflow. My amplify.xyz config is set as

push=true
modelgen=true
profile=default
envName=amplify

So that models are generated as they are created/edited. In schema.graphql I define user:

type User @model {
    id: ID!
    firstName  : String!
    lastName   : String!
    handle     : String!
    email      : String!
}

And build/run the application, and am able to create/read an instance of user as expected. Then suppose I add a simple new field User @model so that I have:

type User @model {
    id: ID!
    firstName  : String!
    lastName   : String!
    handle     : String!
    email      : String!
    blank      : String!
}

And then clean the build folder, and rebuild the application. I then get the inexplicable error

No such module 'Amplify' HomeController.swift

Even though changing the Model class and Amplify appear unrelated. If I remove blank, and clean and rebuild, things are normal again. What is the reason for this behavior?

For reference, here is my podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'alpha' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for alpha
    pod 'amplify-tools'

    pod 'Amplify'
    pod 'AWSPluginsCore'
    pod 'AmplifyPlugins/AWSAPIPlugin'

    pod 'AWSMobileClient', '~> 2.13.0'      # Required dependency
    pod 'AWSUserPoolsSignIn', '~> 2.13.0'

    pod 'AWSAppSync', '~> 3.1.0'
    pod 'AWSMobileClient', '~> 2.13.0'
    pod 'AWSAuthUI', '~> 2.13.0'
    pod 'AWSUserPoolsSignIn', '~> 2.13.0'

end

______________________ UPDATE ___________________

I an amplify push as Julien S suggested, and make sure all the files in amplify/generated/models are moved to the top level directory per (https://aws-amplify.github.io/docs/ios/start?ref=amplify-iOS-btn). Now this problem No such module 'Amplify' HomeController.swift is solved. However I can no longer find the data that was saved before the model was updated. For reference, when the user creates an account, I access the user's token and save it along with the user's email. Then next time the user opens the app, I get the token again and query the user db by token. Relevant code:

class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync {

    func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {

        AWSMobileClient.default().getTokens { (token, error) in
            if let error = error {
                callback(nil,error)
            }
            callback(token?.accessToken?.tokenString, error)
        }
    }
}

In MainController.swift:

override func viewDidLoad() {
    super.viewDidLoad()

    // get user token
    let pool = CognitoPoolProvider();

    pool.getLatestAuthToken { (token, error) in

        if let error = error {

            print("error: \(error)")

        } else {
            self.getUserData(token: token!)
        }
    }
}

func getUserData(token:String){

    print("token >>>> \(token)")

   // this is successful. you got all the user stuff
   // when you change the user model, you can no longer query the user
   let _ = Amplify.API.query(from: User.self, byId: token) { (event) in
        switch event {
            case .completed(let result):
                switch result {
                    case .success(let note):
                        guard let note = note else {
                            print("API Query completed but missing user")
                            return
                        }
                        print("API Query successful, got user: \(note)")
                case .failure(let error):
                    print("Completed with error: \(error.errorDescription)")
                    }
            case .failed(let error):
                print("Failed with error \(error.errorDescription)")
            default:
                print("Unexpected event")
        }
    }

}

Solution

  • I'm assuming you're configuring everything through the Amplify CLI? Are you using the new or old iOS SDK for Amazon? My workflow has generally been when adjusting my schema.graphql file to run an amplify push command to actually propagate those changes to the backend and making sure to have it generate the API.swift file. Are your graphql operations being run through the autogenerated api.swift file? You can also run amplify codegen to recreate the api.swift file as well.