Skip to content

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

@jcuervo-almato

Description

@jcuervo-almato

> 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions