How to add generated files to target when using SPM?

I am following the Get Started documentation for the iOS SDK to integrate Apollo using Swift Package Manager. I am getting stuck at the end of Step 4 as the documentation does not explain what to do after the files are generated.

  1. Install the Apollo frameworks → SPM with Xcode Project - I added the Apollo dependency to the project
  2. Add a schema file to your target directory - I downloaded the schema from Apollo Studio and renamed its extension to graphqls
  3. Create .graphql files for your GraphQL operations - I added these to an operations.graphql file
  4. Setup and run code generation → SPM with Xcode Project - I installed the CLI, initialized it via ./apollo-ios-cli init --schema-name MyAppAPI --module-type swiftPackageManager, I did not modify the apollo-codegen-config.json file, and I ran ./apollo-ios-cli generate which created a MyAppAPI folder containing a Package.swift file and Sources folder

Now the documentation states:

Add the generated schema and operation files to your target

By default, a directory containing your generated schema files will be located in a directory with the schema-name you provided; your generated operation and fragment files will be in a subfolder in that same directory.

If your target is created in an Xcode project or workspace, you will need to manually add the generated files to your target.

I don’t know what to do now. I thought SPM created a module for you to hold these files, no need to manually add them to your target? I expected I’d need to integrate this generated Package.swift into my project but I don’t know how.

Please note we have two app targets, because it’s a whitelisted app we use the target to change the color scheme and such. So the generated API needs to be available to both targets. That’s why I’m attempting to use SPM because I was led to believe it creates a module that can be easily added to both targets, as opposed to CocoaPods where I understand you have to manually create a pod to add as a dependency to both targets. SPM sounds more straightforward when you don’t have a single app target so can’t use .embeddedInTarget with CocoaPods. Thanks for the help!

Hi @jordanh :wave:

I don’t know what to do now. I thought SPM created a module for you to hold these files, no need to manually add them to your target? I expected I’d need to integrate this generated Package.swift into my project but I don’t know how.

You’re correct that code generation will have created a Swift Package Manager module for you and while you don’t need to manually add all the generated files to your project, you do still need to manually add the package to your project. You can do that in the same way you originally added the Apollo iOS package but this time it will be a local package.

Thanks for your help @calvincestari. Would be good to update the docs to provide instructions for adding the package with Xcode - mentioning manually adding files to targets is misleading. :sweat_smile:

So I have added it by going to add a package, choosing Add Local, selecting the MyAppAPI folder, and selecting to add it to this project. Packages now appears in the project navigator and contains MyAppAPI. However, attempting to add a query apollo.fetch(query: GetMeQuery()) reveals an error:

Cannot find ‘GetMeQuery’ in scope

It offers a fix-it to import MyAppAPI however that reveals an error:

No such module ‘MyAppAPI’

Interestingly the previous error has disappeared and I can command click GetMeQuery to jump to its definition now.

Have I missed a step in adding the local package? I thought I’d have to add it to the targets but seems it’s available to all targets in the project.

OK, so we’ve added the dependency to your project but it looks like we’re still missing the step to link your target with the package. I looked for Apple documentation to explain how, and something that we could link to in the Apollo documentation, but didn’t find anything appropriate yet. So here is a screenshot showing where you need to link the framework to you target.

Thanks @calvincestari that worked! In regards to documentation, I don’t think you’d need to link elsewhere to provide instructions to integrate the generated package. A textual explanation alone should be sufficient, something like:

Add the local Swift package to the project: Select your project in the project navigator and switch to the Package Dependencies tab with the project selected. Click the add + button, click Add Local, select the folder containing the generated Package.swift file, choose your project in the Add to project dropdown, and click Add Package.

Link the package to your target: Select your target, click the add + button in the Frameworks, Libraries, and Embedded Content section, choose the generated module, and click Add.