Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added Pie Progress Indicator

  • Loading branch information...
commit d7293c386ba4f8621791f29d1a217603bd26cb32 1 parent 9f9da74
Oliver Drobnik authored May 21, 2012
30  Core/Source/DTDownload.h
... ...
@@ -1,15 +1,24 @@
1 1
 //
2  
-//  CatalogDownloader.h
3  
-//  iCatalog
  2
+//  DTDownload.h
  3
+//  DTFoundation
4 4
 //
5 5
 //  Created by Oliver Drobnik on 8/6/10.
6 6
 //  Copyright 2010 Drobnik.com. All rights reserved.
7 7
 //
8 8
 
9  
-#import <Foundation/Foundation.h>
  9
+// notifications
  10
+extern NSString * const DTDownloadProgressNotification;
  11
+
10 12
 
11 13
 @class DTDownload;
12 14
 
  15
+// block-based response handler, called after headers were received
  16
+typedef void (^DTDownloadResponseHandler)(DTDownload *, NSDictionary *headers);
  17
+
  18
+// block-based completion handler, called once the download has finished
  19
+typedef void (^DTDownloadCompletionHandler)(DTDownload *);
  20
+
  21
+
13 22
 /**
14 23
  Methods that a delegate of a download object is being queried with.
15 24
  */
@@ -150,4 +159,19 @@
150 159
 
151 160
 - (BOOL)isLoading;
152 161
 
  162
+/**-------------------------------------------------------------------------------------
  163
+ @name Block Handlers
  164
+ ---------------------------------------------------------------------------------------
  165
+ */
  166
+
  167
+/**
  168
+ Sets the block to execute as soon as the HTTP response has been received.
  169
+ */
  170
+@property (nonatomic, copy) DTDownloadResponseHandler responseHandler;
  171
+
  172
+/**
  173
+ Sets the block to execute as soon as the download has completed.
  174
+ */
  175
+@property (nonatomic, copy) DTDownloadCompletionHandler completionHandler;
  176
+
153 177
 @end
60  Core/Source/DTDownload.m
@@ -9,6 +9,8 @@
9 9
 #import "DTDownload.h"
10 10
 #import "NSString+DTUtilities.h"
11 11
 
  12
+NSString * const DTDownloadProgressNotification = @"DTDownloadProgressNotification";
  13
+
12 14
 @interface DTDownload ()
13 15
 
14 16
 @property (nonatomic, retain) NSString *internalDownloadFolder;
@@ -50,6 +52,9 @@ @implementation DTDownload
50 52
 	BOOL headOnly;
51 53
 	
52 54
 	BOOL _isLoading;
  55
+	
  56
+	// response handlers
  57
+	DTDownloadResponseHandler _responseHandler;
53 58
 }
54 59
 
55 60
 #pragma mark Downloading
@@ -97,7 +102,7 @@ - (void)startWithResume:(BOOL)shouldResume
97 102
 {
98 103
 	_isLoading = YES;
99 104
 	
100  
-	NSString *fileName = [[_URL absoluteString] md5Checksum];
  105
+	NSString *fileName = [[_URL path] lastPathComponent];
101 106
 	self.internalDownloadFolder = [[self.folderForDownloading stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:@"download"];
102 107
 	
103 108
 	receivedDataFilePath = [internalDownloadFolder stringByAppendingPathComponent:fileName];
@@ -120,9 +125,6 @@ - (void)startWithResume:(BOOL)shouldResume
120 125
 			downloadEntryIdentifier = [NSString stringWithUUID];
121 126
 		}
122 127
 		
123  
-		downloadEntityTag = [resumeInfo objectForKey:@"NSURLDownloadEntityTag"];
124  
-		
125  
-		
126 128
 		if ([delegate respondsToSelector:@selector(shouldResumeDownload:)])
127 129
 		{
128 130
 			if (!shouldResume || ![delegate shouldResumeDownload:self])
@@ -140,6 +142,9 @@ - (void)startWithResume:(BOOL)shouldResume
140 142
 		
141 143
 		if (shouldResume)
142 144
 		{
  145
+			downloadEntityTag = [resumeInfo objectForKey:@"NSURLDownloadEntityTag"];
  146
+
  147
+			
143 148
 			// here we assume we should continue download
144 149
 			receivedDataFile = [NSFileHandle fileHandleForWritingAtPath:receivedDataFilePath];
145 150
 			[receivedDataFile seekToEndOfFile];
@@ -170,20 +175,27 @@ - (void)startWithResume:(BOOL)shouldResume
170 175
 			{
171 176
 				if (receivedBytes && receivedBytes == _totalBytes)
172 177
 				{
173  
-					NSLog(@"Already done!");
174  
-					
  178
+					// Already done!
175 179
 					[self _completeDownload];
176 180
 					return;
177 181
 				}
178 182
 			}
179 183
 		}
  184
+		else 
  185
+		{
  186
+			// reset
  187
+			receivedBytes = 0;
  188
+			_totalBytes = 0;
  189
+			downloadEntityTag = nil;
  190
+			lastModifiedDate = nil;
  191
+		}
180 192
 	}
181 193
 	else 
182 194
 	{
183 195
 		// create download folder
184 196
 		NSError *error = nil;
185 197
 		
186  
-		if (![[NSFileManager defaultManager] createDirectoryAtPath:internalDownloadFolder withIntermediateDirectories:NO attributes:nil error:&error])
  198
+		if (![[NSFileManager defaultManager] createDirectoryAtPath:internalDownloadFolder withIntermediateDirectories:YES attributes:nil error:&error])
187 199
 		{
188 200
 			NSLog(@"Cannot create download folder %@, %@", internalDownloadFolder, [error localizedDescription]);
189 201
 			return;
@@ -192,8 +204,6 @@ - (void)startWithResume:(BOOL)shouldResume
192 204
 		downloadEntryIdentifier = [NSString stringWithUUID];
193 205
 	}
194 206
 	
195  
-	
196  
-	
197 207
 	NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:_URL
198 208
 														 cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
199 209
 													 timeoutInterval:60.0];
@@ -268,6 +278,11 @@ - (void)_completeDownload
268 278
 	{
269 279
 		[delegate download:self didFinishWithFile:targetPath];
270 280
 	}
  281
+	
  282
+	if (_completionHandler)
  283
+	{
  284
+		_completionHandler(self);
  285
+	}
271 286
 }
272 287
 
273 288
 - (void)_updateDownloadInfo
@@ -359,8 +374,6 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon
359 374
 			}
360 375
 		}
361 376
 		
362  
-		
363  
-		
364 377
 		// get something to identify file
365 378
 		NSString *modified = [http.allHeaderFields objectForKey:@"Last-Modified"];
