3

I'm having trouble replicating in Swift the Preprocessor Macro functionality offered by ObjC. I have heard that Swift has no preprocessor, so I'm looking for another way to implement this.

My end goal is to build my project using the command line tools, passing in a custom variable and value, which will be preprocessed and inserted into the code at specific points, before the build takes place.

This is the solution for ObjC:

Use this command to run a test:

xcodebuild \
    test \
    -scheme TestUserDefinedVariablesObjC \
    -destination 'platform=iOS Simulator,name=iPhone 6' \
    MY_VAR=42

I use MY_VAR in code like this:

int a = MY_VAR;

(I add MY_VAR to Preprocessor Macros in my target's Build Settings like this: MY_VAR=$(MY_VAR))

As a last resort, I could add pre-action to the scheme's Run phase that substitutes the correct values using sed or something like that, but it's not a great solution.

paulvs
  • 11,963
  • 3
  • 41
  • 66
  • possible duplicate of [Swift: iOS Deployment Target Command Line Flag](http://stackoverflow.com/questions/24369272/swift-ios-deployment-target-command-line-flag) – David Berry Dec 30 '14 at 17:21
  • @David I'm looking to pass a _variable_ from the command line to the app, not a constant. – paulvs Dec 30 '14 at 17:57
  • Same difference. In Xcode set it up as MY_VAR=$(MY_VAR) – David Berry Dec 30 '14 at 19:43
  • I read the linked question, but it doesn't show you would access it in Swift. – paulvs Dec 30 '14 at 20:03
  • 1
    I'm looking for some way to retrieve the value. I tried `MY_VAR=$(MY_VAR)` in Other Swift Flags, but then using `int a = MY_VAR;` produces a `Use of unresolved identifier 'MY_VAR'` error. – paulvs Dec 30 '14 at 20:08

2 Answers2

0

Are you using different keyset/keyboard? If so check "

example: Preprocessor Macros in my target's Build Settings MY_VAR=\"42\"

check " character. Change it with this "

0

Instead of using SED in a build-phase script, you could use the clang preprocessor. For example, put this in a file named macro-test.c

#if DEBUG
#define LOG(A) print(A)
#else
#define LOG(A) 
#endif

import Foundation

func hello()
{
    LOG("Hello, Swift macro!")
    
    let theAnswer = MY_CONST
    
    print("The answer = ", theAnswer)
}

Add a script build phase that runs the clang preprocessor:

#!/bin/sh
if [ $CONFIGURATION == "Debug" ] ;
then
    DEBUG="1"
else
    DEBUG="0"
fi
MY_CONST=42

clang -E -P -DMY_CONST=$MY_CONST -DOS=$OS -DDEBUG=$DEBUG "${SOURCE_ROOT}/macro-test.c" > "${SOURCE_ROOT}/macro-test.swift"

Add the generated swift file to the Xcode project.

user2342340
  • 1,489
  • 1
  • 8
  • 5