重新打开视图后,AFNetworking恢复进度栏 [英] AFNetworking restore progress bar after view reopened

查看:98
本文介绍了重新打开视图后,AFNetworking恢复进度栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我有一个带有UIProgressView的UIViewController和一个开始使用AFNetworking库下载的按钮。
在关闭viewController然后重新打开之后,如何恢复下载进度栏?

within my app i have a UIViewController with a UIProgressView and a button to start a download with the AFNetworking library. How can i resume the download progress bar, after than the viewController is closed and then reopened?

这是我的代码:

ViewController.m

    [...]
- (void) updateProgress:(float)progress forOperation:(AFHTTPRequestOperation *)operation {
    self.downloadprogress.progress = progress;
}


- (void)downloadTest:(NSString *)cid
{
    NSString *string = [NSString stringWithFormat:@"%@get_new.php?c=%@", BaseURLString, cid];
    NSURL *url = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip", cid]];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];


    __weak typeof(operation)weakOperation = operation;
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        __strong __typeof(weakOperation)strongOperation = weakOperation;
        //NSLog(@"Progress = %f", (float)totalBytesRead / totalBytesExpectedToRead );
        float progressValue = (float)totalBytesRead / totalBytesExpectedToRead;
        [self updateProgress:progressValue forOperation:strongOperation];
    }];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        // DOWNLOAD OK

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        // DOWNLOAD ERROR
    }];

    [operation start];
}
        [...]

ViewController.h

@interface InfoViewController : UIViewController{
    IBOutlet UITextView *txtinfo;

    IBOutlet UIBarButtonItem *btnDown;
}

@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;

- (IBAction)downloadBtn:(id)sender;

@end


推荐答案

I没有使用AFNetworking,所以也许我错了;但是对我来说,由于操作 downloadTest:方法后,您的代码下载将停止>对象。

I haven't used AFNetworking, so perhaps I'm wrong; but it seems for me that with your code download will stop after quit from the downloadTest: method due to deallocation of the operation object.

要解决此问题,请使用属性或某些非本地范围变量。但是,如果即使在销毁了视图控制器之后仍要继续下载,则需要使用在应用程序生存期内存在的对象。

To fix this, use a property or some non-local scope variable. But if you'd like to keep downloading even after destroying your view controller then you need to use an object existing during application life time.

例如,它可能是您的 AppDelegate 的属性。在这种情况下,当前的下载进度也将是 AppDelegate 的属性。通过这种方法,在您的 InfoViewController viewDidLoad:方法中,您可以请求当前下载大小并使用以下命令更新进度条相应的值。另外,要在显示视图控制器时更新当前下载进度,您可以订阅值 AppDelegate 代表当前下载进度的属性更新(使用KVO)。

For example, it could be a property of your AppDelegate. Current download progress in this case would also be an AppDelegate's property. With this approach, in your InfoViewController's viewDidLoad: method you could request current download size and update your progress bar with corresponding value. Also, to update the current download progress while your view controller is presented, you can subscribe to updates of value of AppDelegate's property representing current download progress (using KVO).

请在下面查看此方法的示例。

Please see example of this approach below.

AppDelegate.h

extern NSString* const kStartDownloadNotificationName;
extern NSString* const kStartDownloadNotificationParamCid;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (nonatomic) float currentDownloadProgressValue;

@end

AppDelegate.m

NSString* const kStartDownloadNotificationName = @"StartDownloadNotificationName";
NSString* const kStartDownloadNotificationParamCid = @"StartDownloadNotificationParamCid";

@interface AppDelegate ()

@property (strong, nonatomic) AFHTTPRequestOperation* downloadOperation;

- (void)startDownloadOperationWithNotification:(NSNotification*)notification;

@end

@implementation AppDelegate

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(startDownloadOperationWithNotification:)
                                                 name:kStartDownloadNotificationName
                                               object:nil];
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:kStartDownloadNotificationName
                                                  object:nil];
}

- (void)startDownloadOperationWithNotification:(NSNotification*)notification
{
    NSString* cid = notification.userInfo[kStartDownloadNotificationParamCid];

    if (cid == nil) {
        return;
    }

    NSString *string = [NSString stringWithFormat:@"%@get_new.php?c=%@", BaseURLString, cid];
    NSURL *url = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip", cid]];

    self.downloadOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    self.downloadOperation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];


    __weak typeof(self.downloadOperation)weakOperation = self.downloadOperation;
    [self.downloadOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        __strong __typeof(weakOperation)strongOperation = weakOperation;
        //NSLog(@"Progress = %f", (float)totalBytesRead / totalBytesExpectedToRead );
        self.currentDownloadProgressValue = (float)totalBytesRead / totalBytesExpectedToRead;
    }];

    [self.downloadOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
                                                                // DOWNLOAD OK
                                                            } 
                                                  failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                                                // DOWNLOAD ERROR
                                                            }
    ];

    [self.downloadOperation start];
}

@end

ViewController.h

@interface InfoViewController : UIViewController{
    IBOutlet UITextView *txtinfo;

    IBOutlet UIBarButtonItem *btnDown;
}

@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;

- (IBAction)downloadBtn:(id)sender;

@end

ViewController.m
[...]

ViewController.m [...]

- (void)viewDidLoad
{
    [super viewDidLoad];

    // ...

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    [self updateProgress:appDelegate.currentDownloadProgressValue];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear];

    // ...

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    [appDelegate addObserver:self
                  forKeyPath:@"currentDownloadProgressValue"
                     options:NSKeyValueObservingOptionNew
                     context:NULL];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear];

    // ...

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    [appDelegate removeObserver:self
                     forKeyPath:@"currentDownloadProgressValue"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context 
{

    if ([keyPath isEqual:@"currentDownloadProgressValue"]) {
        NSNumber* currentProgressObj = [change objectForKey:NSKeyValueChangeNewKey];
        [self updateProgress:[currentProgressObj floatValue]];
    }
}


- (void)updateProgress:(float)progress
{
    self.downloadprogress.progress = progress;
}


- (void)downloadTest:(NSString *)cid
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kStartDownloadNotificationName
                                                        object:nil
                                                      userInfo:@{ kStartDownloadNotificationParamCid : cid }];
}
    [...]

PS >抱歉,我没有检查此代码是否存在构建或运行时错误。

P.S. Sorry, I didn't check this code for build or runtime errors.

这篇关于重新打开视图后,AFNetworking恢复进度栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