Skip to content

Commit 35839c9

Browse files
committed
Add the Demo code to test the iOS built-in support for SVG format
1 parent b075f78 commit 35839c9

File tree

4 files changed

+79
-14
lines changed

4 files changed

+79
-14
lines changed

Example/Podfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ PODS:
22
- CocoaLumberjack (3.5.3):
33
- CocoaLumberjack/Core (= 3.5.3)
44
- CocoaLumberjack/Core (3.5.3)
5-
- SDWebImage/Core (5.0.2)
6-
- SDWebImageSVGCoder (0.2.0):
5+
- SDWebImage/Core (5.0.6)
6+
- SDWebImageSVGCoder (0.3.0):
77
- SDWebImage/Core (~> 5.0)
88
- SVGKit (>= 2.1)
99
- SVGKit (2.1.0):
@@ -27,15 +27,15 @@ EXTERNAL SOURCES:
2727

2828
CHECKOUT OPTIONS:
2929
SVGKit:
30-
:commit: cf32da55633e370e66a7ba6e003224bd67296c16
30+
:commit: fc33a18a6d43042c2d389d4ab4a575e9c41a5bcf
3131
:git: https://github.com/SVGKit/SVGKit.git
3232

3333
SPEC CHECKSUMS:
3434
CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947
35-
SDWebImage: 6764b5fa0f73c203728052955dbefa2bf1f33282
36-
SDWebImageSVGCoder: 61f60a3064db079de646a34a5f5aa8d3ac258345
35+
SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965
36+
SDWebImageSVGCoder: 4b354bcdc7d74ce14d9fdb3c9ed9ab2c667f3b57
3737
SVGKit: 8a2fc74258bdb2abb54d3b65f3dd68b0277a9c4d
3838

3939
PODFILE CHECKSUM: 8107c7193dd0c4844a782937610f415caa6ef482
4040

41-
COCOAPODS: 1.6.1
41+
COCOAPODS: 1.7.1

Example/SDWebImageSVGCoder.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,6 @@
451451
buildActionMask = 2147483647;
452452
files = (
453453
);
454-
inputFileListPaths = (
455-
);
456454
inputPaths = (
457455
"${PODS_ROOT}/Target Support Files/Pods-SDWebImageSVGCoder_Example macOS/Pods-SDWebImageSVGCoder_Example macOS-frameworks.sh",
458456
"${BUILT_PRODUCTS_DIR}/CocoaLumberjack-macOS/CocoaLumberjack.framework",
@@ -461,8 +459,6 @@
461459
"${BUILT_PRODUCTS_DIR}/SVGKit-macOS/SVGKit.framework",
462460
);
463461
name = "[CP] Embed Pods Frameworks";
464-
outputFileListPaths = (
465-
);
466462
outputPaths = (
467463
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework",
468464
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",

Example/SDWebImageSVGCoder/SDViewController.m

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ - (void)viewDidLoad
2323

2424
SDImageSVGCoder *SVGCoder = [SDImageSVGCoder sharedCoder];
2525
[[SDImageCodersManager sharedManager] addCoder:SVGCoder];
26-
NSURL *svgURL = [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/1/14/Mahuri.svg"];
26+
NSURL *svgURL = [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/6/67/Firefox_Logo%2C_2017.svg"];
2727
NSURL *svgURL2 = [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2d/Sample_SVG_file%2C_signature.svg"];
2828
NSURL *svgURL3 = [NSURL URLWithString:@"https://simpleicons.org/icons/github.svg"];
2929

@@ -60,10 +60,17 @@ - (void)viewDidLoad
6060
NSLog(@"SVGKFastImageView SVG load success");
6161
}
6262
}];
63-
// For `UIImageView`, you can specify a desired SVG size instead of original SVG viewport (which may be small)
64-
[imageView3 sd_setImageWithURL:svgURL3 placeholderImage:nil options:SDWebImageRetryFailed context:@{SDWebImageContextSVGImageSize : @(CGSizeMake(100, 100))} progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
63+
// on iOS 13, UIImageView supports SVG vector scale. On iOS 12, this will fallback bitmap representation
64+
[imageView3 sd_setImageWithURL:svgURL3 placeholderImage:nil options:SDWebImageRetryFailed context:nil progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
6565
if (image) {
66-
NSLog(@"UIImageView SVG load success");
66+
NSLog(@"SVG load animation success");
67+
[UIView animateWithDuration:2 animations:^{
68+
imageView3.bounds = CGRectMake(0, 0, 300, 300);
69+
} completion:^(BOOL finished) {
70+
[UIView animateWithDuration:2 animations:^{
71+
imageView3.bounds = CGRectMake(0, 0, 100, 100);
72+
}];
73+
}];
6774
}
6875
}];
6976
}

