1

i have an Obj-c class "constants.h" that looks like this:

//  constants.h

#import <Foundation/Foundation.h>

@interface constants : NSObject
#define kLookAhead 3600*24*7*4 //seconds*hours*days*weeks
end

In my myProduct-Bridging-Header.h, I have:

#import "constants.h"

However, when I call kLookAhead in a Swift class, e.g. like this

let timeInterval = kLookAhead

I get the error message "Use of unresolved identifier 'kLookAhead'"

All other classes that I import in myProduct-Bridging-Header.h are working just fine, and kLookAhead is successfully used in my objc classes.

Is there something I should know?

Sjakelien
  • 2,255
  • 3
  • 25
  • 43

2 Answers2

1

Only "simple" macros are imported from (Objective-)C to Swift, compare "Interacting with C APIs" in the "Using Swift with Cocoa and Objective-C" reference. For example,

#define kSimpleInt 1234
#define kSimpleFloat 12.34
#define kSimpleString "foo"

are imported to Swift as

public var kSimpleInt: Int32 { get }
public var kSimpleFloat: Double { get }
public var kSimpleString: String { get }

but

#define kLookAhead 3600*24*7*4

is not imported. A possible solution is to replace the macro definition by a static constant variable:

static const int kLookAhead = 3600*24*7*4;

Remark: Note that a day does not necessarily have 24 hours, it can be 23 or 25 hours when the clocks are adjusted back or forward for daylight saving time. It is generally better to use DateComponents and Calendar methods for calendrical calculations instead of fixed time intervals. Example:

let now = Date()
let fourWeeksAhead = Calendar.current.date(byAdding: .weekdayOrdinal, value: 4, to: now)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • 1
    Thanks, for now, I just replaced "#define kLookAhead 3600*24*7*4" with "#define kLookAhead 2419200". And thanks for the DateComponents tip. – Sjakelien Nov 25 '17 at 13:58
1

In Swift, simple macros are available through bridging header file. From Apple's documentation:

Where you typically used the #define directive to define a primitive constant in C and Objective-C, in Swift you use a global constant instead. For example, the constant definition #define FADE_ANIMATION_DURATION 0.35 can be better expressed in Swift with let FADE_ANIMATION_DURATION = 0.35. Because simple constant-like macros map directly to Swift global variables, the compiler automatically imports simple macros defined in C and Objective-C source files.

So, you are right in assuming that your macro should be available as a global constant. But, I guess all that multiplication had made it difficult for the compiler to see the macro as a simple one.

I used the result as a macro on a sample project and it worked

#define kLookAhead 2419200 //seconds*hours*days*weeks

let timeInterval = kLookAhead // worked
Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33