366 379
 		if (modified) 
@@ -373,6 +386,10 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon
373 386
 			lastModifiedDate = [dateFormatter dateFromString:modified];
374 387
 		}
375 388
 		
  389
+		if (_responseHandler)
  390
+		{
  391
+			_responseHandler(self, [http allHeaderFields]);
  392
+		}
376 393
 	}
377 394
 	else 
378 395
 	{
@@ -415,20 +432,27 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
415 432
 	
416 433
 	self.lastPaketTimestamp = now;
417 434
 	
418  
-	
419 435
 	// notify delegate
420 436
 	if ([delegate respondsToSelector:@selector(download:downloadedBytes:ofTotalBytes:withSpeed:)])
421 437
 	{
422 438
 		[delegate download:self downloadedBytes:receivedBytes ofTotalBytes:_totalBytes withSpeed:downloadSpeed];
423 439
 	}
  440
+	
  441
+	// send notification
  442
+	if (_totalBytes)
  443
+	{
  444
+		NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:(float)receivedBytes / (float)_totalBytes] forKey:@"ProgressPercent"];
  445
+		[[NSNotificationCenter defaultCenter] postNotificationName:DTDownloadProgressNotification object:self userInfo:userInfo];
  446
+	}
424 447
 }
425 448
 
426  
-
427 449
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
428 450
 {
429 451
 	receivedData = nil;
430 452
 	urlConnection = nil;
431  
-	
  453
+
  454
+	_isLoading = NO;
  455
+
432 456
 	[receivedDataFile closeFile];
433 457
 	
434 458
 	if (headOnly)
@@ -442,8 +466,6 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection
442 466
 	{
443 467
 		[self _completeDownload];
444 468
 	}
445  
-	
446  
-	_isLoading = NO;
447 469
 }
448 470
 
449 471
 #pragma mark Notifications
@@ -457,7 +479,9 @@ - (NSString *)folderForDownloading
457 479
 {
458 480
 	if (!folderForDownloading)
459 481
 	{
460  
-		self.folderForDownloading = NSTemporaryDirectory();
  482
+		NSString *md5 = [[_URL absoluteString] md5Checksum];
  483
+		
  484
+		self.folderForDownloading = [NSTemporaryDirectory() stringByAppendingPathComponent:md5];
461 485
 	}
462 486
 	
463 487
 	return folderForDownloading;
@@ -472,6 +496,8 @@ - (BOOL)isLoading
472 496
 @synthesize MIMEType = _MIMEType;
473 497
 @synthesize totalBytes = _totalBytes;
474 498
 @synthesize context;
  499
+@synthesize responseHandler = _responseHandler;
  500
+@synthesize completionHandler = _completionHandler;
475 501
 
476 502
 
477 503
 @end
18  Core/Source/DTDownloadCache.h
@@ -10,6 +10,16 @@
10 10
 
11 11
 extern NSString *DTDownloadCacheDidCacheFileNotification;
12 12
 
  13
+
  14
+enum {
  15
+    DTDownloadCacheOptionNeverLoad = 0,
  16
+    DTDownloadCacheOptionLoadIfNotCached,
  17
+    DTDownloadCacheOptionReturnCacheAndLoadAlways,
  18
+    DTDownloadCacheOptionReturnCacheAndLoadIfChanged,
  19
+};
  20
+typedef NSUInteger DTDownloadCacheOption;
  21
+
  22
+
13 23
 @interface DTDownloadCache : NSObject <DTDownloadDelegate>
14 24
 
15 25
 /**
@@ -20,10 +30,10 @@ extern NSString *DTDownloadCacheDidCacheFileNotification;
20 30
 
21 31
 /**
22 32
  @param URL The URL of the file
23  
- @param shouldLoad If the data should be loaded from the web in case it is not cached already.
  33
+ @param option A loading option to specify wheter the file should be loaded if it is already cached.
24 34
  @returns The cached image or `nil` if none is cached.
25 35
  */
26  
-- (NSData *)cachedDataForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad;
  36
+- (NSData *)cachedDataForURL:(NSURL *)URL option:(DTDownloadCacheOption)option;
27 37
 
28 38
 /**
29 39
  current sum of cached files in Bytes
@@ -52,9 +62,9 @@ extern NSString *DTDownloadCacheDidCacheFileNotification;
52 62
 /**
53 63
  Specialized method for retrieving cached images.
54 64
  @param URL The URL of the image
55  
- @param shouldLoad If the image should be loaded from the web in case it is not cached already.
  65
+ @param option A loading option to specify wheter the file should be loaded if it is already cached.
56 66
  @returns The cached image or `nil` if none is cached.
57 67
  */
58  
-- (UIImage *)cachedImageForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad;
  68
+- (UIImage *)cachedImageForURL:(NSURL *)URL option:(DTDownloadCacheOption)option;
59 69
 
60 70
 @end
106  Core/Source/DTDownloadCache.m
@@ -15,6 +15,7 @@
15 15
 
16 16
 #import <ImageIO/CGImageSource.h>
17 17
 #import "NSString+DTFormatNumbers.h"
  18
+#import "DTAsyncFileDeleter.h"
18 19
 
19 20
 NSString *DTDownloadCacheDidCacheFileNotification = @"DTDownloadCacheDidCacheFile";
20 21
 
@@ -86,11 +87,51 @@ - (id)init
86 87
 
87 88
 #pragma mark Queue Handling
88 89
 
89  
-- (void)_enqueueDownloadForURL:(NSURL *)URL
  90
+- (void)_enqueueDownloadForURL:(NSURL *)URL option:(DTDownloadCacheOption)option
90 91
 {
91 92
 	DTDownload *download = [[DTDownload alloc] initWithURL:URL];
92 93
 	download.delegate = self;
93 94
 	
  95
+	if (option == DTDownloadCacheOptionReturnCacheAndLoadIfChanged)
  96
+	{
  97
+		DTCachedFile *cachedFile = [self _cachedFileForURL:URL inContext:_managedObjectContext];
  98
+		
  99
+		if (cachedFile)
  100
+		{
  101
+			NSString *cachedETag = cachedFile.entityTagIdentifier;
  102
+			NSDate *lastModifiedDate = cachedFile.lastModifiedDate;
  103
+			
  104
+			__weak DTDownloadCache *weakself = self;
  105
+			
  106
+			download.responseHandler = ^(DTDownload *download, NSDictionary *headers) {
  107
+				BOOL shouldCancel = NO;
  108
+				
  109
+				if (cachedETag)
  110
+				{
  111
+					if ([download.downloadEntityTag isEqualToString:cachedETag])
  112
+					{
  113
+						shouldCancel = YES;
  114
+					}
  115
+				}
  116
+				
  117
+				if (lastModifiedDate)
  118
+				{
  119
+					if ([download.lastModifiedDate isEqualToDate:lastModifiedDate])
  120
+					{
  121
+						shouldCancel = YES;
  122
+					}
  123
+				}
  124
+				
  125
+				if (shouldCancel)
  126
+				{
  127
+					[download cancel];
  128
+					[weakself _removeDownloadFromQueue:download];
  129
+				}
  130
+			};
  131
+		}
  132
+	}
  133
+		
  134
+	
94 135
 	[_downloads setObject:download forKey:URL];
95 136
 	[_downloadQueue addObject:download];
96 137
 }
@@ -125,7 +166,7 @@ - (void)_startNextQueuedDownload
125 166
 #pragma mark External Methods
126 167
 
127 168
 
128  
-- (NSData *)cachedDataForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad
  169
+- (NSData *)cachedDataForURL:(NSURL *)URL option:(DTDownloadCacheOption)option
129 170
 {
130 171
 	// TODO: make this thread-safe so it can be called from background threads
131 172
 	if (dispatch_get_current_queue() != dispatch_get_main_queue())
@@ -133,25 +174,40 @@ - (NSData *)cachedDataForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad
133 174
 		__block NSData *retData;
134 175
 		
135 176
 		dispatch_sync(dispatch_get_main_queue(), ^{
136  
-			retData = [self cachedDataForURL:URL shouldLoad:shouldLoad];
  177
+			retData = [self cachedDataForURL:URL option:option];
137 178
 		});
138 179
 		
139 180
 		return retData;
140 181
 	}
141 182
 	
  183
+	NSData *retData = nil;
  184
+	
142 185
 	DTCachedFile *existingCacheEntry = [self _cachedFileForURL:URL inContext:_managedObjectContext];
143 186
 	
144 187
 	if (existingCacheEntry)
145 188
 	{
146  
-		existingCacheEntry.lastAccessDate = [NSDate date];
  189
+		retData = existingCacheEntry.fileData;
  190
+
  191
+		if (option == DTDownloadCacheOptionReturnCacheAndLoadAlways)
  192
+		{
  193
+			[_managedObjectContext deleteObject:existingCacheEntry];
  194
+		}
  195
+		else 
  196
+		{
  197
+			existingCacheEntry.lastAccessDate = [NSDate date];
  198
+		}
  199
+
147 200
 		[self _commitContext:_managedObjectContext];
148  
-		
149  
-		return existingCacheEntry.fileData;
  201
+	}
  202
+
  203
+	if (option == DTDownloadCacheOptionNeverLoad)
  204
+	{
  205
+		return retData;
150 206
 	}
151 207
 	
152  
-	if (!shouldLoad)
  208
+	if (retData && option == DTDownloadCacheOptionLoadIfNotCached)
153 209
 	{
154  
-		return nil;
  210
+		return retData;
155 211
 	}
156 212
 	
157 213
 	// we don't have a cache entry, need to load
@@ -171,10 +227,10 @@ - (NSData *)cachedDataForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad
171 227
 		return nil;
172 228
 	}
