How do I configure full URLs in xcconfig files
Asked Answered
F

6

81

I have an xcconfig file which contains a configuration for which server my app should hit. In debug mode, this will be a different server than for release builds.

The problem I have is that a URL of the form http://www.stackoverflow.com is treated as a comment after the double slash. So the string I get in code is 'http:'

I have read that I can put a -traditional build flag on Info.plist, I was wondering if someone else has had a similar issue and has solved it?

Thanks.

Flavory answered 23/1, 2014 at 19:42 Comment(2)
Have you tried to enclose the URL in quotation marks: "http://bla.com" ?Rearmost
yes, quotation marks and the standard \/\/ escaping does not seem to make a difference. In the \/ case the string becomes http:\/\/stackoverflow.comFlavory
P
137

Here's a simple workaround:

WEBSITE_URL = https:/$()/www.example.com
Pandemonium answered 30/3, 2016 at 0:23 Comment(7)
Unless you do a substitution into your plist file as <string>$(WEBSITE_URL)</string>. Ask me how I know.Hiddenite
@RobertAtkins if you're taking about your Info.plist you should think about using two separate plist files for debug/release. you can configure this in your project's Build Settings->Packaging->Info.plist File configuration (expand to show debug/release). A little annoying I know, but it may do the job for you.Flavory
@RobertAtkins I don't understand your comment. Are you saying that the workaround doesn't work for the scenario you described? If that's what you meant then I'm puzzled, because that's exactly how I'm using it.Pandemonium
If you use the $() trick in your .xcconfig file but have the substitution for $(WEBSITE_URL) in your Info.plist, it doesn't work. If you say ${WEBSITE_URL} (note curly braces) it works.Hiddenite
@RobertAtkins Ah— thanks for the clarification. I used curly braces in my info.plist so I didn't experience the problem you originally pointed out. Good catch.Pandemonium
@RobertAtkins so am I right to say (1) curly braces needs to be used in the plist (say ${PUBLIC_KEY}, and (2) the corresponding xcconfig needs to have $() before each of the backlash \n for it to not escape the character? I am trying to get a public key into the xcconfig to no avail - it's taking the \n character literally. Pasting it into the build settings directly has no issues.Mameluke
Looks like we can use <string>$(WEBSITE_URL)</string> directly nowadays at least in Xcode 13.2.1Indigent
R
52

I also could not figure out how to use a double slash in a xcconfig file. But I found a workaround in

from the Xcode-users mailing list: In the xcconfigfile, save the URL without the http scheme:

MYURL = stackoverflow.com

In the Info.plist, set the property value to

http://${MYURL}
Rearmost answered 23/1, 2014 at 20:20 Comment(2)
Thanks. This brought an end to my problem. Cheers :)Tropopause
Best answer ! :)Sufflate
P
24

Just declare

SIMPLE_SLASH=/

Then your URL becomes

http:$(SIMPLE_SLASH)/www.stackoverflow.com
Pavior answered 14/4, 2015 at 16:48 Comment(1)
I like your way of thinking :PLytic
I
11
SLASH=/

API_URL=http:$(SLASH)/endpoint.com
Indigotin answered 14/11, 2017 at 16:8 Comment(3)
The $(SLASH) will resolve to the variable defined just above /. So this will resolve to the proper http://endpoint.comFlavory
Exactely @Flavory :)Indigotin
@StephenLeppik you add this code in your .xcconfig and get API_URL that return an url without to replace or anything !Indigotin
L
4

Another approach that improves readability could be:

PROTOCOL = http:/
API_URL = $(PROTOCOL)/www.stackoverflow.com

This way protocol can be used elsewhere

Luanneluanni answered 27/1, 2022 at 13:19 Comment(0)
J
-4

You shouldn't use a xcconfig file for this setting.

A xcconfig file is not a "normal" header or module file which is the input of the preprocessor and eventually the input for the compiler. It's nowhere specified how the xcconfig file parser treats character encoding, whether it recognizes escape sequences, whether it expands macros, and how character literals are defined and much more.

It's far better in this case, to have a "config.h" header file and use a conditional based on a preprocessor definition:

#if defined (DEBUG)
    NSURL* url = ...
#else
    NSURL* url = ...
#endif

Here, DEBUG is defined for Debug configuration by default. You may #define any other definition in the build settings under "Preprocessor Macros".

Jacklight answered 23/1, 2014 at 20:43 Comment(5)
This is the way to go if you aren't forced to use build settings (Unfortunately I am). I'm going to try and sway the opinion of my teammates.Flavory
Sometimes you want to inject preprocessor defines in during the build phase, not in the code, example compiling in a private key.Reliance
@JohnTwigg For performing any actions before, during or after building, the preferred way is to define a "Run Script Build Phase" which runs at specific points in the build process. For example, you might set the build version strings in the Info.plist, search and replace a certain source file, convert it to an http file (or any other kind of document using command line tools) and place it into the bundle resources, and virtually any other kind of task that comes to mind :) You can then streamline that process using a "rake file" which customized rake tasks, e.g. "generateKey" or what ever. ;)Jacklight
Sometimes you don't want to hard code a url in your project's version control system, for example my server running on localhost is at 192.168.1.27, and that may be a totally different ip for another team member. I would not want to has #if defined (DEBUG) <my local server ip> in my code. I would want to use something like debug.xcconfig as a file that is not checked into version control so that different team mates can configure it for their own machine.Judon
@Judon Alternatively, you can set such variables as a shell environment variable. Unfortunately, in Mac OS X environment variables for GUI apps are read differently than those for console apps. But there's an easy solution: for GUI apps we need to set the environment variables in launchd. See here, accepted answer on SO: #604285Jacklight

© 2022 - 2024 — McMap. All rights reserved.