When I've tried to use UIDevice on my Mac running my Catalyst application, testing code
UIDevice *d=UIDevice.currentDevice;
for (NSString *k in @[@"name", @"systemName", @"systemVersion", @"model", @"localizedModel"])
NSLog(@"%@ -> %@", k, [d valueForKey:k]);
to my great surprise I am getting
name -> iPad
systemName -> iPadOS
systemVersion -> 26.3
model -> iPad
localizedModel -> iPad
What the. How do I determine the real values? Thanks!
HomeKit API available amongst the native macOS APIs
Hmmm, yeah, that certainly seems to be the case. How weird. I don’t support HomeKit, so I’m gonna ask DTS’s resident expert if they have any context for that.
Anyway, given that your app is focused on HomeKit, that definitely forces you to use Catalyst.
just wanted to save it for possible further interest
OK. Assuming that you’re only saving it locally. If you’re uploading it somewhere, comments like that definitely set off privacy alarm bells |-:
Anyway, with that context let’s look at each of these properties.
The name property returns the user-assigned device name. Honestly, I don’t think you should capture this because it’s privacy sensitive. In many cases it’s something like “Eric’s MacBook”.
In this respect, Mac Catalyst follows iOS, in that it returns a placeholder unless you apply for and are granted access by Apple. See the discussion here.
This restriction is not enforced for non-Catalyst code, so it’s possible to get this value without the managed capability on macOS. If you think that’s absolutely necessary, let me know and I can outline your options.
You don’t need the systemName property because there’s only one meaningful value for a Mac Catalyst, macOS.
The systemVersion you get back is pretty reasonable, given that:
- On macOS 26 and later, the versions are the same.
- On older systems you can map the Catalyst version to the macOS version in a straightforward fashion.
If you want more details, you can call uname:
var n = utsname()
let success = uname(&n) >= 0
guard success else { … handle error … }
let version = withUnsafePointer(to: n) { nPtr in
String(cString: nPtr.pointer(to: \.version.0)!)
}
print(version)
// -> Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:41 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6031
This returns macOS info on macOS, even when you’re in a Mac Catalyst app. It also returns a similar level of detail on iOS.
However, if you think it’s absolutely necessary to get the macOS version, let me know because you do have options.
The model property isn’t particularly useful in the context of the Mac. Rather, most folks track the low-level model value [1]. For example:
% sysctl hw.model
hw.model: Mac15,11
Or in code:
var modelBuf = [CChar](repeating: 0, count: 256)
var modelBufCount = modelBuf.count
let success = sysctlbyname("hw.model", &modelBuf, &modelBufCount, nil, 0) >= 0
guard success else { return }
modelBuf.removeLast(modelBuf.count - modelBufCount)
let model = String(cString: modelBuf)
print(model)
For the localizedModel property, ideally you’d record values like “MacBook Pro” or “Mac mini”. Getting such values on the Mac is tricky. I think it’d be better for you to limit yourself to the low-level model value, at least for the moment.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] This string dates back to Open Firmware on PowerPC-based Macs. There’s been two CPU architecture changes since then O-: