ReactNative中升级IOS 17版本Crash解决

news/2024/7/20 22:51:29 标签: ios, react native, objective-c

ReactNative中升级IOS 17版本Crash解决


在这里插入图片描述

    • ReactNative中升级IOS 17版本Crash解决
        • 一、问题描述
        • 二、原因分析
        • 三、解决方案决策
          • 3.1 设置宽高为非零值
          • 3.2 使用新的UIGraphicsImageRenderer替换就版本的UIGraphicsBeginImageContext
        • 四、可能使用到该API的三方库
          • 4.1 react-native-fast-image
          • 4.2 react-native-linear-gradient
          • 4.3 使用到 `UIGraphicsBeginImageContextWithOptions` 的三方库还有以下一些:
        • 五、参考地址

一、问题描述

业务上用了截图相关UIGraphicsBeginImageContextWithOptions && UIGraphicsEndImageContext 会报出 Assert。

错误信息会是下面这样:

  • UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={382, 0}, scale=3.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer to avoid this assert.

或者会是这样的

  • *** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410
二、原因分析

查了下 api,发现 UIGraphicsBeginImageContext 在iOS 17上已经 deprecated 了. 点击这里,看看官方文档 官方文档说明https://developer.apple.com/documentation/uikit/1623922-uigraphicsbeginimagecontext

在这里插入图片描述

能够清楚地看到针对以下版本废弃

  • iOS 2.0–17.0 Deprecated
  • iPadOS 2.0–17.0 Deprecated
  • Mac Catalyst 13.1–17.0 Deprecated
  • tvOS 9.0–17.0 Deprecated
  • watchOS 2.0–10.0 Deprecated
  • visionOS 1.0–1.0 Deprecated
三、解决方案决策
3.1 设置宽高为非零值

当我们保证api 宽高不为零,则可正常使用,需要改动的地方较多,可能需要将业务中每一个设置为零属性的地方都得检查

3.2 使用新的UIGraphicsImageRenderer替换就版本的UIGraphicsBeginImageContext

改动较小,只需要改动三方库中原生内容即可,无需针对业务中涉及到的每一个元素进行校验,只需要验证部分页面展示正常即可。

四、可能使用到该API的三方库
4.1 react-native-fast-image

解决方案:react-native-fast-image 官方解决
修改node_modules文件路径: ios/FastImage/FFFastImageView.m


- (UIImage*) makeImage: (UIImage*)image withTint: (UIColor*)color {
    UIImage* newImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];

    UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:image.size format:format];

    UIImage *resultImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
        CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
        [color set];
        [newImage drawInRect:rect];
    }];

    return resultImage;
}


4.2 react-native-linear-gradient

官方解决方案: react-native-linear-gradient 官方解决

按照官方解决,已经提供了新的版本包在npm仓库,此时我们可以去更新源代码或者直接更新版本:

  • 下载是最新的版本
    下载最新版本地址:https://github.com/react-native-linear-gradient/react-native-linear-gradient/releases/tag/v2.8.3
    也可以直接去看看npm仓库。

  • 直接更新源码

如果要更新源代码,则进行更新路径/node_modules/react-native-linear-gradient/ios/BVLinearGradientLayer.m 文件中 display函数。


- (void)display {
    [super display];

    // short circuit when height or width are 0. Fixes CGContext errors throwing
    if (self.bounds.size.height == 0 || self.bounds.size.width == 0) {
      return;
    }

    BOOL hasAlpha = NO;

    for (NSInteger i = 0; i < self.colors.count; i++) {
        hasAlpha = hasAlpha || CGColorGetAlpha(self.colors[i].CGColor) < 1.0;
    }

    if (@available(iOS 10.0, *)) {
        UIGraphicsImageRendererFormat *format;
        if (@available(iOS 11.0, *)) {
            format = [UIGraphicsImageRendererFormat preferredFormat];
        } else {
            format = [UIGraphicsImageRendererFormat defaultFormat];
        }
        format.opaque = !hasAlpha;
        UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size format:format];
        UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull ref) {
            [self drawInContext:ref.CGContext];
        }];

        self.contents = (__bridge id _Nullable)(image.CGImage);
        self.contentsScale = image.scale;
    } else {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, !hasAlpha, 0.0);
        CGContextRef ref = UIGraphicsGetCurrentContext();
        [self drawInContext:ref];

        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        self.contents = (__bridge id _Nullable)(image.CGImage);
        self.contentsScale = image.scale;

        UIGraphicsEndImageContext();
    }
}

