/
pxSVGLayer.m
126 lines (113 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// pxSVGLayer.m
// pxSVG
//
// Created by Yury Popov on 12 мая.
// Copyright (c) 2015 PhoeniX. All rights reserved.
//
#import "pxSVGLayer.h"
#import "pxSVGImage.h"
@interface pxSVGLayer ()
@property NSOperation *loadOperation;
@property NSOperation *parseOperation;
15
@property CGRect contentRect;
16
17
18
19
20
21
22
23
24
25
@end
@implementation pxSVGLayer
+ (NSOperationQueue*)loadQueue
{
static NSOperationQueue *lq;
if (!lq) {
lq = [NSOperationQueue new];
lq.name = @"pxSVG Load queue";
26
[lq setMaxConcurrentOperationCount:10];
27
28
29
30
31
32
33
34
35
36
}
return lq;
}
+ (NSOperationQueue*)parseQueue
{
static NSOperationQueue *pq;
if (!pq) {
pq = [NSOperationQueue new];
pq.name = @"pxSVG Parser queue";
37
[pq setMaxConcurrentOperationCount:10];
38
39
40
41
42
43
44
45
46
47
48
49
50
51
}
return pq;
}
- (void)dealloc
{
if (self.loadOperation) [self.loadOperation cancel];
if (self.parseOperation) [self.parseOperation cancel];
}
- (void)loadURL:(NSURL *)url
{
[self clean];
__weak pxSVGLayer *weakself = self;
52
__block NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
53
54
55
56
57
58
59
60
61
NSURLResponse *resp;
NSError *err;
NSData *data;
data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval:30] returningResponse:&resp error:&err];
if ([op isCancelled]) return;
NSString *str = data?[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]:nil;
NSBlockOperation *sync = [NSBlockOperation blockOperationWithBlock:^{
if ([op isCancelled]) return;
if (!weakself) return;
62
weakself.loadOperation = nil;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
NSError *error = err;
if (!error && [resp isKindOfClass:[NSHTTPURLResponse class]] && (((NSHTTPURLResponse*)resp).statusCode != 200))
error = [NSError errorWithDomain:@"pxSVGLoader.httpStatus" code:((NSHTTPURLResponse*)resp).statusCode userInfo:nil];
if (!error && !str)
error = [NSError errorWithDomain:@"pxSVGLoader.emptyData" code:0 userInfo:nil];
if (error) return [weakself loadError:error];
[weakself loadString:str];
}];
[[NSOperationQueue mainQueue] addOperations:@[sync] waitUntilFinished:YES];
}];
op.name = url.absoluteString;
op.threadPriority = 0.1f;
[[self.class loadQueue] addOperation:self.loadOperation=op];
}
- (void)loadData:(NSData *)data
{
[self loadString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]];
}
- (void)loadString:(NSString *)string
{
[self clean];
__weak pxSVGLayer *weakself = self;
87
__block NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
88
89
90
91
pxSVGImage *img = [pxSVGImage svgImageWithXML:string];
if ([op isCancelled]) return;
NSBlockOperation *sync = [NSBlockOperation blockOperationWithBlock:^{
if ([op isCancelled]) return;
92
93
if (!weakself) return;
weakself.parseOperation = nil;
94
if (!img) return [weakself loadError:[NSError errorWithDomain:@"pxSVGParser.parseError" code:0 userInfo:nil]];
95
[weakself loadImage:img];
96
97
98
99
100
101
102
}];
[[NSOperationQueue mainQueue] addOperations:@[sync] waitUntilFinished:YES];
}];
op.threadPriority = 0.1f;
[[self.class parseQueue] addOperation:self.parseOperation=op];
}
103
104
105
106
- (void)loadImage:(pxSVGImage*)image
{
[self clean];
[self addSublayer:[image makeLayer]];
107
self.contentRect = image.bounds;
108
109
110
111
if ([self.svgDelegate respondsToSelector:@selector(svgLayerDidLoadImage:)])
[self.svgDelegate svgLayerDidLoadImage:self];
}
112
113
114
115
116
117
118
119
120
121
- (void)loadError:(NSError *)error
{
if ([self.svgDelegate respondsToSelector:@selector(svgLayer:didFailedLoad:)])
[self.svgDelegate svgLayer:self didFailedLoad:error];
}
- (void)clean
{
if (self.loadOperation) [self.loadOperation cancel];
if (self.parseOperation) [self.parseOperation cancel];
122
while (self.sublayers.count) [self.sublayers.firstObject removeFromSuperlayer];
123
self.contentRect = CGRectZero;
124
125
126
}
@end