objective-cmacoscompiler-flagsmacos-darkmode

Write SDK version to binary when compiling from command line (macOS)


I am trying to detect whether the system is in dark mode. I have already tried reading AppleInterfaceStyle from the user defaults i.e.

    NSString *interfaceStyle = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
    BOOL isDark = [@"dark" caseInsensitiveCompare:interfaceStyle] == NSOrderedSame;

which works most of the time but has issues in Auto mode on Catalina.

Now from what I have read is that the more robust approach is to check the effectiveAppearance of NSApplication which looks like this:

    NSApplication *app = [NSApplication sharedApplication];
    NSAppearance *appearance = app.effectiveAppearance;
    NSAppearanceName appearanceName = [appearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
    BOOL isDark = [appearanceName isEqualToString:NSAppearanceNameDarkAqua];

The problem with this approach is that the application I am writing this for manually sets its appearance property, which prevents the effectiveAppearance from using the system appearance. I tried settings app.appearance = nil before checking the effectiveAppearance but it didn't help.

Now there also is [NSAppearance currentAppearance] which uses the appearance of the current thread. I'm not quite sure what this value resolves to if the thread hasn't set the value explicitly.

My big problem here is that I have no access to a machine running macOS to check my code, so I would highly appreciate if someone knows what to do here.


Edit: It looks like the issue is that the library isn’t compile against the correct version of the SDK. Or at least that version isn’t written to the library information.

From the documentation:

If you build your app against an earlier SDK but still want to support Dark Mode, include the NSRequiresAquaSystemAppearance key (with a value of NO) in your app's Info.plist file. Do so only if your app's appearance looks correct when running in macOS 10.14 and later with Dark Mode enabled.

I am already specifying the version through -mmacosx-version-min=10.14. From what I have found this issue is basically the same that I have, but I don’t quite understand what the solution is from the commit.

I guess it has something to do with the -isysroot and -platform_version. But I didn’t find any good reference for what they do and how they work.

My updated question would be:

How do -isysroot and -platform_version work and how do I use them to enable SDK specific functionality with my binaries?


Solution

  • The solution is quite simple. When manually compiling from the command line -mmacosx-version-min=10.14 needs to get passed to the compiler and the linker.