173 229
 	
174  
-	[self _enqueueDownloadForURL:URL];
  230
+	[self _enqueueDownloadForURL:URL option:option];
175 231
 	[self _startNextQueuedDownload];
176 232
 	
177  
-	return nil;
  233
+	return retData;
178 234
 }
179 235
 
180 236
 - (NSUInteger)currentDiskUsage
@@ -198,8 +254,16 @@ - (void)download:(DTDownload *)download didFinishWithFile:(NSString *)path
198 254
 		NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] init];
199 255
 		tmpContext.persistentStoreCoordinator = _persistentStoreCoordinator;
200 256
 		
201  
-		DTCachedFile *cachedFile = (DTCachedFile *)[NSEntityDescription insertNewObjectForEntityForName:@"DTCachedFile" 
202  
-																				 inManagedObjectContext:tmpContext];	
  257
+		
  258
+		// check if URL already exists
  259
+		DTCachedFile *cachedFile = [self _cachedFileForURL:download.URL inContext:tmpContext];
  260
+		
  261
+		if (!cachedFile)
  262
+		{
  263
+			// create a new entity
  264
+			cachedFile = (DTCachedFile *)[NSEntityDescription insertNewObjectForEntityForName:@"DTCachedFile" inManagedObjectContext:tmpContext];
  265
+		}
  266
+		
203 267
 		cachedFile.lastAccessDate = [NSDate date];
204 268
 		cachedFile.expirationDate = [NSDate distantFuture];
205 269
 		cachedFile.lastModifiedDate = download.lastModifiedDate;
@@ -214,6 +278,9 @@ - (void)download:(DTDownload *)download didFinishWithFile:(NSString *)path
214 278
 		
215 279
 		dispatch_sync(dispatch_get_main_queue(), ^{
216 280
 			[[NSNotificationCenter defaultCenter] postNotificationName:DTDownloadCacheDidCacheFileNotification object:download.URL];
  281
+			
  282
+			// we transfered the file into the database, so we don't need it any more
  283
+			[[DTAsyncFileDeleter sharedInstance] removeItemAtPath:path];
217 284
 		});
218 285
 	});
219 286
 	
@@ -527,7 +594,7 @@ @implementation DTDownloadCache (Images)
527 594
 
528 595
 //TODO: make this thread-safe to be called from background threads
529 596
 
530  
-- (UIImage *)cachedImageForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad
  597
+- (UIImage *)cachedImageForURL:(NSURL *)URL option:(DTDownloadCacheOption)option
531 598
 {
532 599
 	// try memory cache first
533 600
 	UIImage *cachedImage = [_memoryCache objectForKey:URL];
@@ -538,24 +605,13 @@ - (UIImage *)cachedImageForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad
538 605
 	}
539 606
 
540 607
 	// try file cache
541  
-	NSData *data = [self cachedDataForURL:URL shouldLoad:shouldLoad];
  608
+	NSData *data = [self cachedDataForURL:URL option:option];
542 609
 	
543 610
 	if (!data)
544 611
 	{
545 612
 		return nil;
546 613
 	}
547 614
 	
548  
-//	// use ImageIO to make sure it stays cached
549  
-//	NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
550  
-//													 forKey:(id)kCGImageSourceShouldCache];
551  
-//	
552  
-//	CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
553  
-//	CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)dict);
554  
-//	
555  
-//	cachedImage = [UIImage imageWithCGImage:cgImage];
556  
-//	CGImageRelease(cgImage);
557  
-//	CFRelease(source);
558  
-	
559 615
 	cachedImage = [UIImage imageWithData:data];
560 616
 	
561 617
 	if (!cachedImage)
