fix: implementation toDataURL for iOS platform both architectures (#2405)

# Summary
Closes #2233 
in iOS and old Arch, a callback on `toDataURL` method will only be
called the second time of asking.
Based on that
[PR](https://github.com/software-mansion/react-native-svg/pull/2234)
format `RNSVGSvgViewModule` file.

## Test Plan
We can easily test that fix by running the `Test2233`, we have an
example of the problem.

### What are the steps to reproduce (after prerequisites)?

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |          |
This commit is contained in:
Bohdan Artiukhov
2024-08-13 10:45:10 +02:00
committed by GitHub
parent 4320df270a
commit 3350ab442a
3 changed files with 76 additions and 43 deletions

View File

@@ -26,54 +26,47 @@ RCT_EXPORT_MODULE()
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback
attempt:(int)attempt attempt:(int)attempt
{ {
void (^block)(void) = ^{
#ifdef RCT_NEW_ARCH_ENABLED #ifdef RCT_NEW_ARCH_ENABLED
[self.viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) { [self.viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) {
__kindof RNSVGPlatformView *view = [viewRegistry viewForReactTag:reactTag]; __kindof RNSVGPlatformView *view = [viewRegistry viewForReactTag:reactTag];
#else #else
[self.bridge.uiManager [self.bridge.uiManager
addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, RNSVGPlatformView *> *viewRegistry) { addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, RNSVGPlatformView *> *viewRegistry) {
__kindof RNSVGPlatformView *view = [uiManager viewForReactTag:reactTag]; __kindof RNSVGPlatformView *view = [uiManager viewForReactTag:reactTag];
#endif // RCT_NEW_ARCH_ENABLED #endif // RCT_NEW_ARCH_ENABLED
NSString *b64; NSString *b64;
if ([view isKindOfClass:[RNSVGSvgView class]]) { if ([view isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView *svg = view; RNSVGSvgView *svg = view;
if (options == nil) { if (options == nil) {
b64 = [svg getDataURLWithBounds:svg.boundingBox]; b64 = [svg getDataURLWithBounds:svg.boundingBox];
} else { } else {
id width = [options objectForKey:@"width"]; id width = [options objectForKey:@"width"];
id height = [options objectForKey:@"height"]; id height = [options objectForKey:@"height"];
if (![width isKindOfClass:NSNumber.class] || ![height isKindOfClass:NSNumber.class]) { if (![width isKindOfClass:NSNumber.class] || ![height isKindOfClass:NSNumber.class]) {
RCTLogError(@"Invalid width or height given to toDataURL"); RCTLogError(@"Invalid width or height given to toDataURL");
return; return;
}
NSNumber *w = width;
NSInteger wi = (NSInteger)[w intValue];
NSNumber *h = height;
NSInteger hi = (NSInteger)[h intValue];
CGRect bounds = CGRectMake(0, 0, wi, hi);
b64 = [svg getDataURLWithBounds:bounds];
} }
} else { NSNumber *w = width;
RCTLogError(@"Invalid svg returned from registry, expecting RNSVGSvgView, got: %@", view); NSInteger wi = (NSInteger)[w intValue];
return; NSNumber *h = height;
NSInteger hi = (NSInteger)[h intValue];
CGRect bounds = CGRectMake(0, 0, wi, hi);
b64 = [svg getDataURLWithBounds:bounds];
} }
if (b64) { } else {
callback(@[ b64 ]); RCTLogError(@"Invalid svg returned from registry, expecting RNSVGSvgView, got: %@", view);
} else if (attempt < 1) { return;
[self toDataURL:reactTag options:options callback:callback attempt:(attempt + 1)]; }
} else { if (b64) {
callback(@[]); callback(@[ b64 ]);
} } else if (attempt < 1) {
}]; [self toDataURL:reactTag options:options callback:callback attempt:(attempt + 1)];
}; } else {
if (self.bridge) { callback(@[]);
dispatch_async(RCTGetUIManagerQueue(), block); }
} else { }];
dispatch_async(dispatch_get_main_queue(), block); };
}
}
RCT_EXPORT_METHOD(toDataURL RCT_EXPORT_METHOD(toDataURL
: (nonnull NSNumber *)reactTag options : (nonnull NSNumber *)reactTag options
@@ -91,4 +84,13 @@ RCT_EXPORT_METHOD(toDataURL
} }
#endif #endif
- (dispatch_queue_t)methodQueue
{
if (self.bridge) {
return RCTGetUIManagerQueue();
} else {
return dispatch_get_main_queue();
}
}
@end @end

View File

@@ -22,6 +22,7 @@ import Test2248 from './src/Test2248';
import Test2266 from './src/Test2266'; import Test2266 from './src/Test2266';
import Test2276 from './src/Test2276'; import Test2276 from './src/Test2276';
import Test2327 from './src/Test2327'; import Test2327 from './src/Test2327';
import Test2233 from './src/Test2233';
import Test2366 from './src/Test2366'; import Test2366 from './src/Test2366';
import Test2397 from './src/Test2397'; import Test2397 from './src/Test2397';

View File

@@ -0,0 +1,30 @@
import * as React from 'react';
import {Button, SafeAreaView, View} from 'react-native';
import Svg, {Path} from 'react-native-svg';
const SvgLogoWelcome = () => {
const ref = React.useRef<Svg | null>(null);
return (
<View>
<Button
onPress={() => {
ref.current?.toDataURL(base64Image => {
console.log(base64Image, 'data');
});
}}
title="log"
/>
<Svg ref={ref} viewBox="0 0 24 24" fill="black">
<Path d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10S2 17.514 2 12 6.486 2 12 2zm0-2C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.507 13.941c-1.512 1.195-3.174 1.931-5.506 1.931-2.334 0-3.996-.736-5.508-1.931L6 14.434C7.127 16.154 9.2 18 12.001 18c2.8 0 4.872-1.846 5.999-3.566l-.493-.493zM8.5 8a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm7 0a1.5 1.5 0 100 3 1.5 1.5 0 000-3z" />
</Svg>
</View>
);
};
export default function App() {
return (
<SafeAreaView>
<SvgLogoWelcome />
</SafeAreaView>
);
}