Override info.plist value at runtime

I'm testing my user interface in light and dark mode settings and I have the "NSRequiresAquaSystemAppearance" set in my info.plist file and I was wondering if there is a way to override that setting at runtime, rather than having to constantly go to my info.plist and setting it manually between runs?

I'm searching for something like

NSApp.effectiveAppearance.setValue(true, forKey: "NSRequiresAquaSystemAppearance")

Replies

You cannot do that. info.plist is part of bundle and cannot be changed at runtime.

See details here for instance:

https://stackoverflow.com/questions/40214673/setting-value-to-info-plist-file-from-swift?noredirect=1&lq=1

But why change the info.plist and not directly the appearance ?

https://developer.apple.com/documentation/appkit/nsappearancecustomization/choosing_a_specific_appearance_for_your_macos_app

  • Well, aren't you a daisy! That's what I was looking for, not necessarily trying to do something that isn't allowed. I read that article on SO, but I was understanding it as actually modifying the info.plist file on disk during run time, not changing a value on the fly. My misunderstanding.

    I have no idea why the link to the apple documentation didn't come up for me when I was searching for dark and aqua appearance. Much appreciated! I owe you a beverage of your choice!

  • That will be a Ti'punch…

  • I checked the answer button too soon. For some reason this isn't working for me.

    I am running on a late 2015 X86_64 iMac with macOS Big Sur 11.5.1 and Xcode 12.5.1. I have my system preferences to use dark mode system wide.

    However, when I run this code is does not change the window to .aqua as the documentation states. My assumption is that adding in this .aqua appearance it would override the system. Is that not the case?

    import Cocoa class ViewController: NSViewController {   let greenFilter = CIFilter(name: "CIFalseColor")!   let greenCIColor = CIColor(red: 0.3333, green: 0.8667, blue: 0.0, alpha: 1.0)   let darkGreenCIColor = CIColor(red: 0, green: 0.5373, blue: 0.1137, alpha: 1.0)   let redFilter = CIFilter(name: "CIFalseColor")!   let redCIColor = CIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)   let darkRedCIColor = CIColor(red: 0.6275, green: 0.0, blue: 0.0078, alpha: 1.0)   var redFilterColorChange = false   var progressBar: NSProgressIndicator?   var timer = Timer()       override func viewDidLayout() {     NSApp.appearance = NSAppearance(appearanceNamed: .aqua, bundle: nil)   }       override func viewDidLoad() {     super.viewDidLoad()     // Do any additional setup after loading the view.     self.view.appearance = NSAppearance(named: .aqua)     print("Appearance = \(self.view.appearance!.name)")     let progressFrame = NSRect(x: view.frame.midX-view.frame.width/2+30, y: view.frame.midY-10, width: view.frame.width-60, height: 20)     progressBar = NSProgressIndicator(frame: progressFrame)     self.view.addSubview(progressBar!)     progressBar?.contentFilters = []     if self.view.appearance?.name == .darkAqua {       greenFilter.setValue(darkGreenCIColor, forKey: "inputColor0")       redFilter.setValue(darkRedCIColor, forKey: "inputColor0")     } else {       greenFilter.setValue(greenCIColor, forKey: "inputColor0")       redFilter.setValue(redCIColor, forKey: "inputColor0")     }     // Apply the filter     progressBar?.contentFilters = [greenFilter]     progressBar?.isHidden = false     progressBar?.isIndeterminate = false     progressBar?.doubleValue = 0     progressBar?.maxValue = 1.0     startTimer()   }   override var representedObject: Any? {     didSet {     // Update the view, if already loaded.     }   }   func startTimer() {     print("Starting timer")     timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateProgress), userInfo: nil, repeats: true)     print("Progress bar frame = \(progressBar!.frame)")   }   @objc func updateProgress() {     if progressBar!.doubleValue < 1.0 {       if progressBar!.doubleValue > 0.75 && !redFilterColorChange {         progressBar?.contentFilters = [redFilter]         redFilterColorChange = true       }       progressBar?.doubleValue += 0.01       print("Progress bar value = \(progressBar!.doubleValue)")     } else {       timer.invalidate()       progressBar?.contentFilters = [greenFilter]       progressBar?.doubleValue = 0       progressBar?.isHidden = true     }   } }