Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on iOS 17 due to UIGraphicsBeginImageContextWithOptions(0,0,...) in UIImage.tinted(with:) extension #6

Open
jcuervo-almato opened this issue Jan 22, 2025 · 0 comments

Comments

@jcuervo-almato
Copy link

> Crash on iOS 17 due to UIGraphicsBeginImageContextWithOptions(0,0,...) in UIImage.tinted(with:) extension

Hello PaceCloud SDK team,

I’m encountering a crash on iOS 17 (and possibly iOS 16.4+) caused by the tinted(with:) extension in UIImage+Extension.swift. When UIImage.size is (0,0), the call to UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) fails, resulting in this error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'UIGraphicsBeginImageContext() failed to allocate CGBitmapContext: size={0, 0}, ...'

In my use case, the Connected Fueling drawer occasionally tries to tint an icon that inadvertently has a zero-size image, triggering the crash. It appears iOS 17 is more strict about UIGraphicsBeginImageContextWithOptions being called with (0,0) sizes.


Proposed Solution

I replaced the UIGraphicsBeginImageContextWithOptions usage with UIGraphicsImageRenderer, along with a guard statement checking that the image’s width and height are non-zero. Here is my revised extension:

extension UIImage {
    func tinted(with color: UIColor) -> UIImage {
        // Prevent a crash by skipping the operation if size is zero.
        guard self.size.width > 0, self.size.height > 0 else {
            return self
        }

        let renderer = UIGraphicsImageRenderer(
            size: self.size,
            format: UIGraphicsImageRendererFormat.default()
        )

        return renderer.image { context in
            let cgContext = context.cgContext
            cgContext.translateBy(x: 0, y: self.size.height)
            cgContext.scaleBy(x: 1.0, y: -1.0)

            color.setFill()

            if let cgImage = self.cgImage {
                cgContext.clip(to: CGRect(origin: .zero, size: self.size), mask: cgImage)
            }
            cgContext.fill(CGRect(origin: .zero, size: self.size))
        }
    }
}
  • Key changes:
    • A simple guard self.size.width > 0, self.size.height > 0 else { return self } avoids trying to tint an image of zero size.
    • Use UIGraphicsImageRenderer to avoid UIGraphicsBeginImageContextWithOptions(0,0,...) in the first place.

This workaround solves the crash for me on iOS 17 while retaining existing behavior for images with valid sizes.


Request / Context

  1. Context: The crash surfaced in a scenario where the PaceCloud UI tries to render a tinted icon that may occasionally have a zero size.
  2. iOS 17: Apple now appears to throw an assertion instead of silently ignoring (0,0) contexts.
  3. Suggested Next Steps: Integrate a check for zero-size images and/or switch from UIGraphicsBeginImageContextWithOptions to UIGraphicsImageRenderer in the official SDK code.

Thank you for reviewing this. Let me know if you need any more details. I hope this proposed fix can be incorporated (or an equivalent safeguard put in place) to handle zero-sized images gracefully on iOS 17+.

Best regards,
Jean Cuervo - Almato Iberia

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant