0

I have a codebase with many hundreds of ObjC #defines for settings in an iOS App. e.g.

#define kSettingName NO

However, these are seemingly not visible to Swift code (not in scope error) as I'm adding new Swift code to the codebase that still needs to access all of these settings (as does the old ObjC code). Is there a good way to have these many settings visible in Swift?

So far, the best way I've come up with is find/replacing YES/NO with true/false (which makes them visible to Swift, but then, you can't easily do:

if kSettingName { }

in Swift. I could write an Int32 extension:

extension Int32 {
    
    var isTrue: Bool { return self != 0 }
    
    static func == (lhs: Int32, rhs: Bool) -> Bool {
        if rhs {
            return lhs != 0
        } else {
            return lhs == 0
        }
    }
    
}

Which leads to being able to use either

if kSettingName.isTrue { }

or

if kSettingName == true { }

but both are a little less nice than just

if kSettingName { }

Does anyone have any better ideas here?

Tom
  • 68
  • 8
  • It is nothing to do with YES/NO vs true/false. The problem is that #define is a C compiler directive that results in text substitution. At compile time the text `kSettingName` is replaced with `NO`. There is no actual symbol `kSettingName` to be exposed to Swift. Probably the simplest way is to create a class with numerous static properties which are assigned using the #defined values. Then in swift or in objective C you can access `SettingsClass.someSetting` – Paulw11 Aug 02 '22 at 12:53
  • You could add `static bool sSettingName = kSettingName;` to the bridging header file, that would be imported as `var sSettingName: Bool`. – Martin R Aug 02 '22 at 13:14
  • @Paulw11: *Some* define directives *are* imported to Swift (such as string and integer constants), so it is not generally impossible. (But YES/NO are apparently not imported to Swift.) – Martin R Aug 02 '22 at 13:17
  • @MartinR Yep - that certainly seems to work well as an option (although leaves another bit of code hanging around :D ). true/false or TRUE/FALSE in the original settings files end up being Int32's, which isn't ideal. Doesn't seem like there's an automatic option. – Tom Aug 02 '22 at 13:24
  • @Tom: Can you replace `#define kSettingName NO` by `static const bool kSettingName = false;` ? That would be imported to Swift as a `Bool`. – Martin R Aug 02 '22 at 14:14
  • @MartinR Yep, that works, but due to the number of settings (and the fact a build system merges in custom settings packs into that same file), I think your first suggestion in the bridging header is the best one for me, however, that does look to be a good solution too if anyone else is referring to this question in future! – Tom Aug 02 '22 at 15:07

0 Answers0