iOS code to identify metal support in runtime?

It's good that you're looking for something specific to Metal — generally, iOS version checks and hardware name checks are fragile, because they rely on your app knowing all of the OS versions and devices that could ever run it. If Apple were to go back and release an iOS 7.x version that added Metal support (okay, seems unlikely), or a device that supports Metal but isn't one of the hardware names you're looking at (seems much more likely), you'd be stuck having to track all of those things down and update your app to manage them.

Anyway, the best way to check whether the device you're running on is Metal enough for your awesome graphics code? Just try to get a MTLDevice object:

id<MTLDevice> device = MTLCreateSystemDefaultDevice();
if (device) {
    // ready to rock 🤘
} else {
    // back to OpenGL
}

Note that just testing for the presence of a Metal framework class doesn't help — those classes are there on any device running iOS 8 (all the way back to iPhone 4s & iPad 2), regardless of whether that device has a Metal-capable GPU.

In Simulator, Metal is supported as of iOS 13 / tvOS 13 when running on macOS 10.15. Use the same strategy: call MTLCreateSystemDefaultDevice(). If it returns an object then your simulator code is running in an environment where the simulator is hardware-accelerated. If it returns nil then you're running on an older simulator or in an environment where Metal is not available.


On iOS, you should just check MTLCreateSystemDefaultDevice(). If it returns a valid device, you’re good to go. On macOS, you need to be careful; use [MTLCopyAllDevices() count] to determine if you have any supported metal devices available.

You should avoid using MTLCreateSystemDefaultDevice() on macOS because that can force a mux switch to the discrete GPU (eg: if you're dealing with a laptop with automatic graphics switching between a discrete and integrated graphics).