The "npx cap sync" Command Overwrites the XCode File "project.pbxproj"

I have an Ionic/Capacitor mobile app that I am building for iOS. This app uses a custom Capacitor plugin that I have written. The custom plugin requires linking against a library/framework from a 3rd party vendor.

In order to get XCode to link the custom plugin against the 3rd party library, I must go into XCode settings for the project and add the 3rd party library/framework to the settings. If you are familiar with XCode, then this is done by clicking the “Pods” project to access the Pods project settings, choosing the TARGET of my custom plugin to access its settings, then choosing “General” tab, scrolling down to “Frameworks and Libraries” section and adding the 3rd party framework/library.

After the 3rd party framework/library is added to the XCode project settings, everything works perfectly. I can build my Ionic/Capacitor app (along with custom Capacitor plugin), then deploy it to my test iPhone device, and the app (and custom Capacitor plugin) works perfectly.

The problem appears when I need to make a change to the JavaScript Ionic web app code. After making any changes to the Ionic web app (and compiling with “ionic build” command), of course I must run “npx cap sync” to copy the new compiled web application to the XCode project. The “npx cap sync” command does what it’s supposed to do, EXCEPT that it has the nasty side-effect of overwriting the “project.pbxproj” file in the XCode project.

This is a huge problem because that file (project.pbxproj) contains the customized settings to link against the 3rd party library/framework that my custom plugin in needs. So, every time I run “npx cap sync”, I need to manually dig through the XCode settings to re-add the 3rd party library/framework that our custom plugin requires.

This is a giant hassle, and it seems like I shouldn’t need to do this. I did notice that if I run “npx cap copy” (instead of “npx cap sync”), then it doesn’t overwrite the “project.pbxproj” file. However, I’ve always used “npx cap sync” since it definitely copies everything I need.

Here is a video I made for our development team showing the bug and what needs to be done to work around it: https://valmarc.com/download/BP2_Capacitor_Xcode_bug_workaround.mp4

Is there any other solution for linking a custom plugin against a 3rd party library/framework in iOS?

npx cap sync it’s useful if you update your libraries / plugins, so you don’t need to run it all the times.
Npx cap copy, after ionic build --prod is more than enough if you changed nothing but the code

You should never change anything in your Pods manually.
If your plugin requires to change something in its Pods project, then you are doing something wrong.

Capacitor plugins are CocoaPods projects, and CocoaPods allows to add frameworks to the Pods without doing it manually, you probably need to add “vendored_frameworks”, or “frameworks” to your plugin podspec file.

I don’t know what it means to “change anything in your Pods”. I assume I’ve given you some evidence that I’ve done that, but I don’t know exactly what I did to violate that rule.

In any case, it sounds like you’re saying that there is a way to modify a plugin podspec file. I see a file in the Capacitor plugin folder structure named “ios/Pods/Local Podspecs/Capacitor.podspec.json”. Is that the file you’re referring to?

I see you’ve linked to some documentation about Cocoa Pods, but I really don’t know anything about Cocoa Pods, and I wouldn’t know which CocoaPods files I’m allowed to modify. Apparently I’ve already “changed [something] in [my] Pods” that got me into this mess, so I fear if I just read some CocoaPods documentation, then I’ll end up changing something else in my Pods that I’m not supposed to.

Is there some Capacitor-specific documentation that explains how to link a plugin against a 3rd party library/framework? I can’t be the first one who need to do that. I would think it’s a common use case.

I mean this:

You should never go to Pods and do any manual changes in the Pods project settings.

Your plugin’s podspec is in the root of your plugin folder. It’s usually called something like YourPluginName.podspec.

As I said, Capacitor plugins are CocoaPods libraries, so the docs for adding a third party SDK are the docs from CocoaPods.
I already linked the podspec specific docs, that’s what you have to check as the podspec is the file you have to edit. Also told you, you have to search for “vendored_frameworks” (if it’s a 3rd party framework), or “frameworks” (if it’s a system framework). The way the docs are built don’t allow to link those directly, you’ll have to click “single page” on the left and search for vendored_frameworks.

Ok thank you for the advice, and I will definitely look at the “vendored_frameworks” settings in CocoaPods documentation.

All I was trying to say is that it’s not clear at all how to know “what’s allowed” and “what’s prohibited”. So the rule is “you should never change anything in your Pods manually.” But then apparently it’s okay to add “vendored_frameworks” to the podspec file, which seems to violate the previous rule. Is there any Capacitor documentation that would tell me “don’t touch your Pods manually”, UNLESS you’re adding “vendored_frameworks” to the podspec and then it’s okay.

I’m not trying to give you hard time as I appreciate your advice, which I will follow. I’m just pointing out to the Capacitor team that there seem to be some unwritten rules about what to do in different situations.

The difference is the podspec is one of your plugin files, that CocoaPods will use to build the Pods of your app. So you are not editing your app’s Pods, you are editing the plugin files.

Capacitor doesn’t make the rules, as I said, Capacitor plugins are CocoaPods libraries, so the rules are set by CocoaPods, not by Capacitor.