This seems to be a pretty weird issue. I'm following along with a SpriteKit tutorial, and while I can build my project and run it on my phone, I keep getting this error in the IDE: Cannot load underlying module for SpriteKit
It says it cannot load the module but that's weird because SpriteKit should be a native framework that must've been installed with my XCode.
It is pretty annoying because XCode is not context-aware, and code completion doesn't work for any object that's derived from SpriteKit.
Here's my system info: XCode version: Version 12.0 (12A7209)
MacOS version: MacOS Catalina 10.15.7 (19H2)
Is this a bug in XCode?
Post
Replies
Boosts
Views
Activity
In this page - https://developer.apple.com/documentation/avfoundation/avcapturedevice at the note at the bottom of the page it says:
Directly configuring a capture device’s activeFormat property changes the capture session’s preset to inputPriority. This is not true, I have to set the capture session's preset to input priority for the captured device's configuration to take place.
Take a look at the following snippet:
import SwiftUI
import AVFoundation
struct CustomCameraView: UIViewRepresentable {
func makeUIView(context: Context) -> some UIView {
let previewView = UIImageView()
func configureCameraForHighestFrameRate(device: AVCaptureDevice) {
var bestFormat: AVCaptureDevice.Format?
var bestFrameRateRange: AVFrameRateRange?
for format in device.formats {
for range in format.videoSupportedFrameRateRanges {
if range.maxFrameRate > bestFrameRateRange?.maxFrameRate ?? 0 {
bestFormat = format
bestFrameRateRange = range
}
}
}
if let bestFormat = bestFormat,
let bestFrameRateRange = bestFrameRateRange {
do {
try device.lockForConfiguration()
// Set the device's active format.
device.activeFormat = bestFormat
// Set the device's min/max frame duration.
let duration = bestFrameRateRange.minFrameDuration
device.activeVideoMinFrameDuration = duration
device.activeVideoMaxFrameDuration = duration
device.unlockForConfiguration()
} catch {
print("error getting max framerate")
// Handle error.
}
}
}
func setupLivePreview() {
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer.videoGravity = .resizeAspect
videoPreviewLayer.connection?.videoOrientation = .portrait
previewView.layer.addSublayer(videoPreviewLayer)
captureSession.commitConfiguration()
DispatchQueue.global(qos: .userInitiated).async {
captureSession.startRunning()
DispatchQueue.main.async {
videoPreviewLayer.frame = previewView.bounds
}
}
}
var captureSession: AVCaptureSession!
// var videoOutput: AVCaptureVideoDataOutput!
var videoPreviewLayer: AVCaptureVideoPreviewLayer!
captureSession = AVCaptureSession()
captureSession.beginConfiguration()
captureSession.sessionPreset = .inputPriority
guard let backCamera = AVCaptureDevice.default(for: AVMediaType.video) else {
print("Unable to access back camera!")
return UIImageView()
}
configureCameraForHighestFrameRate(device: backCamera)
do {
let input = try AVCaptureDeviceInput(device: backCamera)
// videoOutput = AVCaptureVideoDataOutput()
print("max frame duration on input", input.device.activeVideoMaxFrameDuration)
// if captureSession.canAddInput(input) && captureSession.canAddOutput(videoOutput) {
if captureSession.canAddInput(input) {
captureSession.addInput(input)
setupLivePreview()
}
}
catch let error {
print("Error Unable to initialize back camera: \(error.localizedDescription)")
}
return previewView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
If I don't manually set the captureSession.sessionPreset to .inputPriority, my captured FPS will be the default, and setting device.activeVideoMinFrameDuration and device.activeVideoMaxFrameDuration won't have any effects.
Looks like the documentation on this is wrong.