18  Core/Source/DTPieProgressIndicator.h
... ...
@@ -0,0 +1,18 @@
  1
+//
  2
+//  DTPieProgressIndicator.h
  3
+//  DTFoundation
  4
+//
  5
+//  Created by Oliver Drobnik on 16.05.12.
  6
+//  Copyright (c) 2012 Cocoanetics. All rights reserved.
  7
+//
  8
+
  9
+@interface DTPieProgressIndicator : UIView
  10
+
  11
+@property (nonatomic, assign) CGFloat progressPercent;
  12
+@property (nonatomic, strong) UIColor *color;
  13
+
  14
++ (DTPieProgressIndicator *)pieProgressIndicator;
  15
+
  16
+
  17
+
  18
+@end
105  Core/Source/DTPieProgressIndicator.m
... ...
@@ -0,0 +1,105 @@
  1
+//
  2
+//  DTPieProgressIndicator.m
  3
+//  DTFoundation
  4
+//
  5
+//  Created by Oliver Drobnik on 16.05.12.
  6
+//  Copyright (c) 2012 Cocoanetics. All rights reserved.
  7
+//
  8
+
  9
+#import "DTPieProgressIndicator.h"
  10
+
  11
+#define PIE_SIZE 34.0f
  12
+
  13
+@implementation DTPieProgressIndicator
  14
+{
  15
+	CGFloat _progressPercent;
  16
+	UIColor *_color;
  17
+}
  18
+
  19
++ (DTPieProgressIndicator *)pieProgressIndicator
  20
+{
  21
+	return [[DTPieProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, PIE_SIZE, PIE_SIZE)];
  22
+}
  23
+
  24
+- (id)initWithFrame:(CGRect)frame
  25
+{
  26
+	self = [super initWithFrame:frame];
  27
+	if (self) 
  28
+	{
  29
+		self.contentMode = UIViewContentModeRedraw;
  30
+		self.backgroundColor = [UIColor clearColor];
  31
+	}
  32
+	return self;
  33
+}
  34
+
  35
+
  36
+// Only override drawRect: if you perform custom drawing.
  37
+// An empty implementation adversely affects performance during animation.
  38
+- (void)drawRect:(CGRect)rect
  39
+{
  40
+	// Drawing code
  41
+	CGContextRef ctx = UIGraphicsGetCurrentContext();
  42
+	
  43
+	if (_color)
  44
+	{
  45
+		[_color set];
  46
+	}
  47
+	else 
  48
+	{
  49
+		[[UIColor whiteColor] set];
  50
+	}
  51
+	
  52
+	CGContextSetShadowWithColor(ctx, CGSizeMake(0, 1), 1, [UIColor blackColor].CGColor);
  53
+	CGContextBeginTransparencyLayer(ctx, NULL);
  54
+	
  55
+	CGFloat smallerDimension = MIN(self.bounds.size.width-6.0f, self.bounds.size.height-6.0f);
  56
+	CGRect drawRect =  CGRectMake(roundf(CGRectGetMidX(self.bounds)-smallerDimension/2.0f), roundf(CGRectGetMidY(self.bounds)-smallerDimension/2.0f), smallerDimension, smallerDimension);
  57
+	
  58
+	CGContextSetLineWidth(ctx, 3.0f);
  59
+	CGContextStrokeEllipseInRect(ctx, drawRect);
  60
+	
  61
+	// enough percent to draw
  62
+	if (_progressPercent > 0.1f)
  63
+	{
  64
+		CGPoint center = CGPointMake(CGRectGetMidX(drawRect), CGRectGetMidY(drawRect));
  65
+		CGFloat radius = center.x - drawRect.origin.x;
  66
+		CGFloat angle = _progressPercent * 2.0f * M_PI;
  67
+		
  68
+		CGContextMoveToPoint(ctx, center.x, center.y);
  69
+		//CGContextAddLineToPoint(ctx, center.x, drawRect.origin.y);
  70
+		CGContextAddArc(ctx, center.x, center.y, radius, -M_PI_2, angle-M_PI_2, 0);
  71
+		CGContextAddLineToPoint(ctx, center.x, center.y);
  72
+		
  73
+		CGContextFillPath(ctx);
  74
+	}
  75
+	
  76
+	CGContextEndTransparencyLayer(ctx);
  77
+}
  78
+
  79
+
  80
+#pragma mark Properties
  81
+
  82
+- (void)setProgressPercent:(CGFloat)progressPercent
  83
+{
  84
+	if (_progressPercent != progressPercent)
  85
+	{
  86
+		_progressPercent = progressPercent;
  87
+		
  88
+		[self setNeedsDisplay];
  89
+	}
  90
+}
  91
+
  92
+- (void)setColor:(UIColor *)color
  93
+{
  94
+	if (_color != color)
  95
+	{
  96
+		_color = color;
  97
+		
  98
+		[self setNeedsDisplay];
  99
+	}
  100
+}
  101
+
  102
+@synthesize progressPercent = _progressPercent;
  103
+@synthesize color = _color;
  104
+
  105
+@end
13  Core/Source/DTSmartPagingScrollView.m
@@ -210,8 +210,21 @@ - (void)reloadData
210 210
     {
211 211
         return;
212 212
     }
  213
+
  214
+    // clean up
  215
+    for (UIView *oneView in _visiblePageViews)
  216
+    {
  217
+        [oneView removeFromSuperview];
  218
+    }
213 219
     
  220
+    [_visiblePageViews removeAllObjects];
  221
+    [_viewsByPage removeAllObjects];
  222
+    
  223
+    // load
214 224
     _numberOfPages = [_pageDatasource numberOfPagesInSmartPagingScrollView:self];
  225
+    
  226
+    // make sure we stay in valid range
  227
+    _currentPageIndex = MAX(0, MIN(_currentPageIndex, _numberOfPages-1));
215 228
 
216 229
     [self setNeedsLayout];
217 230
 }
11  Core/Source/NSDictionary+DTError.m
@@ -16,11 +16,10 @@ + (NSDictionary *)dictionaryWithContentsOfURL:(NSURL *)URL error:(NSError **)err
16 16
 	CFPropertyListRef propertyList;
17 17
 	CFStringRef       errorString;
18 18
 	CFDataRef         resourceData;
19  
-	Boolean           status;
20 19
 	SInt32            errorCode;
21 20
 	
22 21
 	// Read the XML file.
23  
-	status = CFURLCreateDataAndPropertiesFromResource(
  22
+	CFURLCreateDataAndPropertiesFromResource(
24 23
 													  kCFAllocatorDefault,
25 24
 													  (__bridge CFURLRef)URL,
26 25
 													  &resourceData,            // place to put file data
@@ -40,7 +39,6 @@ + (NSDictionary *)dictionaryWithContentsOfURL:(NSURL *)URL error:(NSError **)err
40 39
 	if (resourceData) 
41 40
 	{
42 41
 		readDictionary = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)propertyList];
43  
-		CFRelease(propertyList);
44 42
 		CFRelease( resourceData );
45 43
 	}
