18

I have a problem that I can't figure out, and I've searched everywhere.

I recently added Google Sign-in to my app, and it's working fine on the main target, however, since I'm using multiple targets to deploy a secondary version of my app, the second bundle identifier can't get added to "GoogleService-Info.plist". The Google sign-in code refers to this file by name, so I can't simply change the name for each version of the app like I've done for other plists.

I've tried adding environment variables to each scheme and using ${BUNDLE_ID} in the plist to change based on the chosen scheme, but it's not working either. Is there something I'm missing? How should a workspace with multiple targets use the same plist with different variables for each target?

Thanks!

Edit: Tried using an XCConfig file to replace the static values in the plist with compile-time variables. No luck, probably because I think Google Sign-in is accessing the file directly. I assume anyone using Google Sign-in with an app that has multiple targets (ad-supported vs. paid premium) must have a way around this. Please help.

Greg
  • 533
  • 3
  • 14
  • 1
    Have you looked at the custom build phases in Xcode? Create a phase for each target that copies the desired plist to GoogleService-Info.plist. – rascal2210 Aug 07 '15 at 11:19
  • Ever figure anything out with this? I'm trying to set up Google Sign in with two targets, and on one it works fine, and on the other, the Sign In modal view appears, but without a "Cancel" button. Weird. – Adama Sep 22 '15 at 18:45
  • Not yet, no. I'll probably re-visit the problem again in October to begin another push on releasing my secondary version to the app store. Did you manage to get two separate bundle IDs for your different versions? – Greg Sep 23 '15 at 19:07
  • 1
    Got it working using rascal2210's suggestion. I moved the main copy of the GoogleService-Info plist out of the app into 2 separate folders, then used the Build Phases "Copy Files" on each target to import the target specific plist into the Resources folder (chosen by the drop-down). Thanks! – Greg Oct 02 '15 at 20:49
  • @rascal2210 That's neat! Thanks a bunch mate. – Vijay Tholpadi Oct 07 '15 at 07:21
  • Trying to get custom build phases working. Any suggestions? – Sunkas Oct 13 '15 at 15:14
  • 1
    Sunkas, try the steps I mentioned on Oct 02. If you're still having trouble, let me know and I'll write a more complete guide. – Greg Oct 14 '15 at 16:07

3 Answers3

33

I had the same problem and I found a pretty simple solution.

Just copy the GoogleServices-Info.plist and put it in a different folder. The folder must be a physically different folder, since the filesystem won't accept same file names in the same folder. So create a real folder in finder and add it to XCode, don't use XCode groups.

Then change the target membership according to each plist file. Thats it!


Raphael
  • 3,846
  • 1
  • 28
  • 28
  • Elegant! @tentmaking owes you an "I love you" too! – Eric G Aug 12 '16 at 20:49
  • Hey Raphael how did you get this to work in a folder? Google seems to want it in the root, and my project crashes out on the second target. Any advice would be so very appreciated! – CodeNoob Aug 31 '16 at 03:17
  • 1
    Google just needs access to the file in the bundle. As long it is in the bundle it is fine, no matter in which folder it is. Under your target / Build Phases / Copy Bundle Resources you can see which files are copied to your targets bundle. – Raphael Sep 01 '16 at 11:30
7

I had the same problem. I have four different targets which needed to use the same GoogleService-Info.plist file but with different bundleIDs. I stumbled upon this excellent article from Restless Thinker which provided a solution to this exact problem.

PlistBuddy is a free tool provided by Apple and built-in in OSX.!

PlistBuddy can create and modify plist files. Here's a great tutorial by Fotis. He makes it seem like a piece of cake.

First thing is you check if the GoogleService-Info.plist file is listed under the Build Phases>Copy Bundle resources for each target. This should already be in place, but a recheck won't hurt. Add the file if it's not present.

The next thing you'd need to do is to create a new build Phase for each target. Go to your Project>Targets>Select your target>Build Phases Check the top-left area of the Build Phases screen for a + button.

Add a new custom phase. (You may already have the Run Script phase, in which case, just keep adding the commands after your existing commands)

Select New Run Script Phase and in the new box that opens up, enter your PlistBuddy command

/usr/libexec/PlistBuddy -c "Set :BUNDLE_ID ${PRODUCT_BUNDLE_IDENTIFIER}" $BUILT_PRODUCTS_DIR/$TARGET_NAME.app/GoogleService-Info.plist

Make sure your .app (under Product) filename is the same as your target name or this won't work. You can $TARGET_NAME.app to make it the same as your project.app name.

You can change more values in this way, just add another new line to the script. You'd need to add two more lines at least to change the CLIENT_ID and REVERSE_CLIENT_ID.

/usr/libexec/PlistBuddy -c "Set :CLIENT_ID 123456789012-abcdefghijklmnopqrstuvwxyzabcdefghijklm.apps.googleusercontent.com" $BUILT_PRODUCTS_DIR/$TARGET_NAME.app/GoogleService-Info.plist
/usr/libexec/PlistBuddy -c "Set :REVERSED_CLIENT_ID com.googleusercontent.apps.123456789012-abcdefghijklmnopqrstuvwxyzabcdefghijklm" $BUILT_PRODUCTS_DIR/$TARGET_NAME.app/GoogleService-Info.plist

You might have to clean for it to work. Build and run on device. You might need to check the little box under the Run Script which says 'Run script only when installing' when installing on a device. When i left this box unchecked, XCode kept referring to my old Derived data.

Using PlistBuddy, you can change any plist value based on the target. Hope this helped.

Neel
  • 71
  • 1
  • 3
0

make a seperate plist file for each target and dynamically switch between them. to do that you can check the answers here

Community
  • 1
  • 1
Essam Elmasry
  • 1,212
  • 11
  • 11