Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the name of a connected screen Swift

Does anyone know of a way to get the screen name, or model name/number from a display that is connected to the system? I've been looking around for quite some time to see if there is a way to do this. The only method I've seen anyone post only works with a deprecated API (CGDisplayIOServicePort), (and there's not replacement listed for that API), so that isn't really an option.

Basically, I am wanting to give the user a list of connected screens to display the output of the app, and I feel like giving them a list of names of the displays would be much more elegant and nicer than whatever the ID is that is returned from NSScreen or CGGetActiveDisplayList, etc. It has to possible, when you go to the display preferences in OS X it gives you the names of the displays there. Anyone have any ideas?

like image 436
bshock84 Avatar asked Dec 22 '25 19:12

bshock84


2 Answers

macOS 10.15 Catalina introduced a new property localizedName for getting the external display name:

NSScreen.screens.forEach {
    print($0.localizedName)
}
like image 65
Tehdrew Avatar answered Dec 24 '25 08:12

Tehdrew


You can get the names of connected screens directly from IOReg

func screenNames() -> [String] {

  var names = [String]()
  var object : io_object_t
  var serialPortIterator = io_iterator_t()
  let matching = IOServiceMatching("IODisplayConnect")

  let kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
                                                matching,
                                                &serialPortIterator)
  if KERN_SUCCESS == kernResult && serialPortIterator != 0 {
    repeat {
      object = IOIteratorNext(serialPortIterator)
      let info = IODisplayCreateInfoDictionary(object, UInt32(kIODisplayOnlyPreferredName)).takeRetainedValue() as NSDictionary as! [String:AnyObject]
      if let productName = info["DisplayProductName"] as? [String:String],
         let firstKey = Array(productName.keys).first {
            names.append(productName[firstKey]!)
      }

    } while object != 0
  }
  IOObjectRelease(serialPortIterator)
  return names
}

let names = screenNames()
like image 38
vadian Avatar answered Dec 24 '25 08:12

vadian