46 44
 	else 
@@ -61,6 +59,11 @@ + (NSDictionary *)dictionaryWithContentsOfURL:(NSURL *)URL error:(NSError **)err
61 59
 		}
62 60
 	}
63 61
 	
  62
+	if (propertyList)
  63
+	{
  64
+		CFRelease(propertyList);
  65
+	}
  66
+	
64 67
 	return readDictionary;
65 68
 }
66 69
 
@@ -87,7 +90,7 @@ + (NSDictionary *)dictionaryWithContentsOfData:(NSData *)data error:(NSError **)
87 90
 	// we check if it is the correct type and only return it if it is
88 91
 	if ([(__bridge id)plist isKindOfClass:[NSDictionary class]])
89 92
 	{
90  
-		return (__bridge NSDictionary *)plist;
  93
+		return (__bridge_transfer NSDictionary *)plist;
91 94
 	}
92 95
 	else
93 96
 	{
106  DTFoundation.xcodeproj/project.pbxproj
@@ -41,16 +41,16 @@
41 41
 		A70B4CF5148663A800873A4A /* NSURL+DTPrefLinks.h in Headers */ = {isa = PBXBuildFile; fileRef = A70B4CCE1486621B00873A4A /* NSURL+DTPrefLinks.h */; settings = {ATTRIBUTES = (Public, ); }; };
42 42
 		A70B4CF6148663A800873A4A /* LoadableCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = A70B4CC91486621B00873A4A /* LoadableCategory.h */; settings = {ATTRIBUTES = (Public, ); }; };
43 43
 		A70B4CF7148663AF00873A4A /* DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A70B4CC51486621B00873A4A /* DTFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
44  
-		A7200ACB150917FD00D81719 /* UIImage+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A7200AC9150917FD00D81719 /* UIImage+DTFoundation.h */; };
45  
-		A7200ACC150917FD00D81719 /* UIImage+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A7200AC9150917FD00D81719 /* UIImage+DTFoundation.h */; };
  44
+		A7200ACB150917FD00D81719 /* UIImage+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A7200AC9150917FD00D81719 /* UIImage+DTFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
  45
+		A7200ACC150917FD00D81719 /* UIImage+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A7200AC9150917FD00D81719 /* UIImage+DTFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
46 46
 		A7200ACD150917FD00D81719 /* UIImage+DTFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = A7200ACA150917FD00D81719 /* UIImage+DTFoundation.m */; };
47 47
 		A7200ACE150917FD00D81719 /* UIImage+DTFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = A7200ACA150917FD00D81719 /* UIImage+DTFoundation.m */; };
48  
-		A72C110514A4946800F4EF69 /* UIView+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A72C110314A4946800F4EF69 /* UIView+DTFoundation.h */; };
49  
-		A72C110614A4946800F4EF69 /* UIView+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A72C110314A4946800F4EF69 /* UIView+DTFoundation.h */; };
  48
+		A72C110514A4946800F4EF69 /* UIView+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A72C110314A4946800F4EF69 /* UIView+DTFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
  49
+		A72C110614A4946800F4EF69 /* UIView+DTFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = A72C110314A4946800F4EF69 /* UIView+DTFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
50 50
 		A72C110714A4946800F4EF69 /* UIView+DTFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = A72C110414A4946800F4EF69 /* UIView+DTFoundation.m */; };
51 51
 		A72C110814A4946800F4EF69 /* UIView+DTFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = A72C110414A4946800F4EF69 /* UIView+DTFoundation.m */; };
52  
-		A73D5BAB155271FD0024BDB7 /* NSArray+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A73D5BA9155271FD0024BDB7 /* NSArray+DTError.h */; };
53  
-		A73D5BAC155271FD0024BDB7 /* NSArray+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A73D5BA9155271FD0024BDB7 /* NSArray+DTError.h */; };
  52
+		A73D5BAB155271FD0024BDB7 /* NSArray+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A73D5BA9155271FD0024BDB7 /* NSArray+DTError.h */; settings = {ATTRIBUTES = (Public, ); }; };
  53
+		A73D5BAC155271FD0024BDB7 /* NSArray+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A73D5BA9155271FD0024BDB7 /* NSArray+DTError.h */; settings = {ATTRIBUTES = (Public, ); }; };
54 54
 		A73D5BAD155271FD0024BDB7 /* NSArray+DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = A73D5BAA155271FD0024BDB7 /* NSArray+DTError.m */; };
55 55
 		A73D5BAE155271FD0024BDB7 /* NSArray+DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = A73D5BAA155271FD0024BDB7 /* NSArray+DTError.m */; };
56 56
 		A7494DFB15418B3100BDDB7D /* DTDownloadCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A7494DF915418B3100BDDB7D /* DTDownloadCache.h */; };
@@ -62,15 +62,15 @@
62 62
 		A7494E55154190F500BDDB7D /* DTCachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = A7494E52154190F500BDDB7D /* DTCachedFile.m */; };
63 63
 		A7494E56154190F500BDDB7D /* DTCachedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = A7494E52154190F500BDDB7D /* DTCachedFile.m */; };
64 64
 		A760F52C14F24B9F00AD1B0E /* DTASN1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A760F52A14F24B9F00AD1B0E /* DTASN1Parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
65  
-		A760F52D14F24B9F00AD1B0E /* DTASN1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A760F52A14F24B9F00AD1B0E /* DTASN1Parser.h */; };
  65
+		A760F52D14F24B9F00AD1B0E /* DTASN1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = A760F52A14F24B9F00AD1B0E /* DTASN1Parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
66 66
 		A760F52E14F24B9F00AD1B0E /* DTASN1Parser.m in Sources */ = {isa = PBXBuildFile; fileRef = A760F52B14F24B9F00AD1B0E /* DTASN1Parser.m */; };
67 67
 		A760F52F14F24B9F00AD1B0E /* DTASN1Parser.m in Sources */ = {isa = PBXBuildFile; fileRef = A760F52B14F24B9F00AD1B0E /* DTASN1Parser.m */; };
68 68
 		A77DD39E14E648AD00F34B03 /* DTAsyncFileDeleter.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD39C14E648AD00F34B03 /* DTAsyncFileDeleter.h */; settings = {ATTRIBUTES = (Public, ); }; };
69  
-		A77DD39F14E648AD00F34B03 /* DTAsyncFileDeleter.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD39C14E648AD00F34B03 /* DTAsyncFileDeleter.h */; };
  69
