0

I have a VideoListController. It has list of videos with download button. When I press the download button, the control is transferred to DetailViewController. In DetailViewController, I am using AFNetworking to download file.

If I go back to VideoListController from DetailViewController. How can I know progress of download or when download gets completed from VideoListController. I want to know this because based upon that I will reload the list to show play button instead of download.

Javier Quevedo
  • 2,066
  • 1
  • 17
  • 27
Homam
  • 5,018
  • 4
  • 36
  • 39
  • i got ur point for download complete thing, but could u tell me, how r u updating download progress values in other view controllers – ChenSmile Mar 10 '17 at 11:42

2 Answers2

1

I think that the best solution for your problem would be to create a custom delegate protocol that the DetailViewController and the VideoListController can use to communicate with each other. Check this post for additional information How to use custom delegates in Objective-C

In a nutshell the strategy is the following: 1. The DetailViewController defines a delegate protocol that it uses to pass events to its delegate 2. The VideoListController becomes the delegate to that it knows whenever an upload has progressed or been completed 3. The VideoListController keeps track of which DetailViewControllers have completed the download

Here is come code: DetailViewController.h:

@class DetailViewController;
@protocol Delegate <NSObject>
- (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful;
@end

@property (nonatomic, weak) id<DetailViewController> delegate;

DetailViewController.m: Whenever a download is complete do the following:

if ([[self delegate] respondsToSelector:@selector(detailViewController:didFinishDownloadingVideoWithResults:)]){
   [[self delegate] detailViewController:self didFinishDownloadingVideoWithResults:YES];
}

Now, in the VideoListController.m make sure you establish yourself as the delegate of the DetailViewController.

[theDetailViewController setDelegate:self];

And implement the delegate method. You can for instance have a dictionary that defines which DetailViewControllers have completed the download:

   - (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful{
      detailViewControllersDownloadInformation[theDetailViewController] = @(successful);
}

Now, whenever you need to check if a DetailViewController did indeed complete a download, all you have to do is check that dictionary

if (detailViewControllersDownloadInformation[theDetailViewController] && detailViewControllersDownloadInformation[theDetailViewController] == @(YES)){
    // Did download a video
}

Keep in mind that the solution I provide will only let you know if the download has been completed. If you also want to keep track of the progress you need to pass that as an additional parameter in the delegate. We are also assuming that you keep all of the DetailViewControllers in memory. If you release and reuse them you will need to keep track of which element was downloaded in a different data structure.

Community
  • 1
  • 1
Javier Quevedo
  • 2,066
  • 1
  • 17
  • 27
  • I am getting error here: @property (nonatomic, weak) id delegate; I think it should be id delegate; Is it? – Homam Apr 29 '13 at 12:42
  • I have implemented It like this: @ class DetailViewController; @ protocol Delegate - (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful; @ end @ property (nonatomic, weak) id delegate; @end – Homam Apr 29 '13 at 12:47
  • In DetailViewController, when the download gets completed. I add this: if ([[self delegate] respondsToSelector:@selector(detailViewController:didFinishDownloadingVideoWithResults:)]){ [[self delegate] detailViewController:self detailViewController:didFinishDownloadingVideoWithResults:YES]; } But i get this error: Use of undeclared identifier 'didFinishDownloadingVideoWithResults' – Homam Apr 29 '13 at 12:55
  • There was a typo, try it now using: [[self delegate] detailViewController:self didFinishDownloadingVideoWithResults:YES]; – Javier Quevedo Apr 29 '13 at 13:15
  • Since I was getting warning, In VideoListController, I added delegate like this: @interface RowViewController : UITableViewController When I come back from DetailViewController to VideoListController, while downloading, still this method does not get called. -(void) detailViewController:(DetailViewController *)theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful { NSLog(@"Download Completed!"); } – Homam Apr 30 '13 at 05:08
0

I got it working using NSNotificationCenter. In viewDidLoad of DetailViewController, I added this

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(movieDownloadDidFinish)
                                             name:@"MovieDownloadDidFinishNotification"
                                           object:nil];

When download gets complete. I call this:

[[NSNotificationCenter defaultCenter] postNotificationName:@"MovieDownloadDidFinishNotification" object:self];

I remove the observer from DetailViewController when when backbutton in navigation controller is clicked

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MovieDownloadDidFinishNotification" object:nil];

And added method in DetailViewController that is called when download gets completed.

-(void) movieDownloadDidFinish {
    NSLog(@"MovieDownloadDidFinish on DetailViewController");
}

Now in viewDidAppear of VideoListController, I added the observer

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(movieDownloadDidFinish)
                                             name:@"MovieDownloadDidFinishNotification"
                                           object:nil];

And in viewDidDisappear Of VideoListController, I remove the observer

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MovieDownloadDidFinishNotification" object:nil];

And added method in VideoListController that is called when download gets completed.

-(void) movieDownloadDidFinish {
    NSLog(@"MovieDownloadDidFinish On VideoListController");
}

In this way, when DetailViewController is visible, the method movieDownloadDidFinish of DetailViewController is called and similarly movieDownloadDidFinish of VideoListController is called when VideoListController is visible.

Homam
  • 5,018
  • 4
  • 36
  • 39