react-native: Unable to use other configurations than Debug and Release on 0.40
Description
in XCode we can duplicate the default build Configurations by navigating to our Project -> info tab -> click on the plus symbol and duplicate any of the existing configs (debug, Release). Set a new name. Now when edit our scheme and tell XCode to use our new config the build process won’t finish. Most probably you’ll end up with this error:
fatal error: 'React/RCTBundleURLProvider.h' file not found
After staring at the screen for a day I think that the issue is that the build script is copying the React files to either debug-iphoneos or release-iphoneos instead of using the “newconfig”-iphoneos directory.
REPROPDUCTION
Steps to reproduce:
- create a new RN project:
react-native init test
-
Now open the project in XCode, click on your project in the folder tree. Then select the project -> your project and navigate to the Info tab. Duplicate one of the configurations and give it whatever name you like.
-
Edit your current scheme and select the new configuration in the “build configuration” option. Now run the project. It should fail.
-
You can repeat the same steps on RN 0.39 and it works…
Here a few screenshots of the proper screens in XCode:
And on this screen you can see that RTCBundleURLProvider.h is being copied, but to the wrong path
Solution
Don’t have one yet, most probably the issue happens somewhere in runIOS.js
Additional Information
- React Native version: 0.40
- Platform: iOS
- Operating System: MacOS
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 54
- Comments: 55 (10 by maintainers)
Commits related to this issue
- readme: improved “Multi-Deployment Testing” chapter for iOS (#690) After RN 0.40 it is not possible to use other configurations than Debug and Release (https://github.com/facebook/react-native/issues... — committed to microsoft/react-native-code-push by sergey-akhalkov 7 years ago
- Move all header imports to "<React/..>" Summary: To make React Native play nicely with our internal build infrastructure we need to properly namespace all of our header includes. Where previously yo... — committed to facebook/react-native by javache 8 years ago
- [RN] Add "Dev" iOS configuration This configuration is the same as release, but the bundle identifier is changed so it can coexist with a Release build. In addition, the app name is changed to "Jitsi... — committed to saghul/jitsi-meet by saghul 7 years ago
- fixing snapshot fails, see comment https://github.com/facebook/react-native/issues/11813\#issuecomment-273279257 — committed to Suprnovae/cockpit-app-abctotaal by zirconias 7 years ago
While adding a configuration with the same name works, it’s not the most CI-friendly or future-proof solution. This is what I did, instead:
Added the React build target under the current scheme for my project. (Sidenote: if you’re using fastlane to deploy, keep your project’s build target in first place, otherwise fastlane gets confused and thinks you’re building a library, so it never builds an ipa).
Added React under [Target] > Build Phases > Target Dependencies, which made Xcode build React before building the rest of the project.
Under [Target] > Build Settings, added a new User-Defined setting, called
REACT_HEADERS_PATH
. For all configurations not named Debug or Release, I set that to$(BUILD_DIR)/Release-$(PLATFORM_NAME)/include
.Under [Target] > Build Settings > Header Search Paths I added
$(REACT_HEADERS_PATH)
as an entry.Repeat for all targets in your project.
When my project builds, React builds first, and since it doesn’t know about configurations other than Release and Debug, it builds with the Release configuration. This places its headers under
[build dir]/Products/Release-iphoneos/include
. Since this path is now in the Header Search Paths of the main project, it gets picked up and everything else builds fine.Hope this helps.
Updated 4/13 to mention repeating these steps for all targets (thanks @Twinski) and to change to the much shorter and more reliable
$(BUILD_DIR)
(thanks @hoolymama).I think what you are looking for is something like:
check this out: https://github.com/facebook/react-native/commit/46422ddd99a798d1af9ea337629f2de5334d72fa
Guys, the easiest fix that I found - is to set “CONFIGURATION_BUILD_DIR” in buildSettings of your configuration like:
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)";
Or if you want to set in XCode: Your Project -> Build Settings -> Build Locations -> Per-configuration Build Products Path for your new configuration:
$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
For anyone coming here, React-Native has inherent problems with adding build configurations because of the way the packenger references the react-native xcode project libraries from the node_modules folder. In hopes this will be solved natively, the best approach for now (React Native Version 0.45.1 and belowish) is this:
(just jottet down for dummies and colleagues who are not that familia with the magic world of xcode)
Use Schemes Manager by @blargity
*.xcworkspace
and not the*.xcodeproj
of yourios/
folder. Than transfer the learnings to your real project.npm run fix-xcode
(with that example), you’ll see the following. This should be done anytime after you run npm install, hence, the postinstall reference:Tips & Bottle Necks
GoogleService-Info.plist
for google login (you could reference them in your AppDelegate file). However, we try to touch as little of the native code as possible to have little hassle in upgrading further rn-versions. The best way to solve such situations is to have an extra folder in yourios/
folder, which is not added to the xcode project. And have files, depending on their build config suffix be copied to the app at build time. I.e. we manage our firebase files like so: Here our script (simple shell command):Note: I jotted this down because it was quite a hassle to get react-native into a common xcode workflow. So this is also for my colleagues and my memory. I plan for a while to turn this into a proper blog post. But until than, this here is my scratch pad to signal what mess is behind this issue . 😇
I built a package that should help with automatically setting all of the build configurations up in your libraries on each subsequent install:
https://www.npmjs.com/package/react-native-schemes-manager
Please give it a try and let me know how it works for you. We’ve got ~20 native libs now in most of our RN projects, so manually managing this would have been a nightmare.
I would like to second that this is a major headache. Even if I patch it to find React, it can’t find any other native dependencies. Do I have to patch the header search paths for every single dependency I add to the project?
Note, that if you’re using Cocoapods, you may have to change another configuration variable to point to Release, or it won’t be able to find linked Pods:
@K-Leon We have had the same issue with our
Staging
build configuration. AddingStaging
as a configuration to the React.xcodeproj sorted our 0.40.0 build issues.Release
andDebug
worked out of the box.When I jotted that down, I hoped a blog article would be obsolete by the time it goes online. Aka improvements of the metro bundler. Oh well - for better SEO I’ll add it to my todo list. Hopefully saving some devs the long path of desperate hacks until they find that comment. 🙃
I can’t quite make it work with $(BUILT_PRODUCTS_DIR)/Release-$(PLATFORM_NAME)/include For me it resolves to build/Staging-iphoneos/Release-iphoneos/include Its probably something with my configuration - I’ll experiment a bit later, but for now BUILD_DIR is working okay. Cheers!
Just figured it out: You need to copy the Release Target in ‘React’ Project too with the same Name as the parent Target has. Now we need an idea how to make it less troublesome ( without touching React) or we just document it somewhere?
I just download CORS extension for chrome and it works for me
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related
@tisho Thx! Did the trick for me. Extra thing that was needed in my case due to link errors: add “$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)” to Library Search Paths (only for the custom configuration)
Just want to add, because I spend all night implementing the iOS build configuration set up for BuddyBuild that it is important to set the library search path recursive.
@jamesone @blargity’s I’m using react-native-scheme-manager (thanks @blargity!) and works great locally. Buddy Build is still failing though 😦
For anyone who comes across this, I managed to piece together a working XCode setup to get:
Build
andArchive
in myreact-native init
apps (using Cocoapods); if you’re usingfastlane
, this supports its deployment, as wellStaging
,Angel
, etc.)Made a post on an issue in Microsoft’s code-push repo detailing my setup.
I am getting this error on Buddybuild - I’m unsure how it can be fixed! I tried using @philipshurpik solution but got the same errors on buddybuild, but when I ran the same xcode build command that buddybuild uses locally, it fixed it 🤔
After @j2kun 's step, I had to add
"$PODS_CONFIGURATION_BUILD_DIR"
as recursive to Framework Search path to pass the build with cocoapods.How do I
Added the React build target under the current scheme for my project
? It’s not working for me so far. Seems like that’s the only step I’m missing. Still getting this error:This is a bug/feature of Xcode. It attempts to build sub-projects using the same configuration as the main project. If that configuration does not exist, Xcode uses the Release configuration. With the latest changes to public headers exposed by React.xcodeproj, these headers now go to the build path of the sub-project, which is configuration-dependent.
Shout out to @D1no! your solution worked for me! Been banging my head against the wall for the past few days. The solution worked for my CI system as well (buddybuild).
@tisho Your answer is very exciting, according to your guidance, I built a number of new target, and can build success. But the new target fails in archive:
Just want to add that this error occurs with a clean project boilerplate based on react-native init. The error mentioned and error icon are there from the start. However the error mentioned didn’t cause the build to fail, the simulator was still able to load up.
Steps to reproduce:
react-native init <project-name>
#import <React/RCTBundleURLProvider.h>
Package/Software Versions installed as follows:
What a mess!!! I just spent several days trying to figure out what is going on with my XCode project. We rely on custom configs heavily - this completely broke our project. When is this going to be fixed proper???
In case anyone else runs into this issue and wants to test out the schemes-manager solution, I created an example project that incorporates @D1no 's guide as a github project you can pull and play around with. I spent some time hard-coding paths to header files and realized that this would not scale well once more developers ended up working on our projects, so decided to go the schemes-manager route, and everything works great so far.
@D1no @jamesone yes finally! all I ended up having to do was set our Build Configuration to Staging for Archive as jamesone suggested. D’oh! Was setting it for Run, just not for Archive. Thanks!
If anyone is running into this issue when using xcode’s workspaces, just make sure to check the settings of all your projects within the workspace.
@tisho Fix seems to be working! Maybe it’s also useful to say that you also should repeat the $(REACT_HEADERS_PATH) for the VigiTest Target!
@tisho you deserve a medal for this!