Photos & Camera

RSS for tag

Explore technical aspects of capturing high-quality photos and videos, including exposure control, focus modes, and RAW capture options.

Posts under Photos & Camera subtopic

Post

Replies

Boosts

Views

Activity

Recording Constant Frame Rate at 4K 60 fps mode
Hi, We have created an app which allows recording 4K 60 fps videos in the app. We have noted that some time the recording switched to 20 fps (the value 20 is constant) even though the resolution settings is at 4K 60fps. We are using AVCaptureDevice to invoke the camera. has anyone experienced this problem before ? What is unique to 20 fps? Why does it resort to 20 fps from 60 fps and why not to other numbers ?
1
0
289
Oct ’25
LockedCameraCapture Does Not Launch The App from Lock Screen
My implementation of LockedCameraCapture does not launch my app when tapped from locked screen. But when the same widget is in the Control Center, it launches the app successfully. Standard Xcode target template: Lock_Screen_Capture.swift @main struct Lock_Screen_Capture: LockedCameraCaptureExtension { var body: some LockedCameraCaptureExtensionScene { LockedCameraCaptureUIScene { session in Lock_Screen_CaptureViewFinder(session: session) } } } Lock_Screen_CaptureViewFinder.swift: import SwiftUI import UIKit import UniformTypeIdentifiers import LockedCameraCapture struct Lock_Screen_CaptureViewFinder: UIViewControllerRepresentable { let session: LockedCameraCaptureSession var sourceType: UIImagePickerController.SourceType = .camera init(session: LockedCameraCaptureSession) { self.session = session } func makeUIViewController(context: Self.Context) -> UIImagePickerController { let imagePicker = UIImagePickerController() imagePicker.sourceType = sourceType imagePicker.mediaTypes = [UTType.image.identifier, UTType.movie.identifier] imagePicker.cameraDevice = .rear return imagePicker } func updateUIViewController(_ uiViewController: UIImagePickerController, context: Self.Context) { } } Then I have my widget: struct CameraWidgetControl: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration( kind: "com.myCompany.myAppName.lock-screen") { ControlWidgetButton(action: MyAppCaptureIntent()) { Label("Capture", systemImage: "camera.shutter.button.fill") } } } } My AppIntent: struct MyAppContext: Codable {} struct MyAppCaptureIntent: CameraCaptureIntent { typealias AppContext = MyAppContext static let title: LocalizedStringResource = "MyAppCaptureIntent" static let description = IntentDescription("Capture photos and videos with MyApp.") @MainActor func perform() async throws -> some IntentResult { .result() } } The Issue LockedCameraCapture Widget does not launch my app when tapped from locked screen. You get the Face ID prompt and takes you to just Home Screen. But when the same widget is in the Control Center, it launches the app successfully. Error Message When tapped on Lock Screen, I get the following error code: LaunchServices: store ‹private > or url ‹private > was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo=&NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Attempt to map database failed: permission was denied. This attempt will not be retried. Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo=&NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Things I tried Widget image displays correctly App ID and the Provisioning Profile seem to be fine since they work fine when the same code injected in to AVCam sample app and when used the same App ID's. AppIntent file contains the target memberships of the Lock Screen capture and Widget Apple compiles without errors or warnings.
1
0
256
Oct ’25
How-to highlight people in a Vision Pro app using Compositor Services
Fundamentally, my questions are: is there a known transform I can apply onto a given (pixel) position (passed into a Metal Fragment Function) to correctly sample a texture provided by the main cameras + processed by a Vision request. If so, what is it? If not, how can I accurately sample my masks? My goal is to highlight people in a Vision Pro app using Compositor Services. To start, I asynchronously receive camera frames for the main left and right cameras. This is the breakdown of the specific CameraVideoFormat I pass along to the CameraFrameProvider: minFrameDuration: 0.03 maxFrameDuration: 0.033333335 frameSize: (1920.0, 1080.0) pixelFormat: 875704422 cameraType: main cameraPositions: [left, right] cameraRectification: mono From each camera frame sample, I extract the left and right buffers (CVReadOnlyPixelBuffer.withUnsafebuffer ==> CVPixelBuffer). I asynchronously process the extracted buffers by performing a VNGeneratePersonSegmentationRequest on both of them: // NOTE: This block of code and all following code blocks contain simplified representations of my code for clarity's sake. var request = VNGeneratePersonSegmentationRequest() request.qualityLevel = .balanced request.outputPixelFormat = kCVPixelFormatType_OneComponent8 ... let lHandler = VNSequenceRequestHandler() let rHandler = VNSequenceRequestHandler() ... func processBuffers() async { try lHandler.perform([request], on: lBuffer) guard let lMask = request.results?.first?.pixelBuffer else {...} try rHandler.perform([request], on: rBuffer) guard let rMask = request.results?.first?.pixelBuffer else {...} appModel.latestPersonMasks = (lMask, rMask) } I store the two resulting CVPixelBuffers in my appModel. For both of these buffers aka grayscale masks: width (in pixels) = 512 height (in pixels) = 384 byters per row = 512 plane count = 0 pixel format type = 1278226488 I am using Compositor Services to render my content in Immersive Space. My implementation of Compositor Services is based off of the same code from Interacting with virtual content blended with passthrough. Within the Shaders.metal, the tint's Fragment Shader is now passed the grayscale masks (converted from CVPixelBuffer to MTLTexture via CVMetalTextureCacheCreateTextureFromImage() at the beginning of the main render pipeline). fragment float4 tintFragmentShader( TintInOut in [[stage_in]], ushort amp_id [[amplification_id]], texture2d<uint> leftMask [[texture(0)]], texture2d<uint> rightMask [[texture(1)]] ) { if (in.color.a <= 0.0) { discard_fragment(); } float2 uv; if (amp_id == 0) { // LEFT uv = ??????????????????????; } else { // RIGHT uv = ??????????????????????; } constexpr sampler linearSampler (mip_filter::linear, mag_filter::linear, min_filter::linear); // Sample the PersonSegmentation grayscale mask float maskValue = 0.0; if (amp_id == 0) { // LEFT if (leftMask.get_width() > 0) { maskValue = rightMask.sample(linearSampler, uv).r; } } else { // RIGHT if (rightMask.get_width() > 0) { maskValue = rightMask.sample(linearSampler, uv).r; } } if (maskValue > 250) { return (1.0, 1.0, 1.0, 0.5) } return in.color; } I need to correctly sample the masks for a given fragment. The LayerRenderer.Layout is set to .layered. From Developer Documentation. A layout that specifies each view’s content as a slice of a single texture. Using the Metal debugger, I know that the final render target texture for each view / eye is 1888 x 1792 pixels, giving an aspect ratio of 59:56. The initial CVPixelBuffer provided by the main left and right cameras is 1920x1080 (16:9). The grayscale CVPixelBuffer returned by the VNPersonSegmentationRequest is 512x384 (4:3). All of these aspect ratios are different. My questions come down to: is there a known transform I can apply onto a given (pixel) position to correctly sample a texture provided by the main cameras + processed by a Vision request. If so, what is it? If not, how can I accurately sample my masks? Within the tint's Vertex Shader, after applying the modelViewProjectionMatrix, I have tried every version I have been able to find that takes the pixel space position (= vertices[vertexID].position.xy) and the viewport size (1888x1792) to compute the correct clip space position (maybe = pixel space position.xy / (viewport size * 0.5)???) of the grayscale masks but nothing has worked. The "highlight" of the person segmentations is off: scaled a little too big, offset little to far up and off to the side.
1
0
452
Nov ’25
Error when capturing a high-resolution frame with depth data enabled in ARKit
Problem Description (1) I am using ARKit in an iOS app to provide AR capabilities. Specifically, I'm trying to use the ARSession's captureHighResolutionFrame(using:) method to capture a high-resolution frame along with its corresponding depth data: open func captureHighResolutionFrame(using photoSettings: AVCapturePhotoSettings?) async throws -> ARFrame (2) However, when I attempt to do so, the call fails at runtime with the following error, which I captured from the Xcode debugger: [AVCapturePhotoOutput capturePhotoWithSettings:delegate:] settings.depthDataDeliveryEnabled must be NO if self.isDepthDataDeliveryEnabled is NO Code Snippet Explanation (1) ARConfig and ARSession Initialization The following code configures the ARConfiguration and ARSession. A key part of this setup is setting the videoFormat to the one recommended for high-resolution frame capturing, as suggested by the documentation. func start(imagesDirectory: URL, configuration: Configuration = Configuration()) { // ... basic setup ... let arConfig = ARWorldTrackingConfiguration() arConfig.planeDetection = [.horizontal, .vertical] // Enable various frame semantics for depth and segmentation if ARWorldTrackingConfiguration.supportsFrameSemantics(.smoothedSceneDepth) { arConfig.frameSemantics.insert(.smoothedSceneDepth) } if ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneDepth) { arConfig.frameSemantics.insert(.sceneDepth) } if ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth) { arConfig.frameSemantics.insert(.personSegmentationWithDepth) } // Set the recommended video format for high-resolution captures if let videoFormat = ARWorldTrackingConfiguration.recommendedVideoFormatForHighResolutionFrameCapturing { arConfig.videoFormat = videoFormat print("Enabled: High-Resolution Frame Capturing by selecting recommended video format.") } arSession.run(arConfig, options: [.resetTracking, .removeExistingAnchors]) // ... } (2) Capturing the High-Resolution Frame The code below is intended to manually trigger the capture of a high-resolution frame. The goal is to obtain both a high-resolution color image and its associated high-resolution depth data. To achieve this, I explicitly set the isDepthDataDeliveryEnabled property of the AVCapturePhotoSettings object to true. func requestImageCapture() async { // ... guard statements ... print("Manual image capture requested.") if #available(iOS 16.0, *) { // Assuming 16.0+ for this API if let defaultSettings = arSession.configuration?.videoFormat.defaultPhotoSettings { // Create a mutable copy from the default settings, as recommended let photoSettings = AVCapturePhotoSettings(from: defaultSettings) // Explicitly enable depth data delivery for this capture request photoSettings.isDepthDataDeliveryEnabled = true do { let highResFrame = try await arSession.captureHighResolutionFrame(using: photoSettings) print("Successfully captured a high-resolution frame.") if let initialDepthData = highResFrame.capturedDepthData { // Process depth data... } else { print("High-resolution frame was captured, but it contains no depth data.") } } catch { // The exception is caught here print("Error capturing high-resolution frame: \(error.localizedDescription)") } } } // ... } Issue Confirmation & Question (1) Through debugging, I have confirmed the following behavior: If I call captureHighResolutionFrame without providing the photoSettings parameter, or if photoSettings.isDepthDataDeliveryEnabled is set to false, the method successfully returns a high-resolution ARFrame, but its capturedDepthData is nil. (2) The error message clearly indicates that settings.depthDataDeliveryEnabled can only be true if the underlying AVCapturePhotoOutput instance's own isDepthDataDeliveryEnabled property is also true. (3) However, within the context of ARKit and ARSession, I cannot find any public API that would allow me to explicitly access and configure the underlying AVCapturePhotoOutput instance that ARSession manages. (4) My question is: Is there a way to configure the ARSession's internal AVCapturePhotoOutput to enable its isDepthDataDeliveryEnabled property? Or, is simultaneously capturing a high-resolution frame and its associated depth data simply not a supported use case in the current ARKit framework?
1
0
362
Nov ’25
LockedCameraCaptureExtension and Sharing User Preferences
I have the main app that saves preferences to UserDefaults.standard. So I have this one preference that the user is able to toggle - isRawOn UserDefaults.standard.set(self.isRawOn, forKey: "isRawOn") Now, I have LockedCameraCaptureExtension which is required know if that above setting on or off during launch. Also if it's toggled within the extension, the main app should know about it on the next launch. The main app and the extension runs on separate containers and the preferences are not shared due to privacy reasons. Apple mentions of using appContext of CameraCaptureIntent, but not sure how above scenario is possible through that....unless I am missing something. Apple Reference What I have for CameraCaptureIntent: @available(iOS 18, *) struct LaunchMyAppControlIntent: CameraCaptureIntent { typealias AppContext = MyAppContext static let title: LocalizedStringResource = "LaunchMyAppControlIntent" static let description = IntentDescription("Capture photos with MyApp.") @MainActor func perform() async throws -> some IntentResult { .result() } }
1
0
543
Nov ’25
PHAsset asset.mediaSubtypes.contains(.photoHDR) always return false
we are working on HDR images and found this problem, asset.mediaSubtypes.contains(.photoHDR) always return false func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { guard !results.isEmpty else {return} let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: results.map({$0.assetIdentifier!}), options: nil) var selectedAssets:[PHAsset] = [] fetchResult.enumerateObjects { asset, _, _ in selectedAssets.append(asset) } for i in selectedAssets.enumerated() { let asset:PHAsset = i.element print("\(i.offset): ") print(PHAssetMediaSubtype.photoHDR.rawValue) print(asset.mediaSubtypes) print("photoHDR \(PHAssetMediaSubtype.photoHDR.rawValue): \(asset.mediaSubtypes.contains(.photoHDR))") print("photoLive \(PHAssetMediaSubtype.photoLive.rawValue): \(asset.mediaSubtypes.contains(.photoLive))") print("photoPanorama \(PHAssetMediaSubtype.photoPanorama.rawValue): \(asset.mediaSubtypes.contains(.photoPanorama))") print("photoScreenshot \(PHAssetMediaSubtype.photoScreenshot.rawValue): \(asset.mediaSubtypes.contains(.photoScreenshot))") print("videoHighFrameRate \(PHAssetMediaSubtype.videoHighFrameRate.rawValue): \(asset.mediaSubtypes.contains(.videoHighFrameRate))") print("videoScreenRecording \(PHAssetMediaSubtype.videoScreenRecording.rawValue): \(asset.mediaSubtypes.contains(.videoScreenRecording))") } }
1
0
575
Nov ’25
Uploading asset resources in the background
1.May I ask if the Background Upload can run normally in the Release version of ios 26.1? I used the Release version of ios 26.1 for debugging and found that the background upload couldn't be triggered for a long time. I debugged in ios 26.2 and found that background upload could be triggered normally, but kept triggering an Error: "Error returned from daemon: error Domain=com.apple.accounts Code=7 "(null)"
1
0
365
Nov ’25
Apple Watch app closes when changing photo permissions in the iPhone app.
Apple Watch app closes when changing photo permissions in the iPhone app. App A is installed simultaneously on both the paired iPhone and Apple Watch. I'm running App A on both my iPhone and Apple Watch. When I change the photo permissions on App A installed on my iPhone, App A running on my Apple Watch automatically closes. At first, I assumed App A on my iPhone was abnormally closing, causing App A on my Apple Watch to also close. However, I've determined that changing the photo permissions is the cause of the app closing. I don't think this behavior existed before WatchOS/iOS 26. Is this behavior a natural addition to WatchOS/iOS 26? If I go to the home screen while running app A on my iPhone and change its photo permissions in the Settings app, app A running on my Apple Watch automatically closes.
1
0
334
Nov ’25
Background uploading extension's identifier not official yet
Recently Apple gave us the possibility to upload asset resources in the background. We implemented our background upload extension but when our CI tried to upload the app on TestFlight we got an error that the extension point identifier - in our case com.apple.photos.backgound-upload - is not an official one. Any idea when it will become official and we will be able to release a working background uploading?
1
0
210
Nov ’25
PhotoKit Background Upload Extension not working on iOS 26.2 iPhone 17 Simulator
Hi, I’m trying to implement the new PhotoKit PHBackgroundResourceUploadExtension. I created the extension, enabled full photo library access in the host app, and registered the extension point using the string: com.apple.photos.background-upload. However, when I attempted to enable the extension with: try library.setUploadJobExtensionEnabled(true) I received the following error: Error Domain=PHPhotosErrorDomain Code=-1 "(null)" This happens when running the app on Xcode 26.1 and 26.2 Beta, using the iPhone 17 Pro Max simulator (iOS 26.1 and 26.2). My question is: Is this extension supported on the simulator? I’m asking because at the moment it’s difficult for me to test this on a physical device. Also, What's the meaning of the error? Thanks.
1
1
724
Jan ’26
CoreImage memory build up on real device but not on simulator
I'm trying to benchmark a Core Image filter chains memory footprint and notice a weird quirk in instruments. On a real device, even with a simple Core Image chain, the memory balloons each time I ran the filter. See attached screen shots. Running on iPhone 17 Pro: Running on simulator (M2 Macbook Pro) As you can see there's a huge build up of 4MB "VM: IOSurface" memory on the real device, but the simulator seems to clean it up correctly. Here's my basic code: func processImage() { guard let inputImage = ContentViewModel.loadImageFromBundle(name: "kitty.HEIC") else { print("Failed to load sample_image from bundle") return } var outputImage = inputImage outputImage = outputImage.applyingFilter("CIBloom", parameters: [ kCIInputRadiusKey: 20, kCIInputIntensityKey: 0.8 ]) DispatchQueue.global(qos: .userInitiated).async { let data = self.context.jpegRepresentation(of: outputImage, colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) if let data = data, let uiImage = UIImage(data: data) { DispatchQueue.main.async { self.displayImage = Image(uiImage: uiImage) } } } } Why is this happening? Seems like a bug to me or I need to release an object. At the very least makes it challenging to measure memory usage. Any help is greatly appreciated. Alex
1
0
377
Nov ’25
iPhone 17 (Pro) App Freeze When Changing Ultra-Wide Camera Frame Rate on iOS 26.1
Device: iPhone 17 Pro iOS Version: iOS 26.1 Camera: Ultra-wide (0.5x) using AVCaptureSession Our camera app freezes on iPhone 17 when switching frame rates (30fps ↔ 60fps). This works fine on iPhone 16 Pro and earlier. What We've Observed: Freeze happens on frame rate change - particularly when stabilization was enabled Thread.sleep is used - to allow camera hardware to settle before re-enabling stabilization Works on older iPhones - only iPhone 17 exhibits this behavior Console shows these errors before freeze: 17281 <<<< FigXPCUtilities >>>> signalled err=18446744073709534335 <<<< FigCaptureSourceRemote >>>> err=-17281 Is Thread.sleep on the main thread causing the freeze? Should all camera configuration be on a background queue? Is there something specific about iPhone 17 ultra-wide camera that requires different handling? Should we use session.beginConfiguration() / session.commitConfiguration() instead of direct device configuration? Is calling setFrameRate from a property's didSet (which runs synchronously) problematic? Are the FigCaptureSourceRemote errors (-17281) indicative of the problem, and what do they mean?
1
0
678
Nov ’25
_shouldExposeItemIdentifier is false. Unable to get itemIdentifier
PHPhotoLibrary.authorizationStatus(for: .readWrite) == .authorized Iinfo.plist Privacy - Photo Library Usage Description set I check authorization before attempting to get the photoPickerItem.itemIdentifier, but every time the return value from itemIdentifier is nil. Seems I missing some permissions, but unsure why the system is still keeping _shouldExposeItemIdentifier set to false.
1
0
240
Dec ’25
Can iOS capture video at 4032×3024 while running a Vision/ML model?
I am new to Swift and iOS development, and I have a question about video capture performance. Is it possible to capture video at a resolution of 4032×3024 while simultaneously running a vision/ML model on the video stream (e.g., using Vision or CoreML)? I want to know: whether iOS devices support capturing video at that resolution, whether the frame rate drops significantly at that scale, and whether it is practical to run a Vision/ML model in real-time while recording at such a high resolution. If anyone has experience with high-resolution AVCaptureSession setups or combining them with real-time ML processing, I would really appreciate guidance or sample code.
1
0
207
Dec ’25
Recurring FigXPCUtilities / FigCaptureSourceRemote err=-17281 logs when using AVCaptureVideoDataOutput on iOS 26.x
Hi everyone, I’m seeing recurring internal AVFoundation camera logs on iOS 26.2 and I’m trying to understand whether this is expected behavior or a regression in the capture pipeline. These logs appear shortly after starting an AVCaptureSession, while video frames are being delivered, and also when the camera is stopped or the capture session is torn down. <<<< FigXPCUtilities >>>> signalled err=-17281 at <>:302 <<<< FigCaptureSourceRemote >>>> Fig assert: "err == 0 " at bail (FigCaptureSourceRemote.m:569) - (err=-17281) Even in this clean, minimal setup, the same logs appear on iOS 26.2 The exact same logic did not produce these logs on iOS 18.x. To rule out issues caused by my own code, GPT created a minimal SwiftUI example from scratch. My primary interest is to perform real-time processing on the video frames delivered by the camera (via AVCaptureVideoDataOutput), for tasks such as analysis, computer vision, or custom frame handling, while simultaneously displaying the live preview. Thanks in advance for any insight. Example Code
1
1
716
Jan ’26
VisionKit - crash after photo taken in VNDocumentCameraViewController in iOS 26 when Liquid Glass enabled
I'm adopting Liquid Glass in iOS 26, when I try to test VNDocumentCameraViewController with document scanning after Liquid Glass enabled, there's a crash just after a photo is taken in VNDocumentCameraViewController, here's the screenshot when it crashed The exception output in XCode console is this: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <UINavigationBar: 0x1240bde00; frame = (0 117; 390 54); opaque = NO; tintColor = UIExtendedSRGBColorSpace 1 1 0 1; layer = <CALayer: 0x120c21e60>> standardAppearance=0x12407b900 scrollEdgeAppearance=0x12407bb80 compactAppearance=0x12407b880 no-scroll-edge-support, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x1240bd800> style=navigator leftBarButtonItems=0x123d4e5f0 rightBarButtonItems=0x123d4d5a0, navigation bar = <UINavigationBar: 0x107b9ad00; frame = (0 47; 390 54); opaque = NO; autoresize = W; tintColor = UIExtendedSRGBColorSpace 1 1 0 1; layer = <CALayer: 0x120c20150>> delegate=0x10a805200 standardAppearance=0x107b2c300 scrollEdgeAppearance=0x107b2c280 compactAppearance=0x107b2c100, possibly from a client attempt to nest wrapped navigation controllers.' *** First throw call stack: (0x18e1db994 0x18b0f5814 0x18c092aa0 0x193b18660 0x193a7d540 0x193a7e020 0x1953ec4a0 0x1943b7d78 0x18ed83420 0x18ed82f74 0x18eb83134 0x18eb44c10 0x18eb70bc4 0x18eb7e74c 0x193ac8cd0 0x193ac8c04 0x193ad6afc 0x193ad5f8c 0x27b456560 0x18e12c4cc 0x18e15c0b0 0x18e15bfd8 0x18e133c1c 0x18e132a6c 0x22ed54498 0x193af6ba4 0x193a9fa78 0x193bcb68c 0x102cc2718 0x102cc2688 0x102cc2794 0x18b14ae28) libc++abi: terminating due to uncaught exception of type NSException
1
1
465
Jan ’26
Photos & Imaging Régression - Photos app folders no longer function as folders in iOS 26
I’m writing to report a serious usability regression in the iOS 26 Photos app. Folders can still be created and albums can still be assigned to them, but folders can no longer be opened to view the albums they contain. A container that cannot be opened is not a container, and this breaks a fundamental information architecture model that has existed in Photos for well over a decade. This change disproportionately harms users who maintain large, intentional photo libraries—travel archives, projects, professional work, or long-term personal documentation—where hierarchy and ordering are essential. Search and automated surfacing are not substitutes for deliberate structure. Removing the ability to browse folder → album hierarchy on iOS strips users of control while still exposing the UI for folder creation, which is internally inconsistent. If this behavior is intentional, it should be clearly documented and the folder UI removed to avoid misleading users. If it is not intentional, it needs urgent correction. At minimum, iOS should retain parity with macOS Photos for basic navigation of folders and albums. This is not a niche request; it is a regression in core functionality.
1
0
611
Dec ’25
AVCaptureSession preview briefly goes blank after interruption (lock/unlock or camera switch) while isRunning == true
Environment Device: iPhone 15 Pro iOS: iOS 18.0 Framework: AVFoundation App type: Custom camera app using AVCaptureSession + AVCaptureVideoPreviewLayer I’m seeing an intermittent but frequent issue where the camera preview layer briefly flashes empty after certain interruptions, even though the capture session reports itself as running and no errors are emitted. This happens most often after: Locking and unlocking the device Switching cameras (back ↔ front) The issue is not 100% reproducible, but occurs often enough to be noticeable in normal usage. What happens The preview layer briefly flashes as empty (sometimes just a “micro-frame”) Duration: typically ~0.5–2 seconds before frames resume session.isRunning == true throughout No crash, no runtime error, no interruption end failure Focus/exposure restore correctly once frames resume Visually it looks like the preview layer loses frames temporarily, even though the session appears healthy. Repro Intermittent but frequent after: Lock → unlock device Switching camera (front/back) Timing-dependent and non-deterministic Happens multiple times per session, but not every time Key observation AVCaptureSession.isRunning == true does not guarantee that frames are actually flowing. To verify this, I added an AVCaptureVideoDataOutput temporarily: During the blank period, no sample buffers are delivered Frames resume after ~1–2s without any explicit restart Session state remains “running” the entire time What I’ve tried (did NOT fix it) Adding delays before/after startRunning() (0.1–0.5s) Calling startRunning() on different queues Restarting the session in AVCaptureSessionInterruptionEnded Verifying session.connections (all show isActive == true) Rebuilding inputs/outputs during interruption recovery Ensuring startRunning() is never called between beginConfiguration() / commitConfiguration() (Hit the expected runtime warning when attempted) None of the above removed the brief blank preview. Workaround (works visually but expensive) This visually fixes the issue, but: Energy impact jumps from Low → High in Xcode Energy Gauge AVCaptureVideoDataOutput processes 30–60 FPS continuously The gap only lasts ~1–2s, but toggling the delegate on/off cleanly is difficult Overall CPU and energy cost is not acceptable for production Additional notes CPU usage is already relatively high even without the workaround (this app is camera-heavy by nature) With the workaround enabled, energy impact becomes noticeably worse The issue feels like a timing/state desync between session state and actual frame delivery, not a UI issue Questions Is this a known behavior where AVCaptureSession.isRunning == true but frames are temporarily unavailable after interruptions? Is there a recommended way to detect actual frame flow resumption (not just session state)? Should the AVCaptureVideoPreviewLayer.connection (isActive / isEnabled) be explicitly checked or reset after interruptions? Is there a lightweight, energy-efficient way to bridge this short “no frames” gap without using AVCaptureVideoDataOutput? Is rebuilding the entire session the only reliable solution here, or is there a better pattern Apple recommends?
1
0
873
Jan ’26
Camera Permissions Popup
We have a very strange issue that I am trying to solve or find the best practice for. We have a SwiftUI View that uses the Camera to preview. So as suggested in Apples Docs we check authorisation status and then if it's not determined we request authorisation. We also have the privacy entry in the info.plist case .notDetermined: AVCaptureDevice.requestAccess(for: .video) { accessStatusAuthorised in if !accessStatusAuthorised { self.cameraStatus = .notAuthorised } else { self.isAuthorized = true self.cameraStatus = .authorised self.startCameraSession(cameraPosition: cameraPosition) } } case .restricted: cameraStatus = .notAuthorised isAuthorized = false case .denied: cameraStatus = .notAuthorised isAuthorized = false case .authorized: cameraStatus = .authorised isAuthorized = true startCameraSession(cameraPosition: cameraPosition) break @unknown default: isAuthorized = true cameraStatus = .notAuthorised } However when we call this code it freezes the Camera feed, even when allow has been tapped. However and this is the confusing part. If we do not call the code above, we still get the permission for camera access pop up and the camera works fine after allowing. What im concerned about is changing the code to do this and its a possible apple bug that gets fixed and hey then none of the Apps allow the camera function. I cannot see any where that the process has changed for iOS 26 / Xcode 26. Can anyone shed any light on this or had similar experience ?
1
0
174
Jan ’26