Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 21, 2025

Problem

Customers were experiencing crashes when taking screenshots in iOS apps with the following error:

Objective-C exception thrown. Name: NSInternalInconsistencyException 
Reason: UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={1080, 810}, scale=2.000000, bitmapInfo=0x2006. 
Use UIGraphicsImageRenderer to avoid this assert.

The crash was occurring in both UIScreen.Capture() and UIView.Capture() methods, which were using the deprecated UIGraphicsBeginImageContextWithOptions API. Apple explicitly recommends using UIGraphicsImageRenderer instead to avoid these allocation failures.

Solution

Replaced the deprecated UIGraphicsBeginImageContextWithOptions API with the modern UIGraphicsImageRenderer API in both affected methods:

UIScreen.Capture()

  • Removed legacy iOS version checks and fallback code paths
  • Simplified from ~40 lines to a clean 9-line implementation
  • Now uses UIGraphicsImageRenderer to capture the KeyWindow

UIView.Capture(bool afterScreenUpdates)

  • Replaced try-finally block with using statement for UIGraphicsImageRenderer
  • Maintained the afterScreenUpdates parameter functionality
  • Cleaner, more maintainable code

Benefits

  • ✅ Eliminates the CGBitmapContext allocation crash reported by users
  • ✅ Uses Apple's recommended modern API (available on all supported iOS versions)
  • ✅ Simplifies code by removing legacy version checks
  • ✅ More robust and efficient image rendering
  • ✅ Follows Apple's guidelines from the error message itself

References

Fixes #24053.

Original prompt

This section details on the original issue you should resolve

<issue_title>Crash: UIKit - UIScreen - Capture: UIGraphicsBeginImageContext() failed to allocate CGBitampContext</issue_title>
<issue_description>### Apple platform

iOS

Framework version

net9.0-*

Affected platform version

VSCode on mac; .net9 maui 9.0.110

Description

every few days i get a crash from customers of my App that reads like this:

Objective-C exception thrown.  Name: NSInternalInconsistencyException Reason: UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={1080, 810}, scale=2.000000, bitmapInfo=0x2006. Use UIGraphicsImageRenderer to avoid this assert.
Native stack trace:
	0   CoreFoundation                      0x000000018ef55de8 2744BAE5-E258-3D88-B1E7-17A118109A6F + 1113576
	1   libobjc.A.dylib                     0x000000018c6e1d8c objc_exception_throw + 72
	2   Foundation                          0x000000018e2b36c8 519FF073-0591-3EF4-8FE1-4AA7226AC834 + 7268040
	3   UIKitCore                           0x00000001917e8704 A6B14CA2-D4B7-3636-96A8-2280A3954EF4 + 2746116
	4   mycompany.myapp.ios                   0x0000000103582198 wrapper_managed_to_native_UIKit_UIGraphics_BeginImageContextWithOptions_CoreGraphics_CGSize_byte_System_Runtime_InteropServices_NFloat + 168
	5   mycompany.myapp.ios                   0x0000000106e61ac8 Microsoft_iOS_UIKit_UIScreen_Capture + 1196
	6   mycompany.myapp.ios                   0x0000000102e3c328 DATAflor_Common_iOS_DependencyService_DFiOSScreenshotService_TakeScreenshot_object + 88
	7   mycompany.myapp.ios                   0x000000010419d298 DATAflor_Time_iOS_DATAflor_Time_iOS_CustomUIApplication__c__DisplayClass8_0__OnDisplayTouchb__0 + 88
	8   mycompany.myapp.ios                   0x00000001071e3ae8 -[CustomUIApplication sendEvent:] + 48

we are doing screenshots in our app for Hotline-Service-purposes.
now with maui is see these crashes (didn't find such crashes with the old xamarin app but i think it was build with an older XCode too)

When i look at the code here on github (UIKit/UIScreen - Capture) is see this:

public UIImage Capture ()
		{
			if (SystemVersion.CheckiOS (7, 0)) {
				// This is from https://developer.apple.com/library/content/qa/qa1817/_index.html
				try {
					var view = UIApplication.SharedApplication.KeyWindow;
					UIGraphics.BeginImageContextWithOptions (view.Bounds.Size, view.Opaque, 0);
					view.DrawViewHierarchy (view.Bounds, true);
					return UIGraphics.GetImageFromCurrentImageContext ();
				} finally {
					UIGraphics.EndImageContext ();
				}
			}

			// This is from: https://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
			var selScreen = new Selector ("screen");
			var size = Bounds.Size;

			UIGraphics.BeginImageContextWithOptions (size, false, 0);

			try {
				var context = UIGraphics.GetCurrentContext ();

				foreach (var window in UIApplication.SharedApplication.Windows) {
					if (window.RespondsToSelector (selScreen) && window.Screen != this)
						continue;

					context.SaveState ();
					context.TranslateCTM (window.Center.X, window.Center.Y);
					context.ConcatCTM (window.Transform);
					context.TranslateCTM (-window.Bounds.Size.Width * window.Layer.AnchorPoint.X, -window.Bounds.Size.Height * window.Layer.AnchorPoint.Y);

					window.Layer.RenderInContext (context);
					context.RestoreState ();
				}

				return UIGraphics.GetImageFromCurrentImageContext ();
			} finally {
				UIGraphics.EndImageContext ();
			}
		}

As far as i'm aware, BeginImageContextWithOptions is obsolete / deprecated?! wasn't that documented somewhere at apple and discussed in some maui-issue-threads? :)

