Using compiler variables in Swift
The -D
flag to C compilers defines a preprocessor macro. There are no preprocessor macros in Swift. So if you're looking to do something like:
// compile with -DPORT_NUMBER 31337
var port = PORT_NUMBER // error
... you can't. Swift is designed for source code to be syntactically complete before compilation. If you could switch out blocks of it at build time, you'd break the ability of the toolchain to help verify that your code is correct. (Partly this is because preprocessor macros in C are textual replacement: you can use them to rewrite any part of the language, not just fill in values for variables.)
The Swift compiler does have a -D
flag, but its use is more limited: you can use it for build configurations only. So, if you wanted to do something like the following, you'd be cool:
// compile with -DUSE_STAGING_SERVER
#if USE_STAGING_SERVER
var port = 31337
#else
var port = 80
#endif
Note that unlike C, everything inside an #if
block needs to be syntactically complete. (For example, you can't put just the declaration line of a func
in an #if
block and leave the function body outside the conditional.)
Of course, this doesn't help you if you want to have a configuration value set at compile time be used in your code. For that, I'd recommend alternate approaches. Xcode can still do textual substitution in resource files, like property lists. (Note that the Info.plist that comes with your app is full of things like $(TARGET_NAME)
, for example.) So, you could include a bundle resource with your app whose contents are populated at compile time according to your project settings, then read your port number from that.
Xcode: how to compile environment variables and refer to them in Swift?
You can do a pre-action script in Xcode build section
Which will modify placeholder with the following code:
let apiKey : String = "<# THE_API_KEY #>"
Modify the code directly in the source file
Before each build.
And you can add another one if you have a production key in the Archive pre-action
Exemple
place the apiKey
variable in the file you want to access it
In Pre-action
do a script to remplace a place holder text like THE_API_KEY
The script will look like this
cat $PROJECT/$PATH_TO_FILE | sed 's/THE_API_KEY/YOUR_KEY' > $PROJECT/$PATH_TO_FILE
Don't forget to clean the code to avoid put the API key in you commit
With a Post-action
cat $PROJECT/$PATH_TO_FILE | sed 's/YOUR_KEY/THE_API_KEY' > $PROJECT/$PATH_TO_FILE
Swift: Using `var` leads to a compiler warning, using `let` leads to compiler errors?
Your
public func push(_ newItems:[Item]) {
is a method of public class Stack<Item>
, which is a reference type, therefore you can call it on a constant:
let s4: Stack = [1,2,3]
s4.push([4,5])
On the other hand, the variadic method
public mutating func push(_ items:Item...)
is an extension method of protocol CanStack
, which can be adopted by structs as well, therefore it requires a variable. That is why
let s8 = Stack([4,5,6]) // init by array
s8.push(10, 11) // Error: Extra argument in call
does not compile.
Here is a shorter example demonstrating the problem:
protocol P {
mutating func foo()
mutating func bar()
}
extension P {
mutating func bar() {}
}
class C: P {
func foo() {}
}
let c = C()
c.foo()
c.bar() // Cannot use mutating member on immutable value: 'c' is a 'let' constant
The underlying reason (as I understand it from the sources listed below) is that a mutating func
called on a reference type is not only allowed to mutate the properties of self
, but also to replace self
by a new value.
It would compile if P
is declared as a class protocol instead (and the mutating
keyword is removed):
protocol P: class {
func foo()
func bar()
}
extension P {
func bar() {}
}
Related resources:
- Proposal: Intermediate mutation qualifier for protocol functions on reference-types in the Swift forum
- SR-142 mutating function in protocol extension erroneously requires
var
declaration of class variables bug report.
declaring PHImageRequestOption variable in swift gives compiler error
Try below code as you are using swift:
let options = PHImageRequestOptions()
Related Topics
Skaction Completion Handlers; Usage in Swift
How to Draw a Cosine or Sine Curve in Swift
Filter Realm Objects to Only Get One (Distinct) Object by Attribute
Appending Tuples to an Array of Tuples
Swift 2.0 Get Mirrored Superclass Properties
How to Save the Attributed String (Text) into File (Swift, Cocoa)
Get Fullpath or Convert to Fullpath
How to Access a Swift Enum Associated Value Outside of a Switch Statement
Swift, How to Implement Hashable Protocol Based on Object Reference
How to Create an Array with Incremented Values in Swift
Mutating Function Inside Class
How to Implement iOServicematchingcallback in Swift
How to Demonstrate a Zombie Object in Swift
How to Stream Remote Audio in iOS 13? (Swiftui)
Swift [1,2] Conforms to Anyobject But [Enum.A, Enum.B] Does Not
How to Create a Multi Line Text Field in Swiftui for MACos
How to Transfer the User's Score to Another Scene in Swift and Spritekit
Difference Between Dispatchsourcetimer, Timer and Asyncafter