我项目中闪退的就是这个库出的问题,当渐变的文本有内容时,则展示是正常的,但是当文本内容不存在时,就会出现闪退,这就很诡异。

4.3 使用到 UIGraphicsBeginImageContextWithOptions 的三方库还有以下一些:
  • react native本身绘画边框
  • react-native本身图片处理 /node_modules/react-native/Libraries/Image/RCTImageUtils.m
  • react-native-camera
  • react-native-view-shot
  • react-native-svg 文件包含地址: node_modules/react-native-svg/apple/RNSVGRenderable.mm
  • react-native-syan-image-picker 中 TZImagePickerController

其他三方库没有列出来,可以在Xcode中进行搜索 UIGraphicsBeginImageContextWithOptions ,检查是否是有使用到,同时验证显示正常与否。如果显示有问题,则可以去三方库对应的官方Github寻求解决方案或者自行替换。

五、参考地址

Apple官方提问:https://developer.apple.com/forums/thread/733326
Apple官方提问:https://developer.apple.com/forums/thread/731385
github issue:https://github.com/react-native-linear-gradient/react-native-linear-gradient/issues/637



http://www.niftyadmin.cn/n/5038000.html

相关文章

Jolokia 笔记 (Kafka/start/stop)

目录 1. Jolokia 笔记 (Kafka/start/stop) 1. Jolokia 笔记 (Kafka/start/stop) java -javaagent:agent.jarport8778,hostlocalhostJolokia 是作为 Kafka 的 Java agent, 基于 HTTP 协议提供了一个使用 JSON 作为数据格式的外部接口, 提供给 DataKit 使用。 Kafka 启动时, 先配…

应用平台 - OPPO敏感权限

那天在OPPO平台更新app时&#xff0c;发现平台权限升级&#xff0c;新增了敏感权限校验&#xff0c;而且还是必填项… Google 从 Android6.0 开始就对权限做了分类适配&#xff0c;粗浅来看将权限分为了普通权限、危险权限&#xff08;运行时权限、敏感权限&#xff09;&#x…

pytorch的卷积层池化层和非线性变化 和机器学习线性回归

卷积层&#xff1a; 两个输出的情况 就会有两个通道 可以改变通道数的 最简单的神经网络结构&#xff1a; nn.Mudule就是继承父类 super执行的是 先执行父类函数里面的 forward执行的就是前向网络&#xff0c;就是往前推进的&#xff0c;当然也有反向转播&#xff0c;那就是…

实施主品牌进化战略(一):确立主品牌进化架构

主品牌进化战略&#xff0c;即以主品牌为核心创造、巩固、转化竞争优势应对竞争环境变化&#xff0c;避免衰退&#xff0c;回归增长&#xff0c;让主品牌进化的方法论体系。主品牌进化战略制定要从 4 个方面出发&#xff1a;确立主品牌进化架构、更新和明确主品牌竞争方向、建立…

爬虫 — Js 逆向案例二微信公众平台登录

目标网站&#xff1a;https://mp.weixin.qq.com/ 需求&#xff1a;找到密码加密的过程&#xff0c;进行加密 案例分析 1、抓到向服务器发请求的数据包&#xff0c;输入错误的账号和密码 2、找到加密字段 pwd 如果 Search 里面数据太多&#xff0c;也可以在 Initiator 里面查找…

Linux 目录结构介绍

对上面的说明: root 目录 &#xff1a; linux 超级权限 root 的主目录 home 目录 &#xff1a; 系统默认的用户主目录&#xff0c;如果添加用户是不指定用户的主目录&#xff0c;默认在/home 下创建与用户同名的文件夹 bin 目录 &#xff1a; 存放系统所需要的重要命令&am…

【滑动窗口】LCR 016. 无重复字符的最长子串

LCR 016. 无重复字符的最长子串 解题思路 窗口内的字符串就是不重复子串每次遇到新的字符 看看窗口内是否存在该字符 如果存在直接剔除 然后调整窗口左边界不存在 添加窗口内部 右边界 class Solution {public int lengthOfLongestSubstring(String s) {if(s.length() < …

【pytest】 pytest拓展功能 pycharm PermissionError: [Errno 13] Permission denied:

目录 1. pytest-html 1.1 PermissionError: [Errno 13] Permission denied: D:\\software\\python3\\anconda3\\Lib\\site-packages\\pytest_html\\__pycache__\\tmp_ttoasov 1.2错误原因 2. 失败用例重试 3. 用例并行执行 pytest-parallel 1. pytest-html 管理员打开 A…