react-native-vision-camera: 🐛 iOS 17.0.2 (iPhone 15) crashing on camera load

What’s happening?

While loading camera seems like AVCaptureColorSpace throws the following error

Fatal error: AVCaptureDevice.Position has unknown state.
  • Could it be new formats in new iPhone or is this a bug?
  • Is removing this error a good workaround for the time being?
  • Could

Reproduceable Code

const device = cameraDevices.back;
const format = useMemo(() => {
    if (!device?.formats) return undefined;
    const sortedFormats = device.formats.sort(sortFormats);
    const formatsWith60FPS = sortedFormats.filter((f) =>
        f.frameRateRanges.some((r) => frameRateIncluded(r, 60))
    );
    if (formatsWith60FPS.length > 0) return formatsWith60FPS[1];
    if (sortedFormats.length > 0) return sortedFormats[0];
    return undefined;
}, [device?.formats]);
const fps = useMemo(() => {
    if (!format) return undefined;
    return Math.max(
        ...format.frameRateRanges.map((range) => range.maxFrameRate)
    );
}, [format]);
<ReanimatedCamera
    photo={true}
    video={false}
    device={device}
    enableHighQualityPhotos={true}
    enableZoomGesture={false}
    orientation="portrait"
    isActive={focused}
    style={{
        position: 'absolute',
        height: '100%',
        width: '100%',
        padding: 0,
        margin: 0,
    }}
    ref={camera}
    torch={torch}
    format={Platform.OS === 'android' ? undefined : format}
    preset={!format || Platform.OS === 'android' ? 'photo' : undefined}
    fps={Platform.OS === 'android' ? undefined : fps}
    hdr={Platform.OS === 'android' ? undefined : false}
    animatedProps={cameraAnimatedProps}
    onInitialized={() => setCameraReady(true)}
    onError={(err) => {
        console.error(err);
    }}
/>;

Relevant log output

VisionCamera/AVCaptureColorSpace+descriptor.swift:41: Fatal error: AVCaptureDevice.Position has unknown state.

Camera Device

Unknown as I have don't have the new iPhone and this is a crash report

Device

ex. iPhone 15

VisionCamera Version

2.15.6

Can you reproduce this issue in the VisionCamera Example app?

I didn’t try (⚠️ your issue might get ignored & closed if you don’t try this)

Additional information

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Reactions: 20
  • Comments: 43 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Fixed in latest v2

Just released this in 2.16.2., hopefully with a better and more stable solution. Also the crash in colorSpace is fixed.

If you appreciate my free support for VisionCamera, please consider sponsoring me on GitHub. Thanks. ❤️

This patch temporarily resolves the issue by removing colorSpaces from AVCaptureDevice.Format.

Oh right, apparently this field is removed in v3 as well so upgrading might resolve this as well if that’s an option until the new value is figured out.

diff --git a/node_modules/react-native-vision-camera/ios/CameraView+AVCaptureSession.swift b/node_modules/react-native-vision-camera/ios/CameraView+AVCaptureSession.swift
index 5c9b77d..5ea7ad5 100644
--- a/node_modules/react-native-vision-camera/ios/CameraView+AVCaptureSession.swift
+++ b/node_modules/react-native-vision-camera/ios/CameraView+AVCaptureSession.swift
@@ -195,14 +195,14 @@ extension CameraView {
           device.automaticallyEnablesLowLightBoostWhenAvailable = lowLightBoost!.boolValue
         }
       }
-      if let colorSpace = colorSpace as String? {
-        guard let avColorSpace = try? AVCaptureColorSpace(string: colorSpace),
-              device.activeFormat.supportedColorSpaces.contains(avColorSpace) else {
-          invokeOnError(.format(.invalidColorSpace(colorSpace: colorSpace)))
-          return
-        }
-        device.activeColorSpace = avColorSpace
-      }
+      // if let colorSpace = colorSpace as String? {
+      //   guard let avColorSpace = try? AVCaptureColorSpace(string: colorSpace),
+      //         device.activeFormat.supportedColorSpaces.contains(avColorSpace) else {
+      //     invokeOnError(.format(.invalidColorSpace(colorSpace: colorSpace)))
+      //     return
+      //   }
+      //   device.activeColorSpace = avColorSpace
+      // }
 
       device.unlockForConfiguration()
       ReactLogger.log(level: .info, message: "Device successfully configured!")
