Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

iphone - How to write a dowloader class for updating download progress in iOs

Here is my actual issue, as some suggested I want to write a class for handling the multiple download progress in a UITableView. I have no idea how to write a class for this, can somebody help with some tips or ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The group to look at is NSURLRequest and NSURLConnection. The former let's you specify the request (URL, http method, params, etc) and the latter runs it.

Since you want to update status as it goes (I answered a sketch of this in your other question, I think), you'll need to implement the NSURLConnectionDelegate protocol that hands over chunks of data as it arrives from the connection. If you know how much data to expect, you can use the amount received to calculate a downloadProgress float as I suggested earlier:

float downloadProgress = [responseData length] / bytesExpected;

Here's some nice looking example code in SO. You can extend for multiple connections like this...

MyLoader.m

@interface MyLoader ()
@property (strong, nonatomic) NSMutableDictionary *connections;
@end

@implementation MyLoader
@synthesize connections=_connections;  // add a lazy initializer for this, not shown

// make it a singleton
+ (MyLoader *)sharedInstance {

    @synchronized(self) {
        if (!_sharedInstance) {
            _sharedInstance = [[MyLoader alloc] init];
        }
    }
    return _sharedInstance;
}

// you can add a friendlier one that builds the request given a URL, etc.
- (void)startConnectionWithRequest:(NSURLRequest *)request {

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSMutableData *responseData = [[NSMutableData alloc] init];
    [self.connections setObject:responseData forKey:connection];
}

// now all the delegate methods can be of this form.  just like the typical, except they begin with a lookup of the connection and it's associated state
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    NSMutableData *responseData = [self.connections objectForKey:connection];
    [responseData appendData:data];

    // to help you with the UI question you asked earlier, this is where
    // you can announce that download progress is being made
    NSNumber *bytesSoFar = [NSNumber numberWithInt:[responseData length]];
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
        [connection URL], @"url", bytesSoFar, @"bytesSoFar", nil];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"MyDownloaderDidRecieveData"
        object:self userInfo:userInfo];

    // the url should let you match this connection to the database object in
    // your view controller.  if not, you could pass that db object in when you
    // start the connection, hang onto it (in the connections dictionary) and
    // provide it in userInfo when you post progress
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...