[BUG] SIGABRT on iOS when Permissions.Camera not Granted
Is there an existing issue for this?
- [x] I have searched the existing issues
Did you read the "Reporting a bug" section on Contributing file?
- [x] I have read the "Reporting a bug" section on Contributing file: https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md#reporting-a-bug
Current Behavior
The first thing I do when I navigate to a page containing CameraView is checking permissions for Camera. If I don't grant permission on iOS, the application keeps on crashing due to SIGABRT when navigating to this page.
Here I attach full output:
**CommunityToolkit.Maui.Core.CameraException:** 'No camera available on device'
2025-02-14 14:18:27.710420+0100 SampleCameraView[12160:68715]
Unhandled Exception:
CommunityToolkit.Maui.Core.CameraException: No camera available on device
at CommunityToolkit.Maui.Core.CameraManager.<PlatformStartCameraPreview>d__33.MoveNext()
at CommunityToolkit.Maui.Core.CameraManager.<PlatformConnectCamera>d__34.MoveNext()
at CommunityToolkit.Maui.Core.Handlers.CameraViewHandler.ConnectHandler(UIView platformView)
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply() in /Users/builder/azdo/_work/2/s/xamarin-macios/src/Foundation/NSAction.cs:line 179
--- End of stack trace from previous location ---
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle) in /Users/builder/azdo/_work/2/s/xamarin-macios/src/ObjCRuntime/Runtime.cs:line 2719
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/2/s/xamarin-macios/src/
UIKit/UIApplication.cs:line 64
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/2/s/xamarin-macios/src/UIKit/UIApplication.cs:line 96
at SampleCameraView.Program.Main(String[] args) in C:\Users
k-alex\Documents\ProjectsPersonal\CameraView\SampleCameraView\SampleCameraView\Platforms\iOS\Program.cs:line 13
2025-02-14 14:18:27.712810+0100 SampleCameraView[12160:68715] Unhandled managed exception: No camera available on device (CommunityToolkit.Maui.Core.CameraException)
at CommunityToolkit.Maui.Core.CameraManager.<PlatformStartCameraPreview>d__33.MoveNext()
at CommunityToolkit.Maui.Core.CameraManager.<PlatformConnectCamera>d__34.MoveNext()
at CommunityToolkit.Maui.Core.Handlers.CameraViewHandler.ConnectHandler(UIView platformView)
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply() in /Users/builder/azdo/_work/2/s/xamarin-macios/src/Foundation/NSAction.cs:line 179
--- End of stack trace from previous location ---
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle) in /Users/builder/azdo/_work/2/s/xamarin-macios/src/ObjCRuntime/Runtime.cs:line 2719
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/2/s/xamarin-mac
ios/src/UIKit/UIApplication.cs:line 64
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/2/s/xamarin-macios/src/UIKit/UIApplication.cs:line 96
at SampleCameraView.Program.Main(String[] args) in C:\Users
k-alex\Documents\ProjectsPersonal\CameraView\SampleCameraView\SampleCameraView\Platforms\iOS\Program.cs:line 13
=================================================================
Native Crash Reporting
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
=================================================================
Native stacktrace:
=================================================================
0x1031f82e4 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : mono_dump_native_crash_info
0x1031a9588 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : mono_handle_native_crash
0x10336a944 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : sigabrt_signal_handler.cold.1
0x1031f7b10 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : mono_runtime_setup_stat_profiler
0x102017760 - /usr/lib/system/libsystem_platform.dylib : _sigtramp
0x1021c3408 - /usr/lib/system/libsystem_pthread.dylib : pthread_kill
0x1801704ec - /Library/Developer/CoreSimulator/Volumes/iOS_22C150/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.2.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/libsystem_c.dylib : abort
0x1025928d4 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libxamarin-dotnet-debug.dylib : xamarin_find_protocol_wrapper_type
0x10327b5d0 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : mono_invoke_unhandled_exception_hook
0x10316cb4c - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libmonosgen-2.0.dylib : mono_jit_exec
0x1025a7984 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/libxamarin-dotnet-debug.dylib : xamarin_main
0x101786474 - /Users/nk/Library/Developer/CoreSimulator/Devices/30DB2FD0-E4AC-4B84-85B2-7483382D53E4/data/Containers/Bundle/Application/40DCB2B4-F309-4E5A-863C-EFD400300220/SampleCameraView.app/SampleCameraView : main
0x10233d410 - Unknown
0x10207e274 - Unknown
=================================================================
Basic Fault Address Reporting
=================================================================
Memory around native instruction pointer (0x1024dd008):0x1024dcff8 c0 03 5f d6 c0 03 5f d6 10 29 80 d2 01 10 00 d4 .._..._..)......
0x1024dd008 e3 00 00 54 fd 7b bf a9 fd 03 00 91 ee e2 ff 97 ...T.{..........
0x1024dd018 bf 03 00 91 fd 7b c1 a8 c0 03 5f d6 c0 03 5f d6 .....{
...._..._.
0x1024dd028 70 0a 80 d2 01 10 00 d4 e3 00 00 54 fd 7b bf a9 p..........T.{..
=================================================================
Managed Stacktrace:
=================================================================
=================================================================
INFO: Closing debug session after launching on simulator...
The app has been terminated.
Expected Behavior
To be able to handle this exception and avoid application from crashing
Steps To Reproduce
- Create a simple page with CameraView on it.
- On the related ViewModel, ask for Camera permissions.
- If you accept permissions, everything works as expected.
- If you DON'T accept permissions, application will crash showing SIGABRT
Link to public reproduction project repository
https://github.com/nk-alex/CameraView/tree/main
Environment
- .NET MAUI CommunityToolkit.Maui: 9.0.2
- .NET MAUI CommunityToolkit.Maui.Camera: 1.0.5
- OS:
- .NET MAUI: 8.0.71
Anything else?
Due to several dependencies I'm not going to be able to update my project to .NET 9 by now. So I'm looking for a possible workaround for .NET 8
I check device permission beforehand to avoid the crash on iOS. This doesn't work on Windows for me because Windows returns granted for all Permissions. Therefore I'm unable to detect a denied permission on Windows.
The docs give this example to check and request permission: https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/permissions?view=net-maui-9.0&tabs=windows
public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status == PermissionStatus.Granted)
return status;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// Prompt the user to turn on in settings
// On iOS once a permission has been denied it may not be requested again from the application
return status;
}
if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
{
// Prompt the user with additional information as to why the permission is needed
}
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
return status;
}
You can adjust the function to take a Permission generic so it can be reused for all Permissions if you'd like.
CameraViewHandler.ConnectHandler doesn't actually check the result of the permission request:
https://github.com/CommunityToolkit/Maui/blob/e6c7c4d75682a95e68d00ca47ff64290fd75743a/src/CommunityToolkit.Maui.Camera/Handlers/CameraViewHandler.shared.cs#L87-L97
https://github.com/CommunityToolkit/Maui/blob/e6c7c4d75682a95e68d00ca47ff64290fd75743a/src/CommunityToolkit.Maui.Camera/CameraManager.shared.cs#L26-L33
I think a fix becomes a question of: "How should the control behave when camera authorization is not granted"?
- Is it possible to bubble-up a
PermissionExceptionand let consumers respond? - Should it display some sort of default "error" view? Something like CollectionView's EmptyView
- etc...
I think the first solution seems most appropriate for this issue: bubble-up a PermissionException and let consumers respond.
PR created: https://github.com/CommunityToolkit/Maui/pull/2634
I think the first solution seems most appropriate for this issue: bubble-up a PermissionException and let consumers respond.
PR created: #2634
I tend to agree, but don't know if handlers are the best place to be throwing exceptions. Wouldn't that require consumers to derive from CameraViewHandler?
MyCameraViewHandler.cs
public class MyCameraViewHandler: CameraViewHandler
{
protected override async void ConnectHandler(NativePlatformCameraPreviewView platformView)
{
try
{
base.ConnectHandler(platformView);
}
catch (PermissionException ex)
{
// Handle
}
}
}
Handling the exception internally and providing notification via an event or "error" property might make consumption a bit easier.
What do you think about leveraging the existing OnMediaCaptureFailed in this case?
@phunkeler
I agree that throwing exceptions in the handlers isn't ideal for consumers to handle. However, I feel that the OnMediaCaptureFailed event doesn't seem appropriate for this use case either, as its name implies it should only be triggered when a media capture operation fails. It might make more sense to introduce a new event specifically for this kind of scenario?