From a9810b1ce28cd1dd72067072f72ab5f9bbb84358 Mon Sep 17 00:00:00 2001 From: Bron Davies Date: Fri, 23 Oct 2026 08:46:07 -0600 Subject: [PATCH] fix(macos): declare UIImagePNGRepresentation and UIImageJPEGRepresentation extern "C" They are defined in RCTUIImage.m, an Objective-C file, so their symbols are C. Declared without extern "C", an Objective-C++ caller looks for C++-mangled names and fails to link on macOS (react-native-svg's RNSVGSvgView.mm, for one). The other two functions in RCTUIImage.h are already declared this way. RCTImageLoader.mm kept a copy of both functions from when React-RCTImage could not depend on RCTUIKit (#1611). As C++ its copies had mangled names and never clashed; declared extern "C" they would be duplicate symbols. React-Core depends on React-RCTUIKit now, so the copy goes and the image loader uses RCTUIKit's. --- .../Libraries/Image/RCTImageLoader.mm | 32 ------------------- .../Libraries/RCTUIKit/RCTUIImage.h | 8 +++++ 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/packages/react-native/Libraries/Image/RCTImageLoader.mm b/packages/react-native/Libraries/Image/RCTImageLoader.mm index 19d7461cf4ab..3d750fb0b6bb 100644 --- a/packages/react-native/Libraries/Image/RCTImageLoader.mm +++ b/packages/react-native/Libraries/Image/RCTImageLoader.mm @@ -40,38 +40,6 @@ static NSInteger RCTImageBytesForImage(RCTPlatformImage *image) // [macOS] #endif // macOS] } -#if TARGET_OS_OSX // [macOS - -/** - * Github #1611 - We can't depend on RCTUIKit here, because this file's podspec (React-RCTImage) doesn't - * take a dependency on RCTUIKit's pod `React-Core`. Let's just copy the methods we want to shim here - */ - -static NSData *NSImageDataForFileType(NSImage *image, NSBitmapImageFileType fileType, NSDictionary *properties) -{ - RCTAssert(image.representations.count == 1, @"Expected only a single representation since UIImage only supports one."); - - NSBitmapImageRep *imageRep = (NSBitmapImageRep *)image.representations.firstObject; - if (![imageRep isKindOfClass:[NSBitmapImageRep class]]) { - RCTAssert([imageRep isKindOfClass:[NSBitmapImageRep class]], @"We need an NSBitmapImageRep to create an image."); - return nil; - } - - return [imageRep representationUsingType:fileType properties:properties]; -} - - -NSData *UIImagePNGRepresentation(NSImage *image) { - return NSImageDataForFileType(image, NSBitmapImageFileTypePNG, @{}); -} - -NSData *UIImageJPEGRepresentation(NSImage *image, CGFloat compressionQuality) { - return NSImageDataForFileType(image, - NSBitmapImageFileTypeJPEG, - @{NSImageCompressionFactor: @(compressionQuality)}); -} -#endif // macOS] - static auto currentRequestCount = std::atomic(0); static NSError *addResponseHeadersToError(NSError *originalError, NSHTTPURLResponse *response) diff --git a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIImage.h b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIImage.h index 017828dbca8a..360a609f7d33 100644 --- a/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIImage.h +++ b/packages/react-native/ReactApple/Libraries/RCTUIKit/RCTUIImage.h @@ -114,8 +114,16 @@ NS_INLINE NSImage *UIImageWithData(NSData *imageData) // MARK: - Image encoding (macOS only) #if TARGET_OS_OSX +#ifdef __cplusplus +extern "C" { +#endif + NSData *UIImagePNGRepresentation(NSImage *image); NSData *UIImageJPEGRepresentation(NSImage *image, CGFloat compressionQuality); + +#ifdef __cplusplus +} +#endif #endif NS_ASSUME_NONNULL_END