This is the 14th day of my participation in the August More Text Challenge. For details, see:August is more challenging

preface

Now that the video and audio are done, it’s time to read the picture books.

Grab the interface data and find a URL field in it. The URL is a ZIP link

Open a link in your browser to download it and unzip it

As you can see from the screenshot above, it contains images and audio resources, as well as an index.json file

The index.json file contains the information about the picture book, including the name of the image and the audio, and the length of the audio

Reading a picture book is actually a picture with an audio, slide to which picture to play which audio. So here are the steps:

Download the ZIP package. 2. Decompress the ZIP package. 3

downloadzippackage

To download the ZIP package we use Alamofire. There are many ways to download Alamofire, so which one should we use?

1, we download the ZIP package according to the URL. 2, we download the ZIP package and put it in the customized directory

Looking at the Alamofire documentation, we found this usage description (the following paragraph is an excerpt from the Alamofire documentation)

Download File Destination

All downloaded data is initially stored in the system temporary directory. It will eventually be deleted by the system at some point in the future, so if it’s something that needs to live longer, it’s important to move the file somewhere else.

You can provide a Destination closure to move the file from the temporary directory to a final destination. Before the temporary file is actually moved to the destinationURL, the Options specified in the closure will be executed. The two currently supported Options are:

  • .createIntermediateDirectories – Creates intermediate directories for the destination URL if specified.
  • .removePreviousFile – Removes a previous file from the destination URL if specified.
let destination: DownloadRequest.Destination = { _, _ in
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = documentsURL.appendingPathComponent("image.png")

    return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}

AF.download("https://httpbin.org/image/png", to: destination).response { response in
    debugPrint(response)

    if response.error == nil, let imagePath = response.fileURL?.path {
        let image = UIImage(contentsOfFile: imagePath)
    }
}
Copy the code

You can also use the suggested download destination API:

let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

AF.download("https://httpbin.org/image/png", to: destination)
Copy the code

So we write a download method in NetworkManager

public func download(_ url: String, to destination: DownloadRequest.Destination? = nil, progress: @escaping (Progress) -> Void, responseURL: @escaping (URL) -> Void, failure: @escaping (AppError) -> Void) { AF.download(url, to: destination) .downloadProgress(closure: progress) .response { response in if response.error == nil, FilePath = response.fileurl {responseURL(filePath)} else {failure(AppError(code: -1, errorMessage: "download failed "))}}}Copy the code

Unpack thezippackage

To decompress the ZIP package, we use the ZIP library to decompress it

  • useCocoaPodsThe import
pod 'Zip'
Copy the code
  • To viewZipThe use of the documentation found that there are two methods to decompressThe following paragraph is an excerptZipDocument)

1, Quick functions provides

do {
    let filePath = Bundle.main.url(forResource: "file", withExtension: "zip")!
    let unzipDirectory = try Zip.quickUnzipFile(filePath) // Unzip
} catch {
  print("Something went wrong")
}
Copy the code

2, the Advanced Zip

For more advanced usage, Zip has functions that let you set custom destination paths, work with password protected zips and use a progress handling closure. These functions throw if there is an error but don’t return.

do {
    let filePath = Bundle.main.url(forResource: "file", withExtension: "zip")!
    let documentsDirectory = FileManager.default.urls(for:.documentDirectory, in: .userDomainMask)[0]
    try Zip.unzipFile(filePath, destination: documentsDirectory, overwrite: true, password: "password", progress: { (progress) -> () in
        print(progress)
    }) // Unzip
} catch {
  print("Something went wrong")
}
Copy the code

Since our unzipped files need to be placed in a custom directory, we use the second method

Download and extractzippackage

  • Create a newZipManagerManagement class
class ZipManager: NSObject {static let share = ZipManager() private let bookZipFilePath = NSHomeDirectory() + Private let bookUnzipFilePath = NSHomeDirectory() + "/Documents/BookUnzip/"} private let bookUnzipFilePath = NSHomeDirectory() + "/Documents/BookUnzip/"}Copy the code
  • whenzipAfter the package is decompressed, we need to delete itzippackage
Private func deleteFile(url: String) { let filePath = bookZipFilePath + url.MD5String + url.pathExtension do { try FileManager.default.removeItem(atPath: filePath) } catch {} }Copy the code
  • If the picture book exists, go to it directly, so add a method to determine whether the file exists
Private func isExistence(url: String) -> Bool { let fileName = url.MD5String do { let files = try FileManager.default.contentsOfDirectory(atPath: bookUnzipFilePath) return files.contains(fileName) } catch { return false } }Copy the code
  • inZipManagerIt adds a decompression method
/ / / / / / - Parameters: / / / - url: zip for the location of / / / - downloadURL: zip for download links, as unzip the file folder name / / / - unzipProgress: Private func unzip(_ url: URL, downloadURL: String, unzipProgress: @escaping (Double) -> Void) { let filePath = bookUnzipFilePath + downloadURL.MD5String let fileURL = URL(fileURLWithPath: filePath) do { try Zip.unzipFile(url, destination: fileURL, overwrite: true, password: Nil, progress: {progress in unzipProgress(progress) if progress >= 1 {self.deletefile (url: Catch downloadURL)}})} {print (" decompression failed ") failure (AppError (code: 1, errorMessage: error localizedDescription))}}Copy the code
  • inZipManagerAdd a download and extract method
Func downloadZipHandler(_ url: String) {/// download a existence file and unzip it. Url) {response(getBook(url)) return} // Configure the download path let destination: DownloadRequest.Destination = { _, _ in let filePath = self.bookZipFilePath + url.MD5String + url.pathExtension let fileURL = URL(fileURLWithPath: filePath) return (fileURL, [.removePreviousFile, . The download createIntermediateDirectories])} / / / NetworkManager. Share. Download (url, to: destination) { progress in downloadProgress(progress) } responseURL: {self.unzip(responseURL, downloadURL: url, unzipProgress:) {self.unzip(responseURL, downloadURL: url, unzipProgress: unzipProgress) } failure: { error in failure(error) } }Copy the code

The download and decompression are done, and in the next section we’ll start working on the decompressed file