SceneKit with WidgetKit Implementation

I have been trying to implement a sphere I have created from SceneKit into a widget I have made with WidgetKit. However, upon running, I receive a fatal error in the timeline stating

PlatformViewRepresentableAdaptor<UIKitSceneView>

Below is the relevant code to the SceneKit and WidgetKit along with the import statements

Please keep in mind that even when using an empty scene rather than one with all of the details below, I received the same error.

Code Block swift
import WidgetKit
import SwiftUI
import Intents
import SceneKit
import UIKit
extension SCNMaterial {
    convenience init(color: UIColor) {
        self.init()
        diffuse.contents = color
    }
    convenience init(image: UIImage) {
        self.init()
        diffuse.contents = image
    }
}
func addBloom() -> [CIFilter]? {
    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(0.2, forKey: "inputIntensity")
    bloomFilter.setValue(35, forKey: "inputRadius")
    return [bloomFilter]
}
func sceneSetup() -> SCNScene{
    let scene = SCNScene()
    let sphere = SCNSphere(radius: 1)
    sphere.segmentCount = 100
    let mat = SCNMaterial(image: UIImage(named: "desaturated.png")!)
    sphere.materials = [mat]
    sphere.firstMaterial?.diffuse.wrapS = SCNWrapMode.clamp
    sphere.firstMaterial?.diffuse.wrapT = SCNWrapMode.clamp
    let sphereNode = SCNNode(geometry: sphere)
    sphereNode.filters = addBloom()
    scene.rootNode.addChildNode(sphereNode)
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = SCNLight.LightType.ambient
    ambientLightNode.light!.color = UIColor(white: 0.8, alpha: 1.0)
    scene.rootNode.addChildNode(ambientLightNode)
    let omniLightNode = SCNNode()
    omniLightNode.light = SCNLight()
    omniLightNode.light!.type = SCNLight.LightType.omni
    omniLightNode.light!.color = UIColor(white: 0.99, alpha: 1.0)
    omniLightNode.position = SCNVector3Make(0, 0, 50)
    scene.rootNode.addChildNode(omniLightNode)
    sphereNode.rotation = SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 0.0)
    sphereNode.runAction(SCNAction.rotate(by: 0.9*CGFloat(Double.pi), around: SCNVector3(x: 0.0, y: 1.0, z: 0.0), duration: 0.0))
    return scene
}
struct ClassClockWidgetEntryView : View {
    var entry: Provider.Entry
    var scene = SCNScene()
    @Environment(\.colorScheme) var colorScheme
    var body: some View {
            ZStack() {
                SceneView(scene: sceneSetup())
            }
        .padding(.all, 25)
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
        .background(LinearGradient(gradient: colorScheme == .dark ? Gradient(colors: [Color( colorLiteral(red: 0.2549019754, green: 0.2745098174, blue: 0.3019607961, alpha: 1)), Color( colorLiteral(red: 0.121719892, green: 0.131788787, blue: 0.1464163903, alpha: 1))]) : Gradient(colors: [Color( colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), Color( colorLiteral(red: 0.9109456692, green: 0.9109456692, blue: 0.9109456692, alpha: 1))]), startPoint: .topTrailing, endPoint: .bottomLeading))
        .edgesIgnoringSafeArea(.all)
    }
}

Accepted Reply

After speaking with an engineer at Apple, he explained that the error is a result of the WidgetKit needing to be written in pure SwiftUI and that SceneKit is not supported. The solution he recommended is to create a separate function that creates a snapshot of the scene and to implement it as an image in the widget.

Replies

I would like to add that I am using the new SceneView() function in the body as mentioned and released this week at WWDC referenced in this post
After speaking with an engineer at Apple, he explained that the error is a result of the WidgetKit needing to be written in pure SwiftUI and that SceneKit is not supported. The solution he recommended is to create a separate function that creates a snapshot of the scene and to implement it as an image in the widget.
For anyone who is wondering how to convert a SpriteKit into an image, this is the code to do it:

Code Block swift
let skView = SKView(frame: CGRect(
x: 0, y: 0,
width: 100,
height: 100
))
skView.presentScene(skScene)
let renderedImg = UIImage(cgImage:
(skView.texture(from: skScene)?.cgImage())!
)