Skip to content

Commit

Permalink
Added Pie Progress Indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
odrobnik committed May 21, 2012
1 parent 9f9da74 commit d7293c3
Show file tree
Hide file tree
Showing 9 changed files with 386 additions and 81 deletions.
30 changes: 27 additions & 3 deletions Core/Source/DTDownload.h
@@ -1,15 +1,24 @@
//
// CatalogDownloader.h
// iCatalog
// DTDownload.h
// DTFoundation
//
// Created by Oliver Drobnik on 8/6/10.
// Copyright 2010 Drobnik.com. All rights reserved.
//

#import <Foundation/Foundation.h>
// notifications
extern NSString * const DTDownloadProgressNotification;


@class DTDownload;

// block-based response handler, called after headers were received
typedef void (^DTDownloadResponseHandler)(DTDownload *, NSDictionary *headers);

// block-based completion handler, called once the download has finished
typedef void (^DTDownloadCompletionHandler)(DTDownload *);


/**
Methods that a delegate of a download object is being queried with.
*/
Expand Down Expand Up @@ -150,4 +159,19 @@

- (BOOL)isLoading;

/**-------------------------------------------------------------------------------------
@name Block Handlers
---------------------------------------------------------------------------------------
*/

/**
Sets the block to execute as soon as the HTTP response has been received.
*/
@property (nonatomic, copy) DTDownloadResponseHandler responseHandler;

/**
Sets the block to execute as soon as the download has completed.
*/
@property (nonatomic, copy) DTDownloadCompletionHandler completionHandler;

@end
60 changes: 43 additions & 17 deletions Core/Source/DTDownload.m
Expand Up @@ -9,6 +9,8 @@
#import "DTDownload.h"
#import "NSString+DTUtilities.h"

NSString * const DTDownloadProgressNotification = @"DTDownloadProgressNotification";

@interface DTDownload ()

@property (nonatomic, retain) NSString *internalDownloadFolder;
Expand Down Expand Up @@ -50,6 +52,9 @@ @implementation DTDownload
BOOL headOnly;

BOOL _isLoading;

// response handlers
DTDownloadResponseHandler _responseHandler;
}

#pragma mark Downloading
Expand Down Expand Up @@ -97,7 +102,7 @@ - (void)startWithResume:(BOOL)shouldResume
{
_isLoading = YES;

NSString *fileName = [[_URL absoluteString] md5Checksum];
NSString *fileName = [[_URL path] lastPathComponent];
self.internalDownloadFolder = [[self.folderForDownloading stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:@"download"];

receivedDataFilePath = [internalDownloadFolder stringByAppendingPathComponent:fileName];
Expand All @@ -120,9 +125,6 @@ - (void)startWithResume:(BOOL)shouldResume
downloadEntryIdentifier = [NSString stringWithUUID];
}

downloadEntityTag = [resumeInfo objectForKey:@"NSURLDownloadEntityTag"];


if ([delegate respondsToSelector:@selector(shouldResumeDownload:)])
{
if (!shouldResume || ![delegate shouldResumeDownload:self])
Expand All @@ -140,6 +142,9 @@ - (void)startWithResume:(BOOL)shouldResume

if (shouldResume)
{
downloadEntityTag = [resumeInfo objectForKey:@"NSURLDownloadEntityTag"];


// here we assume we should continue download
receivedDataFile = [NSFileHandle fileHandleForWritingAtPath:receivedDataFilePath];
[receivedDataFile seekToEndOfFile];
Expand Down Expand Up @@ -170,20 +175,27 @@ - (void)startWithResume:(BOOL)shouldResume
{
if (receivedBytes && receivedBytes == _totalBytes)
{
NSLog(@"Already done!");

// Already done!
[self _completeDownload];
return;
}
}
}
else
{
// reset
receivedBytes = 0;
_totalBytes = 0;
downloadEntityTag = nil;
lastModifiedDate = nil;
}
}
else
{
// create download folder
NSError *error = nil;

if (![[NSFileManager defaultManager] createDirectoryAtPath:internalDownloadFolder withIntermediateDirectories:NO attributes:nil error:&error])
if (![[NSFileManager defaultManager] createDirectoryAtPath:internalDownloadFolder withIntermediateDirectories:YES attributes:nil error:&error])
{
NSLog(@"Cannot create download folder %@, %@", internalDownloadFolder, [error localizedDescription]);
return;
Expand All @@ -192,8 +204,6 @@ - (void)startWithResume:(BOOL)shouldResume
downloadEntryIdentifier = [NSString stringWithUUID];
}



NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:_URL
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:60.0];
Expand Down Expand Up @@ -268,6 +278,11 @@ - (void)_completeDownload
{
[delegate download:self didFinishWithFile:targetPath];
}

if (_completionHandler)
{
_completionHandler(self);
}
}

