What's the Swift equivalent of Objective-C's #ifdef __IPHONE_11_0?
The iOS 11 SDK comes with Swift 3.2 (or Swift 4), so you can use a Swift version check to accomplish the same thing:
#if swift(>=3.2)
if #available(iOS 11.0, *) {
…
}
#endif
Swift errors using #if, #endif
Ideally, limit the usage of #if
as much as possible. Using preprocessor directives is always a bit of a code smell. In this case, you can simply use a boolean variable:
#if DEBUG
let debug = true
#else
let debug = false
#endif
Then simply use the variable:
var a = 0
var b = 0
...
else if debug && a == b {
}
In release mode the code will become unreachable and the optimizer will remove it anyway.
With a bit of imagination, we can find other solutions, for example, we can move the check to a function:
func isDebugCheck(a: Int, b: Int) -> Bool {
#if DEBUG
return a == b
#else
return false
#endif
}
or we can move the whole code to a separate function and replace if-else
by a return
(or continue
, depending on you needs), e.g.:
if a == 7 {
...
return
}
#if DEBUG
if a == b {
return
}
#endif
if ...
Xcode 9.1 upgrade to Swift 4 breaks #ifdef
Previously, I was using the 'Other Swift Flags' build setting in Xcode to pass '-DXCODE_BUILD'. Apparently that setting doesn't work for Swift 4. The new setting that does work is 'Active Compilation Conditions' (it should be set to include XCODE_BUILD, no need for the -D flag).
Conditional exclusion of code in Swift
The issue was about replicating the configuration in the Other Swift Flags file in the form
-D option
Apparently Swift ignores the flags in the preprocessor field. Now it accepts ||, && and ! without any problem with syntax:
#if option || !option2
......
#elseif option3
......
#endif
How to translate the following code snippet from Swift to Objective-C?
I have managed to solve this problem with a workaround discussed here.
#if __clang_major__ >= 12
NSLog(@"My Objective-C language support is what Apple Clang/Xcode 12.x can support.");
#endif
Note that clang_major or clang_minor etc. variables resemble (almost same to) Xcode versions and need careful investigation before the usage.
Swift replacement for Objective-C macro
The easiest way is probably to take advantage of string interpolation and use:
func FLOG(message:String, method:String = __FUNCTION__) {
println("\(method): \(message)")
}
Then you usage is similar to:
FLOG("Illegal value: \(value)")
Having the method argument default to __FUNCTION__
means that it will normally be replaced with the calling function name. Other automatic variables that you could use include __FILE__
, __LINE__
and __COLUMN__
. Unfortunately __PRETTY_FUNCTION__
is no longer available.
If you want more control over the formatting of the message than string interpolation allows, take a look at this question which demonstrates simplifying access to printf-style formatting in Swift, and would let you do:
FLOG("Illegal value: %x" % [value])
See also this post from Apple that addresses using __FILE__
and __LINE__
in assert
Is there an #ifdef to distinguish between Xcode 6.4 and Xcode 7 beta in Swift?
no, as Swift imposes all "define" path must compile.
sorry but old good times of #ifdef are gone
Related Topics
Protocol Doesn't Conform to Itself
How to Generate a Random Number in Swift Without Repeating the Previous Random Number
How to Make a Weak Protocol Reference in 'Pure' Swift (Without @Objc)
Nsdate Timeintervalsince1970 Not Working in Swift
Printing a Variable Memory Address in Swift
How to Make an Enum Decodable in Swift
In Swiftui, How to Increase the Height of a Button
Why Do Self and Self Sometimes Refer to Different Types in Static Functions
Using a Dispatch_Once Singleton Model in Swift
Deinit Method Is Never Called - Swift Playground
Nsurlsession Concurrent Requests With Alamofire
Getting "File Not Found" in Bridging Header When Importing Objective-C Frameworks into Swift Project