+		A77DD39F14E648AD00F34B03 /* DTAsyncFileDeleter.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD39C14E648AD00F34B03 /* DTAsyncFileDeleter.h */; settings = {ATTRIBUTES = (Public, ); }; };
70 70
 		A77DD3A014E648AD00F34B03 /* DTAsyncFileDeleter.m in Sources */ = {isa = PBXBuildFile; fileRef = A77DD39D14E648AD00F34B03 /* DTAsyncFileDeleter.m */; };
71 71
 		A77DD3A114E648AD00F34B03 /* DTAsyncFileDeleter.m in Sources */ = {isa = PBXBuildFile; fileRef = A77DD39D14E648AD00F34B03 /* DTAsyncFileDeleter.m */; };
72 72
 		A77DD40814E81AEE00F34B03 /* DTZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD40614E81AED00F34B03 /* DTZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
73  
-		A77DD40914E81AEE00F34B03 /* DTZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD40614E81AED00F34B03 /* DTZipArchive.h */; };
  73
+		A77DD40914E81AEE00F34B03 /* DTZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD40614E81AED00F34B03 /* DTZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
74 74
 		A77DD40A14E81AEE00F34B03 /* DTZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = A77DD40714E81AEE00F34B03 /* DTZipArchive.m */; };
75 75
 		A77DD40B14E81AEE00F34B03 /* DTZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = A77DD40714E81AEE00F34B03 /* DTZipArchive.m */; };
76 76
 		A77DD41614E825FC00F34B03 /* crypt.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD40D14E825FC00F34B03 /* crypt.h */; };
@@ -92,45 +92,57 @@
92 92
 		A77DD42614E825FC00F34B03 /* zip.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD41514E825FC00F34B03 /* zip.h */; };
93 93
 		A77DD42714E825FC00F34B03 /* zip.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD41514E825FC00F34B03 /* zip.h */; };
94 94
 		A7949A3A14C963F500A8CCDE /* DTHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7949A3814C963F500A8CCDE /* DTHTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
95  
-		A7949A3B14C963F500A8CCDE /* DTHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7949A3814C963F500A8CCDE /* DTHTMLParser.h */; };
  95
+		A7949A3B14C963F500A8CCDE /* DTHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7949A3814C963F500A8CCDE /* DTHTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
96 96
 		A7949A3C14C963F500A8CCDE /* DTHTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = A7949A3914C963F500A8CCDE /* DTHTMLParser.m */; };
97 97
 		A7949A3D14C963F500A8CCDE /* DTHTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = A7949A3914C963F500A8CCDE /* DTHTMLParser.m */; };
98 98
 		A7A7CC7914866CAF00EC2EE4 /* DTVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CC81486621B00873A4A /* DTVersion.m */; };
99 99
 		A7A7CC7A14866CAF00EC2EE4 /* NSString+DTFormatNumbers.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCB1486621B00873A4A /* NSString+DTFormatNumbers.m */; };
100 100
 		A7A7CC7B14866CAF00EC2EE4 /* NSURL+DTAppLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCD1486621B00873A4A /* NSURL+DTAppLinks.m */; };
101 101
 		A7A7CC7C14866CAF00EC2EE4 /* NSURL+DTPrefLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = A70B4CCF1486621B00873A4A /* NSURL+DTPrefLinks.m */; };
102  
-		A7D0AA25153C1B160020F18B /* NSDictionary+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA23153C1B160020F18B /* NSDictionary+DTError.h */; };
103  
-		A7D0AA26153C1B160020F18B /* NSDictionary+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA23153C1B160020F18B /* NSDictionary+DTError.h */; };
  102
+		A7D0AA25153C1B160020F18B /* NSDictionary+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA23153C1B160020F18B /* NSDictionary+DTError.h */; settings = {ATTRIBUTES = (Public, ); }; };
  103
+		A7D0AA26153C1B160020F18B /* NSDictionary+DTError.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA23153C1B160020F18B /* NSDictionary+DTError.h */; settings = {ATTRIBUTES = (Public, ); }; };
104 104
 		A7D0AA27153C1B160020F18B /* NSDictionary+DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA24153C1B160020F18B /* NSDictionary+DTError.m */; };
105 105
 		A7D0AA28153C1B160020F18B /* NSDictionary+DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA24153C1B160020F18B /* NSDictionary+DTError.m */; };
106  
-		A7D0AA2B153C1FE40020F18B /* NSString+DTURLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA29153C1FE40020F18B /* NSString+DTURLEncoding.h */; };
107  
-		A7D0AA2C153C1FE40020F18B /* NSString+DTURLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA29153C1FE40020F18B /* NSString+DTURLEncoding.h */; };
  106
+		A7D0AA2B153C1FE40020F18B /* NSString+DTURLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA29153C1FE40020F18B /* NSString+DTURLEncoding.h */; settings = {ATTRIBUTES = (Public, ); }; };
  107
+		A7D0AA2C153C1FE40020F18B /* NSString+DTURLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA29153C1FE40020F18B /* NSString+DTURLEncoding.h */; settings = {ATTRIBUTES = (Public, ); }; };
108 108
 		A7D0AA2D153C1FE40020F18B /* NSString+DTURLEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA2A153C1FE40020F18B /* NSString+DTURLEncoding.m */; };
109 109
 		A7D0AA2E153C1FE40020F18B /* NSString+DTURLEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA2A153C1FE40020F18B /* NSString+DTURLEncoding.m */; };
110  
-		A7D0AA44153C22B00020F18B /* DTDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA42153C22B00020F18B /* DTDownload.h */; };
111  
-		A7D0AA45153C22B00020F18B /* DTDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA42153C22B00020F18B /* DTDownload.h */; };
  110
+		A7D0AA44153C22B00020F18B /* DTDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA42153C22B00020F18B /* DTDownload.h */; settings = {ATTRIBUTES = (Public, ); }; };
  111
+		A7D0AA45153C22B00020F18B /* DTDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA42153C22B00020F18B /* DTDownload.h */; settings = {ATTRIBUTES = (Public, ); }; };
112 112
 		A7D0AA46153C22B00020F18B /* DTDownload.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA43153C22B00020F18B /* DTDownload.m */; };
113 113
 		A7D0AA47153C22B00020F18B /* DTDownload.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA43153C22B00020F18B /* DTDownload.m */; };
114  
-		A7D0AA4A153C233E0020F18B /* NSString+DTUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA48153C233E0020F18B /* NSString+DTUtilities.h */; };
115  
-		A7D0AA4B153C233E0020F18B /* NSString+DTUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA48153C233E0020F18B /* NSString+DTUtilities.h */; };
  114