- (void)_updateDownloadInfo
Expand Down Expand Up @@ -359,8 +374,6 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon
}
}



// get something to identify file
NSString *modified = [http.allHeaderFields objectForKey:@"Last-Modified"];
if (modified)
Expand All @@ -373,6 +386,10 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon
lastModifiedDate = [dateFormatter dateFromString:modified];
}

if (_responseHandler)
{
_responseHandler(self, [http allHeaderFields]);
}
}
else
{
Expand Down Expand Up @@ -415,20 +432,27 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

self.lastPaketTimestamp = now;


// notify delegate
if ([delegate respondsToSelector:@selector(download:downloadedBytes:ofTotalBytes:withSpeed:)])
{
[delegate download:self downloadedBytes:receivedBytes ofTotalBytes:_totalBytes withSpeed:downloadSpeed];
}

// send notification
if (_totalBytes)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:(float)receivedBytes / (float)_totalBytes] forKey:@"ProgressPercent"];
[[NSNotificationCenter defaultCenter] postNotificationName:DTDownloadProgressNotification object:self userInfo:userInfo];
}
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
receivedData = nil;
urlConnection = nil;


_isLoading = NO;

[receivedDataFile closeFile];

if (headOnly)
Expand All @@ -442,8 +466,6 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self _completeDownload];
}

_isLoading = NO;
}

#pragma mark Notifications
Expand All @@ -457,7 +479,9 @@ - (NSString *)folderForDownloading
{
if (!folderForDownloading)
{
self.folderForDownloading = NSTemporaryDirectory();
NSString *md5 = [[_URL absoluteString] md5Checksum];

self.folderForDownloading = [NSTemporaryDirectory() stringByAppendingPathComponent:md5];
}

return folderForDownloading;
Expand All @@ -472,6 +496,8 @@ - (BOOL)isLoading
@synthesize MIMEType = _MIMEType;
@synthesize totalBytes = _totalBytes;
@synthesize context;
@synthesize responseHandler = _responseHandler;
@synthesize completionHandler = _completionHandler;


@end
18 changes: 14 additions & 4 deletions Core/Source/DTDownloadCache.h
Expand Up @@ -10,6 +10,16 @@

extern NSString *DTDownloadCacheDidCacheFileNotification;


enum {
DTDownloadCacheOptionNeverLoad = 0,
DTDownloadCacheOptionLoadIfNotCached,
DTDownloadCacheOptionReturnCacheAndLoadAlways,
DTDownloadCacheOptionReturnCacheAndLoadIfChanged,
};
typedef NSUInteger DTDownloadCacheOption;


@interface DTDownloadCache : NSObject <DTDownloadDelegate>

/**
Expand All @@ -20,10 +30,10 @@ extern NSString *DTDownloadCacheDidCacheFileNotification;

/**
@param URL The URL of the file
@param shouldLoad If the data should be loaded from the web in case it is not cached already.
@param option A loading option to specify wheter the file should be loaded if it is already cached.
@returns The cached image or `nil` if none is cached.
*/
- (NSData *)cachedDataForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad;
- (NSData *)cachedDataForURL:(NSURL *)URL option:(DTDownloadCacheOption)option;

/**
current sum of cached files in Bytes
Expand Down Expand Up @@ -52,9 +62,9 @@ extern NSString *DTDownloadCacheDidCacheFileNotification;
/**
Specialized method for retrieving cached images.
@param URL The URL of the image
@param shouldLoad If the image should be loaded from the web in case it is not cached already.
@param option A loading option to specify wheter the file should be loaded if it is already cached.
@returns The cached image or `nil` if none is cached.
*/
- (UIImage *)cachedImageForURL:(NSURL *)URL shouldLoad:(BOOL)shouldLoad;
- (UIImage *)cachedImageForURL:(NSURL *)URL option:(DTDownloadCacheOption)option;

@end

0 comments on commit d7293c3

Please sign in to comment.