so i wonder if this could be changed here and if this would fix that crash?
Or if someone could tell me why it ISN'T changed here?

Thanks a lot

Steps to Reproduce

don't know - write an app that calls ".Capture()" in the iOS-Part of a maui app running on iOS (iPad, iPhone)? It doesn't happen every time but i see it every few days when my customers are reporting it.

Did you find any workaround?

not yet

Relevant logs

see issue with the log inside</issue_description>

<agent_instructions>The Capture method should be updated, and there are two versions:

  • public UIImage Capture ()
    {
    if (SystemVersion.CheckiOS (7, 0)) {
    // This is from https://developer.apple.com/library/content/qa/qa1817/_index.html
    try {
    var view = UIApplication.SharedApplication.KeyWindow;
    UIGraphics.BeginImageContextWithOptions (view.Bounds.Size, view.Opaque, 0);
    view.DrawViewHierarchy (view.Bounds, true);
    return UIGraphics.GetImageFromCurrentImageContext ();
    } finally {
    UIGraphics.EndImageContext ();
    }
    }
    // This is from: https://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
    var selScreen = new Selector ("screen");
    var size = Bounds.Size;
    UIGraphics.BeginImageContextWithOptions (size, false, 0);
    try {
    var context = UIGraphics.GetCurrentContext ();
    foreach (var window in UIApplication.SharedApplication.Windows) {
    if (window.RespondsToSelector (selScreen) && window.Screen != this)
    continue;
    context.SaveState ();
    context.TranslateCTM (window.Center.X, window.Center.Y);
    context.ConcatCTM (window.Transform);
    context.TranslateCTM (-window.Bounds.Size.Width * window.Layer.AnchorPoint.X, -window.Bounds.Size.Height * window.Layer.AnchorPoint.Y);
    window.Layer.RenderInContext (context);
    context.RestoreState ();
    }
    return UIGraphics.GetImageFromCurrentImageContext ();
    } finally {
    UIGraphics.EndImageContext ();
    }
    }
    }
  • macios/src/UIKit/UIView.cs

    Lines 253 to 265 in c7579d1

    public UIImage Capture (bool afterScreenUpdates = true)
    {
    UIImage snapshot;
    var bounds = Bounds; // try to access objc the smalles amount of times.
    try {
    UIGraphics.BeginImageContextWithOptions (bounds.Size, Opaque, 0.0f);
    DrawViewHierarchy (bounds, afterScreenUpdates);
    snapshot = UIGraphics.GetImageFromCurrentImageContext ();
    } finally {
    UIGraphics.EndImageContext ();
    }
    return snapshot;
    }

Update both to use my suggestion from my first comment in this issue.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@rolfbjarne This is completely untested, but can you try this and see if it works for you?
public UIImage Capture ()
{
	var view = UIApplication.SharedApplication.KeyWindow;
	using var renderer = new UIGraphicsImageRenderer (size);
	return renderer.CreateImage ((context) => {
		view.DrawViewHier...

</details>

Fixes dotnet/macios#24053

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start the survey.

…hicsImageRenderer in UIScreen and UIView Capture methods

Co-authored-by: rolfbjarne <[email protected]>
Copilot AI changed the title [WIP] Fix crash caused by UIGraphicsBeginImageContext failure Fix crash in UIScreen.Capture() and UIView.Capture() by replacing deprecated UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer Oct 21, 2025
Copilot AI requested a review from rolfbjarne October 21, 2025 10:04
Copilot finished work on behalf of rolfbjarne October 21, 2025 10:04
@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #1b062e4] Build passed (Build packages) ✅

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [PR Build #1b062e4] Build passed (Detect API changes) ✅

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #1b062e4] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #1b062e4] Tests on macOS X64 - Mac Sonoma (14) passed 💻

All tests on macOS X64 - Mac Sonoma (14) passed.

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #1b062e4] Tests on macOS M1 - Mac Monterey (12) passed 💻

All tests on macOS M1 - Mac Monterey (12) passed.

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #1b062e4] Tests on macOS arm64 - Mac Sequoia (15) passed 💻

All tests on macOS arm64 - Mac Sequoia (15) passed.

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #1b062e4] Tests on macOS M1 - Mac Ventura (13) passed 💻

All tests on macOS M1 - Mac Ventura (13) passed.

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #1b062e4] Tests on macOS arm64 - Mac Tahoe (26) passed 💻

All tests on macOS arm64 - Mac Tahoe (26) passed.

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🚀 [CI Build #1b062e4] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 115 tests passed 🎉

Tests counts

✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker: All 44 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 8 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 11 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 9 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 8 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: 1b062e40d1bd884dc081decb76d32afc0e0957f8 [PR build]

@rolfbjarne rolfbjarne changed the title Fix crash in UIScreen.Capture() and UIView.Capture() by replacing deprecated UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer Fix crash in UIScreen.Capture() and UIView.Capture() by replacing deprecated UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer. Fixes #24053. Oct 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash: UIKit - UIScreen - Capture: UIGraphicsBeginImageContext() failed to allocate CGBitampContext

3 participants