MCDownloader (iOS download) instructions

Sample

MCDownloader (iOS download) instructions

Preface

Many iOS applications need to download data, and the process and results of these downloads to manage, so I have the idea to write this MCDownloader. In the IOS file download -MCDownloadManager this article, I use GCD and set to achieve this function, can basically meet the demand, implementation of the principle of the main reference AFNetworking source of this part, interested students can look at my AFNetworking 3 series of source code interpretation.

But this article about the realization of the principle of MCDownloader and the above mentioned are not the same, is based on NSOperation, can be said to be my SDWebImage source code interpretation some additional extensions, similarly, interested students can see I write SDWebImage source solution reading series.

MCDownloader current version is 1.0.0, you can download https://github.com/agelessman/MCDownloader here

function

The MCDownloader1.0.0 version provides the following features:

  1. Multi thread asynchronous download, support for the number of concurrent threads. In the example diagram above, the concurrency number is 3
  2. Download the edge to save, this is the most important idea of the download, the data is stored in real time locally, while supporting breakpoint Download
  3. Very convenient data acquisition capabilities, through the MCDownloadReceipt to download the data abstraction, almost all of the information can be obtained in MCDownloadReceipt
  4. Provides the download progress, the block can be monitored by the interface function to download progress and complete the callback, you can also bind to the block to monitor the block callback MCDownloadReceipt
  5. Display current download speed
  6. Support batch download, bulk cancel function
  7. Support tasks to suspend, cancel, delete function
  8. Support download order customization, first in first out or first in first out
  9. Support background and lock screen Download

How to use?

Open download

The unique identifier for each download task is URL, so we use the following code to start a download task:

[[MCDownloader sharedDownloader] downloadDataWithURL:[NSURL URLWithString:url] progress:^ (NSInteger receivedSize, NSInteger expectedSize, NSInteger speed, NSURL * _Nullable targetURL) {completed:^} (MCDownloadReceipt * _Nullable receipt NSError * _Nullable error, BOOL finished) {NSLog ("@ ==%@", error.description);}];

You can customize the processing method in the upper progress and completed. Progress and completion of block callbacks are triggered in the main thread.

Suspend or cancel

MCDownloader is the same as the suspension and cancellation, because the internal download is based on NSOperation implementation, so each task is a NSOperation, and then add them to the queue. When a task is cancelled or suspended, it is necessary to pay attention to the fact that the task will be added to the queue when it is resumed.

Use the following code to suspend or cancel a download task:

[[MCDownloader sharedDownloader] cancel:receipt completed:^{[self.button setTitle:@ "Start" forState:UIControlStateNormal];}];

Since the cancellation does not occur in the main thread, a completed is required to capture the cancel successful event, and then call the main thread.

Remove data

Remove the data saved locally by the following method:

[[MCDownloader sharedDownloader] remove:receipt completed:^{[self.tableView reloadData]}];

Get data information

The following code can be used to obtain some information of the data, the information can be obtained in the download process, can also be downloaded after the completion of the acquisition.

MCDownloadReceipt *receipt = [[MCDownloader sharedDownloader] downloadReceiptForURLString:self.url];

Through the above code can be seen, URL as the only identification data. In the example above, we are in the cell to update the download progress, in order to prevent the problem of cell reuse, I bind progress and complete callback for each block receipt:

__weak typeof (receipt) weakReceipt = receipt; receipt.downloaderProgressBlock = (NSInteger ^ receivedSize, NSInteger expectedSize, NSInteger speed, NSURL * _Nullable targetURL __strong typeof (weakReceipt)) {strongReceipt = weakReceipt; if ([targetURL.absoluteString isEqualToString:self.url]) {[self.button setTitle:@ "Stop" forState:UIControlStateNormal]; self.bytesLable.text [NSString stringWithFormat:@ = "%0.1fm/%0.1fm" receivedSize/1024.0/1024, expectedSize/1024.0, /1024]; self.progressView.progress = (receivedSize/1024.0/1024) / (expectedSize/1024.0/1024); self.speedLable.text [NSString stringWithFormat:@ = "%@/s", "0": @ strongReceipt.speed?]}}; receip; T.downloaderCompletedBlock = ^ (MCDownloadReceipt *receipt, NSError * _Nullable error, BOOL finished) {if (error) {[self.button setTitle:@ "Start" forState:UIControlStateNormal]; self.nameLabel.text = @ "Download Failure";}else {[self.button setTitle:@ "Play" forState:UIControlStateNormal]; self.nameLabel.text = @ "Download Finished";}};

Cancel all download and delete all data

In a certain scenario, you need to cancel all downloads, for example, when you hear the network state becomes 4G, you need to ask the user to continue downloading. Or when you need to clear the cache:

[[MCDownloader sharedDownloader] cancelAllDownloads]; [[MCDownloader sharedDownloader] removeAndClearAll];

These features above, in the demo are demonstrated.

Core idea

Because the download function is not particularly complex features, so I simply talk about the realization of the internal principle.

At the beginning of the code design, I first wrote the class is MCDownloadReceipt. Through it to abstract the data, we first regardless of how it is obtained, only concerned about how much information it needs to expose. This class is very simple, I do not get the code up, but need to pay attention to the following points:

  • These properties are designed to be read-only, indicating that the data is only available in the class, and the data is not modified
  • Receipt needs to be saved locally, and I use an archive approach for persistence
  • File name to do MD5 processing
  • Each receipt is bound to a state attribute

After the completion of the model, it is necessary to deal with the most basic download task, MCDownloadOperation inherited from the NSOperation, so in the MCDownloadOperation we do not need to care about the problem of the thread. We only do the following things in this class:

  • Open the download task, in the task of the start method, I made some of the necessary measures to ensure the start of the task, interested can go to see the source code
  • Accept data and write data
  • Handling the callback function during and after download
  • Handle download status
  • How to cancel the task

Next to the core of the place, how to combine MCDownloadReceipt and MCDownloadOperation, that is, the content of MCDownloader. MCDownloader is exposed to the core of the module, in the design of the main considerations of the following things:

  • Need a simple object to manage the global situation
  • Support to set up some additional information related to download, such as timeout, request headers and concurrency, etc.
  • To provide some of the common ways to control the download, how to start, cancel, remove, etc.

To sum up, this is basically the basic process of writing any of the framework, the first design before coding. In addition, the use of the process, if there are any problems, you can give me a message, if there is a new demand, you can give me a message.

Due to the limited level, it is inevitable that there will be errors, if found, but also hope to be able to tell.