+		A7D0AA4A153C233E0020F18B /* NSString+DTUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA48153C233E0020F18B /* NSString+DTUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
  115
+		A7D0AA4B153C233E0020F18B /* NSString+DTUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA48153C233E0020F18B /* NSString+DTUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
116 116
 		A7D0AA4C153C233E0020F18B /* NSString+DTUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA49153C233E0020F18B /* NSString+DTUtilities.m */; };
117 117
 		A7D0AA4D153C233E0020F18B /* NSString+DTUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA49153C233E0020F18B /* NSString+DTUtilities.m */; };
118  
-		A7D0AA6D153C39920020F18B /* DTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA6B153C39920020F18B /* DTUtils.h */; };
119  
-		A7D0AA6E153C39920020F18B /* DTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA6B153C39920020F18B /* DTUtils.h */; };
  118
+		A7D0AA6D153C39920020F18B /* DTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA6B153C39920020F18B /* DTUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
  119
+		A7D0AA6E153C39920020F18B /* DTUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D0AA6B153C39920020F18B /* DTUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
120 120
 		A7D0AA6F153C39920020F18B /* DTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA6C153C39920020F18B /* DTUtils.m */; };
121 121
 		A7D0AA70153C39920020F18B /* DTUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D0AA6C153C39920020F18B /* DTUtils.m */; };
122  
-		A7D6F2E515063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; };
123  
-		A7D6F2E615063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; };
  122
+		A7D6F2E515063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
  123
+		A7D6F2E615063448001CACDD /* DTExtendedFileAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
124 124
 		A7D6F2E715063448001CACDD /* DTExtendedFileAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */; };
125 125
 		A7D6F2E815063448001CACDD /* DTExtendedFileAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */; };
126  
-		A7D8628114EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; };
127  
-		A7D8628214EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; };
  126
+		A7D8628114EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; settings = {ATTRIBUTES = (Public, ); }; };
  127
+		A7D8628214EBF65C001436AF /* NSString+DTPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */; settings = {ATTRIBUTES = (Public, ); }; };
128 128
 		A7D8628314EBF65C001436AF /* NSString+DTPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8628014EBF65C001436AF /* NSString+DTPaths.m */; };
129 129
 		A7D8628414EBF65C001436AF /* NSString+DTPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8628014EBF65C001436AF /* NSString+DTPaths.m */; };
  130
+		A7D8C2AA15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8C2A815643C4E009E94AD /* DTPieProgressIndicator.h */; };
  131
+		A7D8C2AB15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8C2A815643C4E009E94AD /* DTPieProgressIndicator.h */; };
  132
+		A7D8C2AC15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8C2A915643C4E009E94AD /* DTPieProgressIndicator.m */; };
  133
+		A7D8C2AD15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8C2A915643C4E009E94AD /* DTPieProgressIndicator.m */; };
130 134
 		A7FE30641548005700F5DC66 /* NSObject+DTRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FE30631548005700F5DC66 /* NSObject+DTRuntime.h */; };
131 135
 		A7FE30651548005700F5DC66 /* NSObject+DTRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FE30631548005700F5DC66 /* NSObject+DTRuntime.h */; };
132 136
 		A7FE30681548009A00F5DC66 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = A7FE30671548009A00F5DC66 /* NSObject+DTRuntime.m */; };
133 137
 		A7FE30691548009A00F5DC66 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = A7FE30671548009A00F5DC66 /* NSObject+DTRuntime.m */; };
  138
+		FA4264F2155D6B5B00E39D79 /* DTPageZoomScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4264EE155D6B5B00E39D79 /* DTPageZoomScrollView.h */; };
  139
+		FA4264F3155D6B5B00E39D79 /* DTPageZoomScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4264EE155D6B5B00E39D79 /* DTPageZoomScrollView.h */; };
  140
+		FA4264F4155D6B5B00E39D79 /* DTPageZoomScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4264EF155D6B5B00E39D79 /* DTPageZoomScrollView.m */; };
  141
+		FA4264F5155D6B5B00E39D79 /* DTPageZoomScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4264EF155D6B5B00E39D79 /* DTPageZoomScrollView.m */; };
  142
+		FA4264F6155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4264F0155D6B5B00E39D79 /* DTSmartPagingScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; };
  143
+		FA4264F7155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4264F0155D6B5B00E39D79 /* DTSmartPagingScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; };
  144
+		FA4264F8155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4264F1155D6B5B00E39D79 /* DTSmartPagingScrollView.m */; };
  145
+		FA4264F9155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4264F1155D6B5B00E39D79 /* DTSmartPagingScrollView.m */; };
134 146
 /* End PBXBuildFile section */
135 147
 
136 148
 /* Begin PBXFileReference section */
@@ -191,10 +203,16 @@
191 203
 		A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTExtendedFileAttributes.m; sourceTree = "<group>"; };
192 204
 		A7D8627F14EBF65C001436AF /* NSString+DTPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+DTPaths.h"; sourceTree = "<group>"; };
193 205
 		A7D8628014EBF65C001436AF /* NSString+DTPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+DTPaths.m"; sourceTree = "<group>"; };
  206
+		A7D8C2A815643C4E009E94AD /* DTPieProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTPieProgressIndicator.h; sourceTree = "<group>"; };
  207
+		A7D8C2A915643C4E009E94AD /* DTPieProgressIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTPieProgressIndicator.m; sourceTree = "<group>"; };
194 208
 		A7F4DFF8147FD08900F4059A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
195 209
 		A7F4DFFA147FD08F00F4059A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
196 210
 		A7FE30631548005700F5DC66 /* NSObject+DTRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DTRuntime.h"; sourceTree = "<group>"; };
197 211
 		A7FE30671548009A00F5DC66 /* NSObject+DTRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DTRuntime.m"; sourceTree = "<group>"; };
  212
+		FA4264EE155D6B5B00E39D79 /* DTPageZoomScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTPageZoomScrollView.h; sourceTree = "<group>"; };
  213
+		FA4264EF155D6B5B00E39D79 /* DTPageZoomScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTPageZoomScrollView.m; sourceTree = "<group>"; };
  214
+		FA4264F0155D6B5B00E39D79 /* DTSmartPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTSmartPagingScrollView.h; sourceTree = "<group>"; };
  215
+		FA4264F1155D6B5B00E39D79 /* DTSmartPagingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTSmartPagingScrollView.m; sourceTree = "<group>"; };
198 216
 /* End PBXFileReference section */
199 217
 
200 218
 /* Begin PBXFrameworksBuildPhase section */