SDWebImageSVGCoder/Classes/SDImageSVGCoder.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,25 @@
99
#import "SDSVGImage.h"
1010
#import "SDWebImageSVGCoderDefine.h"
1111
#import <SVGKit/SVGKit.h>
12+
#import <dlfcn.h>
1213

1314
#define kSVGTagEnd @"</svg>"
1415

16+
typedef struct CF_BRIDGED_TYPE(id) CGSVGDocument *CGSVGDocumentRef;
17+
static CGSVGDocumentRef (*CGSVGDocumentCreateFromDataProvider)(CGDataProviderRef provider, CFDictionaryRef options);
18+
static CGSVGDocumentRef (*CGSVGDocumentRetain)(CGSVGDocumentRef);
19+
static void (*CGSVGDocumentRelease)(CGSVGDocumentRef);
20+
21+
@interface UIImage (PrivateSVGSupport)
22+
23+
- (instancetype)_initWithCGSVGDocument:(CGSVGDocumentRef)document;
24+
- (instancetype)_initWithCGSVGDocument:(CGSVGDocumentRef)document scale:(double)scale orientation:(UIImageOrientation)orientation;
25+
+ (instancetype)_imageWithCGSVGDocument:(CGSVGDocumentRef)document;
26+
+ (instancetype)_imageWithCGSVGDocument:(CGSVGDocumentRef)document scale:(double)scale orientation:(UIImageOrientation)orientation;
27+
- (CGSVGDocumentRef)_CGSVGDocument;
28+
29+
@end
30+
1531
@implementation SDImageSVGCoder
1632

1733
+ (SDImageSVGCoder *)sharedCoder {
@@ -23,6 +39,12 @@ + (SDImageSVGCoder *)sharedCoder {
2339
return coder;
2440
}
2541

42+
+ (void)initialize {
43+
CGSVGDocumentCreateFromDataProvider = dlsym(RTLD_DEFAULT, "CGSVGDocumentCreateFromDataProvider");
44+
CGSVGDocumentRetain = dlsym(RTLD_DEFAULT, "CGSVGDocumentRetain");
45+
CGSVGDocumentRelease = dlsym(RTLD_DEFAULT, "CGSVGDocumentRelease");
46+
}
47+
2648
#pragma mark - Decode
2749

2850
- (BOOL)canDecodeFromData:(NSData *)data {
@@ -33,6 +55,32 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)
3355
if (!data) {
3456
return nil;
3557
}
58+
59+
if ([self.class supportsVectorSVGImage]) {
60+
return [self createVectorSVGWithData:data options:options];
61+
} else {
62+
return [self createBitmapSVGWithData:data options:options];
63+
}
64+
}
65+
66+
- (UIImage *)createVectorSVGWithData:(NSData *)data options:(SDImageCoderOptions *)options {
67+
NSParameterAssert(data);
68+
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
69+
if (!provider) {
70+
return nil;
71+
};
72+
CGSVGDocumentRef document = CGSVGDocumentCreateFromDataProvider(provider, NULL);
73+
if (!document) {
74+
return nil;
75+
}
76+
UIImage *image = [UIImage _imageWithCGSVGDocument:document];
77+
CGSVGDocumentRelease(document);
78+
79+
return image;
80+
}
81+
82+
- (UIImage *)createBitmapSVGWithData:(NSData *)data options:(SDImageCoderOptions *)options {
83+
NSParameterAssert(data);
3684
// Parse SVG
3785
SVGKImage *svgImage = [[SVGKImage alloc] initWithData:data];
3886
if (!svgImage) {
@@ -99,6 +147,20 @@ - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format o
99147

100148
#pragma mark - Helper
101149

150+
+ (BOOL)supportsVectorSVGImage {
151+
static dispatch_once_t onceToken;
152+
static BOOL supports;
153+
dispatch_once(&onceToken, ^{
154+
// iOS 11+ supports PDF built-in rendering, use selector to check is more accurate
155+
if ([UIImage respondsToSelector:@selector(_imageWithCGSVGDocument:)]) {
156+
supports = YES;
157+
} else {
158+
supports = NO;
159+
}
160+
});
161+
return supports;
162+
}
163+
102164
+ (BOOL)isSVGFormatForData:(NSData *)data {
103165
if (!data) {
104166
return NO;

0 commit comments

Comments
 (0)