ReactNative中升級IOS 17版本Crash解決
一、問題描述
業(yè)務(wù)上用了截圖相關(guān)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,發(fā)現(xiàn) UIGraphicsBeginImageContext
在iOS 17上已經(jīng) 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 設(shè)置寬高為非零值
當我們保證api 寬高不為零,則可正常使用,需要改動的地方較多,可能需要將業(yè)務(wù)中每一個設(shè)置為零屬性的地方都得檢查
3.2 使用新的UIGraphicsImageRenderer替換就版本的UIGraphicsBeginImageContext
改動較小,只需要改動三方庫中原生內(nèi)容即可,無需針對業(yè)務(wù)中涉及到的每一個元素進行校驗,只需要驗證部分頁面展示正常即可。
四、可能使用到該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 官方解決
按照官方解決,已經(jīng)提供了新的版本包在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函數(shù)。
- (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();
}
}
我項目中閃退的就是這個庫出的問題,當漸變的文本有內(nèi)容時,則展示是正常的,但是當文本內(nèi)容不存在時,就會出現(xiàn)閃退,這就很詭異。
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
,檢查是否是有使用到,同時驗證顯示正常與否。如果顯示有問題,則可以去三方庫對應(yīng)的官方Github尋求解決方案或者自行替換。文章來源:http://www.zghlxwxcb.cn/news/detail-718472.html
五、參考地址
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
github: https://github.com/ibireme/YYText/issues/984
github:https://github.com/muntius/react-native-fast-image/commit/fc2b8acd97f07989e312f5cbd61d2e541fda3611
github:https://github.com/DylanVann/react-native-fast-image/issues/1002文章來源地址http://www.zghlxwxcb.cn/news/detail-718472.html
到了這里,關(guān)于ReactNative中升級IOS 17版本Crash解決的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!