@@ -251,6 +269,8 @@
251 269
 		A7494E4A154190C000BDDB7D /* DTDownloadCache */ = {
252 270
 			isa = PBXGroup;
253 271
 			children = (
  272
+				A7D0AA42153C22B00020F18B /* DTDownload.h */,
  273
+				A7D0AA43153C22B00020F18B /* DTDownload.m */,
254 274
 				A7494DF915418B3100BDDB7D /* DTDownloadCache.h */,
255 275
 				A7494DFA15418B3100BDDB7D /* DTDownloadCache.m */,
256 276
 				A7494E51154190F500BDDB7D /* DTCachedFile.h */,
@@ -333,13 +353,14 @@
333 353
 		A7D0AA6A153C395C0020F18B /* Classes */ = {
334 354
 			isa = PBXGroup;
335 355
 			children = (
  356
+				FA4264EC155D6B2500E39D79 /* DTSmartPagingScrollView */,
336 357
 				A7494E4A154190C000BDDB7D /* DTDownloadCache */,
337  
-				A7D0AA42153C22B00020F18B /* DTDownload.h */,
338  
-				A7D0AA43153C22B00020F18B /* DTDownload.m */,
339 358
 				A760F52A14F24B9F00AD1B0E /* DTASN1Parser.h */,
340 359
 				A760F52B14F24B9F00AD1B0E /* DTASN1Parser.m */,
341 360
 				A77DD39C14E648AD00F34B03 /* DTAsyncFileDeleter.h */,
342 361
 				A77DD39D14E648AD00F34B03 /* DTAsyncFileDeleter.m */,
  362
+				A7D8C2A815643C4E009E94AD /* DTPieProgressIndicator.h */,
  363
+				A7D8C2A915643C4E009E94AD /* DTPieProgressIndicator.m */,
343 364
 				A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */,
344 365
 				A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */,
345 366
 				A7949A3814C963F500A8CCDE /* DTHTMLParser.h */,
@@ -372,6 +393,17 @@
372 393
 			path = ../..;
373 394
 			sourceTree = BUILT_PRODUCTS_DIR;
374 395
 		};
  396
+		FA4264EC155D6B2500E39D79 /* DTSmartPagingScrollView */ = {
  397
+			isa = PBXGroup;
  398
+			children = (
  399
+				FA4264EE155D6B5B00E39D79 /* DTPageZoomScrollView.h */,
  400
+				FA4264EF155D6B5B00E39D79 /* DTPageZoomScrollView.m */,
  401
+				FA4264F0155D6B5B00E39D79 /* DTSmartPagingScrollView.h */,
  402
+				FA4264F1155D6B5B00E39D79 /* DTSmartPagingScrollView.m */,
  403
+			);
  404
+			name = DTSmartPagingScrollView;
  405
+			sourceTree = "<group>";
  406
+		};
375 407
 /* End PBXGroup section */
376 408
 
377 409
 /* Begin PBXHeadersBuildPhase section */
@@ -407,6 +439,9 @@
407 439
 				A7494E54154190F500BDDB7D /* DTCachedFile.h in Headers */,
408 440
 				A7FE30651548005700F5DC66 /* NSObject+DTRuntime.h in Headers */,
409 441
 				A73D5BAC155271FD0024BDB7 /* NSArray+DTError.h in Headers */,
  442
+				FA4264F3155D6B5B00E39D79 /* DTPageZoomScrollView.h in Headers */,
  443
+				FA4264F7155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */,
  444
+				A7D8C2AB15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */,
410 445
 			);
411 446
 			runOnlyForDeploymentPostprocessing = 0;
412 447
 		};
@@ -443,6 +478,9 @@
443 478
 				A7494E53154190F500BDDB7D /* DTCachedFile.h in Headers */,
444 479
 				A7FE30641548005700F5DC66 /* NSObject+DTRuntime.h in Headers */,
445 480
 				A73D5BAB155271FD0024BDB7 /* NSArray+DTError.h in Headers */,
  481
+				FA4264F2155D6B5B00E39D79 /* DTPageZoomScrollView.h in Headers */,
  482
+				FA4264F6155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */,
  483
+				A7D8C2AA15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */,
446 484
 			);
447 485
 			runOnlyForDeploymentPostprocessing = 0;
448 486
 		};
@@ -598,6 +636,9 @@
598 636
 				A7494E56154190F500BDDB7D /* DTCachedFile.m in Sources */,
599 637
 				A7FE30691548009A00F5DC66 /* NSObject+DTRuntime.m in Sources */,
600 638
 				A73D5BAE155271FD0024BDB7 /* NSArray+DTError.m in Sources */,
  639
+				FA4264F5155D6B5B00E39D79 /* DTPageZoomScrollView.m in Sources */,
  640
+				FA4264F9155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */,
  641
+				A7D8C2AD15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */,
601 642
 			);
602 643
 			runOnlyForDeploymentPostprocessing = 0;
603 644
 		};
@@ -630,6 +671,9 @@
630 671
 				A7494E55154190F500BDDB7D /* DTCachedFile.m in Sources */,
631 672
 				A7FE30681548009A00F5DC66 /* NSObject+DTRuntime.m in Sources */,
632 673
 				A73D5BAD155271FD0024BDB7 /* NSArray+DTError.m in Sources */,
  674
+				FA4264F4155D6B5B00E39D79 /* DTPageZoomScrollView.m in Sources */,
  675
+				FA4264F8155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */,
  676
+				A7D8C2AC15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */,
633 677
 			);
634 678
 			runOnlyForDeploymentPostprocessing = 0;
635 679
 		};
@@ -675,7 +719,10 @@
675 719
 		A7BAD1171483F934000E2B6A /* Debug */ = {
676 720
 			isa = XCBuildConfiguration;
677 721
 			buildSettings = {
678  
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
  722
+				ARCHS = (
  723
+					"$(ARCHS_STANDARD_32_BIT)",
  724
+					armv6,
  725
+				);
679 726
 				CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)";
680 727
 				DEAD_CODE_STRIPPING = NO;
681 728
 				DEPLOYMENT_POSTPROCESSING = YES;
@@ -699,7 +746,10 @@
699 746
 		A7BAD1181483F934000E2B6A /* Release */ = {
700 747
 			isa = XCBuildConfiguration;
701 748
 			buildSettings = {
702  
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
  749
+				ARCHS = (
  750
+					"$(ARCHS_STANDARD_32_BIT)",
  751
+					armv6,
  752
+				);
703 753
 				CONTENTS_FOLDER_PATH = "$(WRAPPER_NAME)/Versions/$(FRAMEWORK_VERSION)";
704 754
 				DEAD_CODE_STRIPPING = NO;
705 755
 				DEPLOYMENT_POSTPROCESSING = YES;

0 notes on commit d7293c3

Please sign in to comment.
Something went wrong with that request. Please try again.