Did RealityView syntax change?

All of a sudden (like when XCode 15.2 left beta yesterday?) I can't build attachments into my RealityView:

var body: some View {
        RealityView { content, attachments in
            // stuff
        } attachments: {
            // stuff
        }

Produces "No exact matches in call to initializer" on the declaration line (RealityView { content, attachments in).

So far as I can tell, this is identical to the sample code provided at the WWDC session, but I've been fussing with various syntaxes for an hour now and I can't figure out what the heck it wants.

Replies

And in fact, the code copied straight from the WWDC section no longer builds, either:

import SwiftUI
import RealityKit

struct MoonOrbit: View {
    var body: some View {
        RealityView { content, attachments in
            guard let earth = try? await Entity(named: "Earth") else {
                return
            }
            content.add(earth)

            if let earthAttachment = attachments.entity(for: "earth_label") {
                earthAttachment.position = [0, -0.15, 0]
                earth.addChild(earthAttachment)
            }
        } attachments: {
            Text("Earth").tag("earth_label")
        }
    }
}

This produces "'init(make:update:attachments:)' is unavailable in visionOS" on the RealityView declaration line.

Hello,

Yes, the syntax did change slightly! Here is the updated version of that snippet:

struct MoonOrbit: View {
    var body: some View {
        RealityView { content, attachments in
            guard let earth = try? await Entity(named: "Earth") else {
                return
            }
            content.add(earth)

            if let earthAttachment = attachments.entity(for: "earth_label") {
                earthAttachment.position = [0, -0.15, 0]
                earth.addChild(earthAttachment)
            }
        } attachments: {
            Attachment(id: "earth_label") {
                Text("Earth")
            }
        }
    }
}

Also, as a general tip for debugging steps when you see a compilation error messages along the lines of:

"No exact matches in call to initializer"

When you see a compilation error like this, you can use Xcode's "Jump to Definition" feature to jump to the type/property/function definition in the header or swift interface file, in this case, you would jump to RealityView's definition. Once you are there, you can look at all of the init signatures for RealityView to see what the expected types of the each init's parameters.

In this case, the init signature that you would see is:

public init<A>(make: @escaping @MainActor @Sendable (inout RealityViewContent, RealityViewAttachments) async -> Void, update: (@MainActor (inout RealityViewContent, RealityViewAttachments) -> Void)? = nil, @AttachmentContentBuilder attachments: @escaping () -> A) where Content == RealityViewAttachmentBuilderContent<A, RealityViewContent.Body<RealityViewDefaultPlaceholder>>, A : AttachmentContent

This signature gives you the clue that you to return A in the attachments closure, where A conforms to the AttachmentContent protocol. A trip to the docs page for AttachmentContent shows us that Attachment conforms to AttachmentContent, and that's the piece of info we needed to figure out what to do and get this to compile!

Note that it is not expected that you follow the trail of breadcrumbs I described above to figure this out on your own, this is a totally valid question to bring to the forums, but I think it is generally useful to the community to know that it is possible to figure this out by following that trail :)

And for more information about Swift interface files, see TN3108: Viewing the interface of your Swift code.