diff --git a/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+matchesFilter.swift b/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+matchesFilter.swift
index 35789a6..bff8572 100644
--- a/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+matchesFilter.swift
+++ b/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+matchesFilter.swift
@@ -54,13 +54,13 @@ extension AVCaptureDevice.Format {
         return false
       }
     }
-    if let colorSpaces = filter.value(forKey: "colorSpaces") as? [String] {
-      let avColorSpaces = colorSpaces.map { try? AVCaptureColorSpace(string: $0) }
-      let allColorSpacesIncluded = supportedColorSpaces.allSatisfy { avColorSpaces.contains($0) }
-      if !allColorSpacesIncluded {
-        return false
-      }
-    }
+    // if let colorSpaces = filter.value(forKey: "colorSpaces") as? [String] {
+    //   let avColorSpaces = colorSpaces.map { try? AVCaptureColorSpace(string: $0) }
+    //   let allColorSpacesIncluded = supportedColorSpaces.allSatisfy { avColorSpaces.contains($0) }
+    //   if !allColorSpacesIncluded {
+    //     return false
+    //   }
+    // }
     if let frameRateRanges = filter.value(forKey: "frameRateRanges") as? [NSDictionary] {
       let allFrameRateRangesIncluded = videoSupportedFrameRateRanges.allSatisfy { range -> Bool in
         frameRateRanges.contains { dict -> Bool in
diff --git a/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+toDictionary.swift b/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+toDictionary.swift
index fec83ca..f7bce0e 100644
--- a/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+toDictionary.swift
+++ b/node_modules/react-native-vision-camera/ios/Extensions/AVCaptureDevice.Format+toDictionary.swift
@@ -33,7 +33,7 @@ extension AVCaptureDevice.Format {
       "minISO": minISO,
       "fieldOfView": videoFieldOfView,
       "maxZoom": videoMaxZoomFactor,
-      "colorSpaces": supportedColorSpaces.map(\.descriptor),
+      // "colorSpaces": supportedColorSpaces.map(\.descriptor),
       "supportsVideoHDR": isVideoHDRSupported,
       "supportsPhotoHDR": false,
       "frameRateRanges": videoSupportedFrameRateRanges.map {
diff --git a/node_modules/react-native-vision-camera/ios/Parsers/AVCaptureColorSpace+descriptor.swift b/node_modules/react-native-vision-camera/ios/Parsers/AVCaptureColorSpace+descriptor.swift
index 13a403b..e1781ab 100644
--- a/node_modules/react-native-vision-camera/ios/Parsers/AVCaptureColorSpace+descriptor.swift
+++ b/node_modules/react-native-vision-camera/ios/Parsers/AVCaptureColorSpace+descriptor.swift
@@ -1,3 +1,5 @@
+// Removed support for colorSpace and this field is removed in vision-camera v3 and once stablized we'll migrate
+
 //
 //  AVCaptureColorSpace+descriptor.swift
 //  mrousavy
@@ -6,39 +8,39 @@
 //  Copyright © 2020 mrousavy. All rights reserved.
 //
 
-import AVFoundation
+// import AVFoundation
 
-extension AVCaptureColorSpace {
-  init(string: String) throws {
-    switch string {
-    case "hlg-bt2020":
-      if #available(iOS 14.1, *) {
-        self = .HLG_BT2020
-      } else {
-        throw EnumParserError.unsupportedOS(supportedOnOS: "14.1")
-      }
-      return
-    case "p3-d65":
-      self = .P3_D65
-      return
-    case "srgb":
-      self = .sRGB
-      return
-    default:
-      throw EnumParserError.invalidValue
-    }
-  }
+// extension AVCaptureColorSpace {
+//   init(string: String) throws {
+//     switch string {
+//     case "hlg-bt2020":
+//       if #available(iOS 14.1, *) {
+//         self = .HLG_BT2020
+//       } else {
+//         throw EnumParserError.unsupportedOS(supportedOnOS: "14.1")
+//       }
+//       return
+//     case "p3-d65":
+//       self = .P3_D65
+//       return
+//     case "srgb":
+//       self = .sRGB
+//       return
+//     default:
+//       throw EnumParserError.invalidValue
+//     }
+//   }
 
-  var descriptor: String {
-    switch self {
-    case .HLG_BT2020:
-      return "hlg-bt2020"
-    case .P3_D65:
-      return "p3-d65"
-    case .sRGB:
-      return "srgb"
-    default:
-      fatalError("AVCaptureDevice.Position has unknown state.")
-    }
-  }
-}
+//   var descriptor: String {
+//     switch self {
+//     case .HLG_BT2020:
+//       return "hlg-bt2020"
+//     case .P3_D65:
+//       return "p3-d65"
+//     case .sRGB:
+//       return "srgb"
+//     default:
+//       fatalError("AVCaptureDevice.Position has unknown state.")
+//     }
+//   }
+// }

Upgrade to V3.

Looks like this is the new enum value they’ve added: https://developer.apple.com/documentation/avfoundation/avcapturecolorspace/applelog

I suppose adding support for this requires building the app with xcode 15 / ios 17 SDK.

@mrousavy is it fixed on 2.16.1? Or should we wait for a new V2 release?

I think it’ll be released in 2.16.2, but not yet now https://github.com/mrousavy/react-native-vision-camera/commits/v2

Just released this in 2.16.2., hopefully with a better and more stable solution. Also the crash in colorSpace is fixed.

If you appreciate my free support for VisionCamera, please consider sponsoring me on GitHub. Thanks. ❤️

Xcode 15, camera screen crashes with Property '__scanCodes' doesn't exist. The previous build (2.15.5) works fine but doesn’t work with code 15.

react-native-vision-camera version 2.16.2 react-native-reanimated version 3.5.4

Just released this in 2.16.2., hopefully with a better and more stable solution. Also the crash in colorSpace is fixed.

If you appreciate my free support for VisionCamera, please consider sponsoring me on GitHub. Thanks. ❤️

Hi @mrousavy

I am still using V2 2.15.6 because by the time I implemented it 2.16.1 didn’t have support for frameProcessors.

I am getting the app crashing for iOS 17+. Does 2.16.2 has support for frameProcessors? Or what would you suggest in this case?

We are having the same issue. We are still using react-native-camera and not react-native-vision-camera. I am guessing if we upgrade to the latest react-native-vision-camera that will solve this. We are going to give that a try in the am. Has anyone else had the issue of the camera going black on an older phone, but on iOS17?

Could a fix for this be as simple as adding

    case "appleLog":
        if #available(iOS 17, *) {
          self = .appleLog
        } else {
          throw EnumParserError.unsupportedOS(supportedOnOS: "17")
        }
        return

to the init function and

    case .appleLog:
       return "appleLog"

to descriptor swith statement of AVCaptureColorSpace? Or what are the side effects of commenting the code as in @thyxus patch?

Found a co worker with the new iphone 15 pro and can confirm that patching 2.15.4 with this code is working! 🎉

my bad lol, the error message is wrong here.

Will fix this in V3 to make the enum casting safer!

Could a fix for this be as simple as adding

    case "appleLog":
        if #available(iOS 17, *) {
          self = .appleLog
        } else {
          throw EnumParserError.unsupportedOS(supportedOnOS: "17")
        }
        return

to the init function and

    case .appleLog:
       return "appleLog"

to descriptor swith statement of AVCaptureColorSpace? Or what are the side effects of commenting the code as in @thyxus patch?

Found a co worker with the new iphone 15 pro and can confirm that patching 2.15.4 with this code is working! 🎉

I can confirm that it works. But the build only works with xcode 15. Unfortunately our CI/CD process is using xcode 14 so I end up applying the patch

I did use patch-package and followed your steps. @GSFZamai image

It seems that you are applying at the wrong file. Correct file is node_modules/react-native-vision-camera/ios/Parsers/AVCaptureColorSpace+descriptor.swift Seems like you are applying at node_modules/react-native-vision-camera/ios/Parsers/AVCaptureDevice+descriptor.swift

I applied this commit as a patch and it worked.

RNVC 2.15.6. But soon I’ll update to RNVC v3

Mukthayar1(https://github.com/mrousavy/react-native-vision-camera/issues/1840#issuecomment-1752964704)

In the released version 2.16.2, I am encountering the issue “__scanCodes not found,” while it was working fine in the previous build.

@mrousavy, I am experiencing the same problem!

my bad lol, the error message is wrong here.

Will fix this in V3 to make the enum casting safer!

Will there be a release of V2 that fixes this?

This patch temporarily resolves the issue by removing colorSpaces from AVCaptureDevice.Format.

Oh right, apparently this field is removed in v3 as well so upgrading might resolve this as well if that’s an option until the new value is figured out. …

This patch seems to be working for me on iPhone 15 Pro 👍🏻 We do not use anything regarding colorSpaces in our app.

Would be great if someone with access to on iPhone 15 Pro or 15 Pro Max were able to add logging to see what the actual unknown state is, since there is no new reference in the iOS documentation for what the new state value is.