Metal Camera Tutorial Bonus: Running Metal project in iOS Simulator
In the Metal Camera Tutorial series we have created a simple app that renders camera frames on screen in real time. However, this app uses Metal
framework, which is not available in iOS Simulator. Basically, your app won’t even build if you select simulator as a build device, which is a shame in case you want to add unit tests for example, being able to run them without actual device connected to your machine.
Some parts of Metal
have stub implementations for desktop processor architectures, which means you can at least build the app (only to find out it’s not working as expected on the simulator). Other parts, like MetalKit
don’t even exist for Simulator, so you will have to wrap the imports into conditional compilation blocks, like that:
import UIKit
import Metal
#if arch(i386) || arch(x86_64)
#else
import MetalKit
#endif
We check if current processor architecture is a desktop one, and in this case simply don’t import any ARM-only frameworks. Beware that the classes from MetalKit
are not available either, so you will need to wrap any code using them too:
public class MTKViewController: UIViewController {
#if arch(i386) || arch(x86_64)
#else
/// `UIViewController`'s view
private var metalView: MTKView!
#endif
// MARK: - Public overrides
override public func loadView() {
super.loadView()
#if arch(i386) || arch(x86_64)
NSLog("Failed creating a default system Metal device, since Metal is not available in iOS Simulator.")
#else
assert(device != nil, "Failed creating a default system Metal device. Please, make sure Metal is available on your hardware.")
#endif
initializeMetalView()
initializeRenderPipelineState()
}
// MARK: - Private Metal-related properties and methods
/**
initializes and configures the `MTKView` we use as `UIViewController`'s view.
*/
private func initializeMetalView() {
#if arch(i386) || arch(x86_64)
#else
metalView = MTKView(frame: view.bounds, device: device)
metalView.delegate = self
metalView.framebufferOnly = true
metalView.colorPixelFormat = .BGRA8Unorm
metalView.contentScaleFactor = UIScreen.mainScreen().scale
metalView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
view.insertSubview(metalView, atIndex: 0)
#endif
}
}
With those compilation time checks you clearly won’t get your app running normally in iOS Simulator. However, it will let you build it, and, for example, cover the code not requring Metal
with unit tests. You could add a stubbed camera session to verify camera permissions and delegates, for instance — well, you get the idea.
Where do I go from here?
This was the bonus part of Metal Camera Tutorial series, where we explore ways of achieving lowest-overhead access to hardware to grab camera frames, convert them to textures and render on screen in real time:
- Part 1: Getting raw camera data
- Part 2: Converting sample buffer to a Metal texture
- Part 3: Rendering a Metal texture
- Bonus: Running Metal project in iOS Simulator
You can check out the final project from this Metal Camera Tutorial on GitHub.
Leave a Comment