ReactNative で IOS 17 バージョンをアップグレードする際のクラッシュの解決策
1. 問題の説明
スクリーンショットがビジネスで使用される場合UIGraphicsBeginImageContextWithOptions
、UIGraphicsEndImageContext
Assert が報告されます。
エラーメッセージは次のようになります。
- UIGraphicsBeginImageContext() は CGBitampContext の割り当てに失敗しました: size={382, 0}、scale=3.000000、bitmapInfo=0x2002。このアサートを回避するには、UIGraphicsImageRenderer を使用します。
あるいはこうなるだろう
- *** void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)()、UIGraphics.m:410 でアサーション エラーが発生しました
2. 原因分析
API を確認したところ、UIGraphicsBeginImageContext
iOS 17 では廃止されたことがわかりました。ここをクリックして公式ドキュメントを参照してください。公式ドキュメント https://developer.apple.com/documentation/uikit/1623922-uigraphicsbeginimagecontext
次のバージョンの非推奨が明確に確認できます
- iOS 2.0 ~ 17.0 は非推奨になりました
- iPadOS 2.0 ~ 17.0 は非推奨になりました
- Mac Catalyst 13.1 ~ 17.0 は非推奨になりました
- tvOS 9.0–17.0 は非推奨になりました
- watchOS 2.0 ~ 10.0 は非推奨になりました
- visionOS 1.0–1.0 は非推奨になりました
3. ソリューションの意思決定
3.1 幅と高さをゼロ以外の値に設定する
API の幅と高さが 0 でないことを確認すると、正常に使用できますが、変更する必要がある箇所が多数あるため、ビジネス内の属性が 0 に設定されている箇所をすべて確認する必要がある場合があります。
3.2 新しい UIGraphicsImageRenderer を使用して古いバージョンの UIGraphicsBeginImageContext を置き換える
変更は比較的小規模です。サードパーティ ライブラリのネイティブ コンテンツを変更するだけで済みます。ビジネスに関係するすべての要素を確認する必要はありません。一部のページが正常に表示されることを確認するだけで済みます。
4. この API を使用する可能性のあるサードパーティのライブラリ
4.1 反応ネイティブ高速イメージ
解決策: 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 公式ソリューション
公式ソリューションによると、新しいバージョンのパッケージが 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 の表示関数を更新します。
- (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();
}
}
私のプロジェクトのクラッシュはこのライブラリの問題で、グラデーションテキストにコンテンツがある場合は正常に表示されるのですが、テキストコンテンツが存在しない場合にはクラッシュが発生するという非常に奇妙な現象です。
UIGraphicsBeginImageContextWithOptions
4.3次のサードパーティ ライブラリが使用されます。
- React Native自体が境界線を引く
- 反応ネイティブ自体 画像処理/node_modules/react-native/Libraries/Image/RCTImageUtils.m
- 反応ネイティブカメラ
- 反応ネイティブビューショット
- React-native-svg ファイルには、次のアドレスが含まれています:node_modules/react-native-svg/apple/RNSVGRenderable.mm
- 反応ネイティブ-syan-image-picker中 TZImagePickerController
その他のサードパーティ製ライブラリはリストにありませんが、Xcode で検索してUIGraphicsBeginImageContextWithOptions
使用されているかどうかを確認し、表示が正常であるかどうかを確認してください。表示に問題がある場合は、サードパーティのライブラリに対応する公式 Github にアクセスして解決策を見つけるか、自分で置き換えることができます。
5. 参考アドレス
Apple 公式の質問: https://developer.apple.com/forums/thread/733326
Apple 公式の質問: https://developer.apple.com/forums/thread/731385
github の問題: https://github.com/react -native-linear-gradient/react-native-linear-gradient/issues/637