Chapter 2: SceneKit editor is blank


I’m at the end of Section 1, Chapter 2, trying to change the position of the train. It says: “Select train.obj in the Project navigator; this will show you the train model in the SceneKit editor. Now, click on the train to select it.”

But when I select train.obj in the Project navigator, I end up with a blank scene in the SceneKit editor. Moreover, when I open the Scene Graph, I see no nodes: Just an empty pane.

Ideas? I’ve never tried to view an obj with Xcode, so maybe I’m missing something simple. The file itself does show a preview in the Finder, and it does have data when I view it in TextEdit.


Hi @yonibentov and welcome to the forums!

Annoyingly, it looks like the SceneKit editor no longer works with .obj files. As you say, it’s not showing up in the scene graph at all.

It shouldn’t affect you too much, as the book doesn’t use the SceneKit editor too much. But to move your train down, you’ll have to move it down in code.

In the Import Train playground, you have a shader with a multiline string. In that string, replace

return vertex_in.position;


float4 position = vertex_in.position;
position.y -= 1;
return position;

Don’t miss the semi-colons at the end of the lines.

vertex_main is a vertex function that operates on every vertex in the train model. This will change the y position of all the vertices of the train in code.

Glad to know it wasn’t just me! Thanks very much for the help. Loving the book so far.

1 Like

Another Xcode 12 problem that I’ll point out now, as you’ll get to it soon. In a later chapter when you use a playground to create the library, that’s changed too. Instead of having to get the bundle name for the shaders, you simply do library = device.makeDefaultLibrary()!

If you get stuck and want an immediate answer while I’m not available, have a look in this forum at existing posts, as lots of people have travelled this path already :slight_smile: .

Thanks for the warning! Yup, I did just run into that, but I’m still stuck. I found this post (Chapter 4 playgrounds not compiling Xcode 12.0.1), but now I get a different error:

Fatal error: ‘try!’ expression unexpectedly raised an error: Error Domain=CompilerError Code=1 “Function fragment_main is using language version 2.3 which is incompatible with this OS.” UserInfo={NSLocalizedDescription=Function fragment_main is using language version 2.3 which is incompatible with this OS.}: file N3DTransforms_Sources/Utility.swift, line 26

Searching for things like “language version” for Metal didn’t seem to give me any results on the forum, so I apologize in advance if I missed a different post on this topic.

1 Like

Ugh. Yes. Playgrounds in Xcode 12 I think from 12.2 (?) use Metal Shading Language v 2.3, which is only available on Big Sur.

If you’re not on Big Sur, I think the only way around it is to create a project not a playground :unamused:

I’m downloading Xcode 11 from Sign In - Apple to see if it works in that.

Testing chapter 4 transforms playground, looks like Xcode 11 will still work on Catalina. Setting up the library is as per the book though:

// Xcode 12
library = device.makeDefaultLibrary()!
// Xcode 11
let path = Bundle.main.path(forResource: "Shaders", ofType: "metal")
let source = try String(contentsOfFile: path!, encoding: .utf8)
library = try device.makeLibrary(source: source, options: nil)

I got it working by revisiting the Pipeline project, adding Utility.swift to it, and changing the Renderer.swift code according to the instructions in Ch. 4.

Since I’m just starting out (that’s what the book is for, right?), and in case someone else stumbles on this thread, I wanted to point out that the new code goes into the extension to the Renderer class, not into the Renderer class itself. And because of that, instead of things like “blah = device.makeBuffer…” we’ll need to say “blah = Renderer.device.makeBuffer…”––Xcode told me that, so I’m sure someone else reading this would’ve figured it out. But still.

Anyway, thanks so much for all the help! I think new questions will merit a new thread. :slight_smile:

1 Like

Well done, and thank you for persisting with it. I might move on from playgrounds in the next version. It’s nice to see the triangles happening immediately, but they seem rather fragile.

Literally this, then you’re golden!

public func createLibrary() -> MTLLibrary {  
    return device.makeDefaultLibrary()!
1 Like

As a variant I’d propose rename file Shaders.metal to Shaders.txt. You can have correct syntax highlighting by setup correct file type in the file inspector at the right-hand side.

Actually problem appears because Xcode compiles metal file to default.metallib. You can load this compiled file using default library. But sometimes Xcode has other version of compiler (f.e. Xcode beta working on Release macos) and as a result you will get errors. If you change the extension of file Shaders Xcode will just copy this file to resources as is. And application will compile it in runtime without any problems.

Something like that:

public func createLibrary() -> MTLLibrary {
    guard let url = Bundle.main.url(forResource: "Shaders", withExtension: "txt") else {
        fatalError("Cannot find shaders file")
    guard let source = try? String(contentsOf: url) else {
        fatalError("Cannot read shaders file")
    guard let library = try? device.makeLibrary(source: source, options: nil) else {
        fatalError("Cannot make library")
    return library

Interesting. Thank you.