简体   繁体   English

在某些情况下,当从扩展中调用时,UIGraphicsImageRenderer 闭包不会完成并返回图像

[英]UIGraphicsImageRenderer closure doesn't complete and return an image in some cases when invoked from within an extension

I'm attempting to generate an image when a notification service extension receives a push (yes that's within a service extension, not a content extension. I have a requirement to generate an image and add to contacts on receipt of a user directed push).我正在尝试在通知服务扩展收到推送时生成图像(是的,在服务扩展中,而不是内容扩展中。我需要在收到用户定向推送时生成图像并添加到联系人中)。 I have noticed however that in some usages UIGraphicsImageRenderer doesn't return, depending upon what its closure contains.但是,我注意到在某些用法中 UIGraphicsImageRenderer 不会返回,具体取决于其闭包包含的内容。 Here's an example:这是一个例子:

    let mainImageRenderer = UIGraphicsImageRenderer(size: theSize)
    let mainImage = mainImageRenderer.image { context in
        context.cgContext.setFillColor(UIColor.clear.cgColor)
        context.fill(CGRect(origin: .zero, size: screenSize))
        let rectangle = CGRect(x: 0, y: 0, width: 50, height: 50)
        context.cgContext.setFillColor(UIColor.red.cgColor)
        context.cgContext.setStrokeColor(UIColor.black.cgColor)
        context.cgContext.setLineWidth(10)
        context.cgContext.addRect(rectangle)
        context.cgContext.drawPath(using: .fillStroke)
        NSLog("Line 1 - This line logged")
    }
    NSLog("Line 2 - This line not logged and no image is created")

If this code is run within the app itself (or run within a notification content extension for that matter) then it works and Line 2 is reached, but when its run within a notification service extension then Line 2 is never reached.如果此代码在应用程序本身中运行(或在通知内容扩展中运行),那么它可以工作并且到达第 2 行,但是当它在通知服务扩展中运行时,永远不会到达第 2 行。 Its similar behavior if the closure includes UIImage.draw(at:) or UIImage.draw(in) for example.例如,如果闭包包括UIImage.draw(at:)UIImage.draw(in) ,则其行为类似。 However if the closure contains NSAttributedString.draw() then the code executes as expected when called from within the notification extension, here's example code which does workand in this case Line 2 does get reached:但是,如果闭包包含 NSAttributedString.draw() 则代码在从通知扩展中调用时按预期执行,这里的示例代码确实有效,在这种情况下第 2 行确实到达:

let textImage = textRenderer.image { context in
    context.cgContext.setFillColor(gray.cgColor)
    context.fill(CGRect(origin: .zero, size: textRectangleSize))
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center
    let attrs: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 10),
        .paragraphStyle: paragraphStyle
    ]
    let attributedString = NSAttributedString(string: transcript, attributes: attrs)
    attributedString.draw(with: CGRect(x: 10, y: 10, width: textRectangleSize.width - 20, height:textRectangleSize.height - 20),
                          options: .usesLineFragmentOrigin, context: nil)
    NSLog("Line 1 - This line logged")
}
NSLog("Line 2 - Now this line is logged and image is created")

Is there some fundamental reason/issue preventing UIKit from functioning properly within a notification service extension?是否有一些根本原因/问题阻止 UIKit 在通知服务扩展中正常运行? If so then why is NSAttributedString.draw not causing any issues with UIGraphicsImageRenderer but other things such as UIImage.draw() do cause issues?如果是这样,那么为什么 NSAttributedString.draw 不会导致 UIGraphicsImageRenderer 出现任何问题,但其他诸如 UIImage.draw() 之类的东西会导致问题?

Is there an alternative graphics API that I could use instead of UIGraphicsImageRenderer()?是否有可以用来代替 UIGraphicsImageRenderer() 的替代图形 API? I basically want to be able to draw a rectangle within another UIImage.我基本上希望能够在另一个 UIImage 内绘制一个矩形。

UPDATE: After doing some more experimentation, I discovered the size of the image being created affects the results, for example this fails:更新:在做了更多的实验之后,我发现正在创建的图像的大小会影响结果,例如这失败了:

private class func createBackdropImage() -> UIImage {
    let screenSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
    let renderer = UIGraphicsImageRenderer(size: screenSize)
    let image = renderer.image { context in
        context.cgContext.setFillColor(UIColor.red.cgColor)
        context.fill(CGRect(origin: .zero, size: screenSize))
    }
    NSLog("May or may not reach here depending upon size")
    return image
}

If I run the following, on my handset the values for width/height are coming out at 375/812 and this causes the code not to execute as expected and the log line not to be reached.如果我运行以下命令,我的手机上的宽度/高度值将显示为 375/812,这会导致代码无法按预期执行,并且无法到达日志行。 However if the size is made smaller then it works as expected.但是,如果尺寸变小,那么它会按预期工作。 I tried reducing a little from 375/812 down to 370/800 but it still fails, however if I make it smaller, for example 300/700, then it starts working.我尝试将其从 375/812 降低到 370/800,但仍然失败,但是如果我将其变小,例如 300/700,它就会开始工作。

Why is the size of the image being created having this affect?为什么正在创建的图像的大小会产生这种影响? And why only within a notification service extension is this behavior happening?为什么只有在通知服务扩展中才会发生这种行为?

I think this probably is a memory issue.我认为这可能是 memory 问题。 Extensions have limited memory and trying to do image processing with images the size of the screen dimensions might be too much for it, hence why decreasing the overall size of the image being created makes it work.扩展限制了 memory 并且尝试对图像进行图像处理,屏幕尺寸的大小可能对它来说太大了,因此为什么减小正在创建的图像的整体大小使其工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UIGraphicsImageRenderer:灰度图像的pngData - UIGraphicsImageRenderer: pngData for grayscale image Swift-从闭包内部返回变量 - Swift - return variable from within closure 为什么用 UIGraphicsImageRenderer 绘制图像时大量使用 memory? - Why use a lot of memory when drawing image with UIGraphicsImageRenderer? 使用UIGraphicsImageRenderer渲染完整尺寸的图像 - Rendering a full sized image with UIGraphicsImageRenderer SwiftUI 与 addArc 一起旋转在某些情况下无法正常工作 - SwiftUI rotate together with addArc doesn't work correctly in some cases UIGraphicsImageRenderer 生成 PPI 不正确的图像 - UIGraphicsImageRenderer produces image with incorrect PPI 在 UITableview 单元格中折叠 UIImageview,当它不返回图像时 - Collapse UIImageview in UITableview cell, when it doesn't return an image UIGraphicsImageRenderer 应用过滤器后镜像图像 - UIGraphicsImageRenderer mirrors image after applying filter 从转义闭包更新 UILabel 不会立即生效 - Updating a UILabel from an escaping closure doesn't take effect immedialtely 在某些情况下尝试自动调整大小时,iOS 10中的键盘扩展名会失去高度 - Keyboard extension loses height in iOS 10 when trying to size automatically in some cases
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM