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

preface

After downloading and unpacking the files in the last section, let’s start working on the unpacked files

Reading a picture book is actually a picture with an audio, slide to which picture to play which audio, picture book information is in the index.json file, now we will parse the index.json file

To get the data

  • According to theindex.jsonThe data in the file, build the picture book modelBookModel
struct BookModel: Codable { let audioMode: String let cover: String let name: String let pageCount: Int var pagesv2: [BookPageModel] Let portrait: Bool Let read: String Let version: String /// Customize parameters - Cover image path var coverURL: String } struct BookPageModel: Codable { let audio: String let bac: String let p: Int let time: Var imageURL: String var audioURL: String} Var audioURL: String}Copy the code
  • inZipManagerI’m going to add onegetBookHow to get a picture book model
Private func getBook(_ url: String) -> BookModel? { guard let u = URL(string: Url) else {return nil} / / / according to capture the url last level folder name let lastFileDocuments = u.l astPathComponent. ReplacingOccurrences (of: ".zip", with: "") let allPath = bookUnzipFilePath + url.md5String + "/\(lastFileDocuments)/" /// index allPath + "index.json" do { let indexData = try Data(contentsOf: URL(fileURLWithPath: indexPath)) if var bookModel = try? CleanJSONDecoder().decode(BookModel.self, from: CoverURL = allPath + bookModel.cover for (index, Model) in bookModel. Pagesv2. Enumerated () {/ / / set the picture path bookModel. The pagesv2 [index] imageURL = allPath + model. The bac / / / Bookmodel.pagesv2 [index].audiourl = allPath + model.audio} return bookModel} return nil} catch {return nil} }Copy the code

The data show

Now that we have the data, let’s start presenting the data. We’re going to use UICollectionView to show the images

newReadBookViewControllerThe controller

Class ReadBookViewController: BaseViewController {private let bookModel: bookModel init(bookModel: BookModel) {self. BookModel = BookModel landscape display / / / if the let the delegate = UIApplication. Shared. The delegate as? AppDelegate { delegate.orientationMask = .landscapeRight } super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidAppear(_ animated: Bool) {super. ViewDidAppear (animated) / / / prohibited sideslip return navigationController?. InteractivePopGestureRecognizer? The isEnabled = false } override func viewWillDisappear(_ animated: Bool) {super. ViewWillDisappear (animated) / / / cancel banned sideslip return navigationController?. InteractivePopGestureRecognizer? The isEnabled Landscape display = true / / / cancel if let the delegate = UIApplication. Shared. Delegate as? AppDelegate {delegate. OrientationMask =. Portrait }} override func viewDidLoad() {super.viewDidLoad() setupNav() addSubviews()} private func setupNav() {// hide the navigation bar navigation.bar.isHidden = true } private func addSubviews() { } }Copy the code

createcollectionView

private lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.itemSize = UIScreen.main.bounds.size layout.scrollDirection = .horizontal layout.minimumLineSpacing = 0 layout.minimumInteritemSpacing = 0 let view = UICollectionView(frame: .zero, collectionViewLayout: layout) view.backgroundColor = .black view.delegate = self view.dataSource = self view.register(ReadBookCell.self) view.showsVerticalScrollIndicator = false view.showsHorizontalScrollIndicator = false view.isPagingEnabled = true return  view }() private func addSubviews() { view.addSubview(collectionView) collectionView.snp.makeConstraints { (make) in make.edges.equalToSuperview() } } extension ReadBookViewController: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return bookModel.pagesv2.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withClass: ReadBookCell.self, for: indexPath) cell.imgView.image = UIImage(contentsOfFile: bookModel.pagesv2[indexPath.item].imageURL) return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { } }Copy the code

Now the picture is shown

Playback of audio

The audio playback is going to use the one we encapsulated last time

createplayer

private lazy var player: AudioPlayer = {
    let player = AudioPlayer()
    player.delegate = self
    player.playbackPausesWhenResigningActive = false
    player.playbackPausesWhenBackgrounded = false
    player.playbackResumesWhenBecameActive = false
    player.playbackResumesWhenEnteringForeground = false
    return player
}()

extension ReadBookViewController: AudioPlayerDelegate {

    func playerStateDidChange(_ player: AudioPlayer) {}

    func playerCurrentTimeDidChange(_ player: AudioPlayer) {}

    func playerPlaybackDidEnd(_ player: AudioPlayer) {}

    func player(_ player: AudioPlayer, didFailWithError error: Error?) {}
}
Copy the code

play

Private func playerURL () {/ / / boundary treatment if playerIndex < 0 | | playerIndex > bookModel. Pagesv2. {return} let count - 1 model  = bookModel.pagesv2[playerIndex] player.player(URL(fileURLWithPath: model.audioURL).absoluteString) }Copy the code

Photo and audio linkage

  • callUIScrollViewDelegateThe method of
Extension ReadBookViewController: UIScrollViewDelegate {/ / / sliding end call the method func scrollViewDidEndDecelerating (_ scrollView: UIScrollView) { debugPrint(scrollView.contentOffset.x) let offsetX = collectionView.contentOffset.x let currentIndex = Int(offsetX / UIScreen.width) if (currentIndex ! = playerIndex) { playerIndex = currentIndex playerURL() } } func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { debugPrint(scrollView.contentOffset.x) let offsetX = collectionView.contentOffset.x let currentIndex = Int(offsetX / UIScreen.width) if (currentIndex ! = playerIndex) { playerIndex = currentIndex playerURL() } } }Copy the code
  • After the audio playback is over, setcollectionViewthesetContentOffsetMethods the pages
extension ReadBookViewController: AudioPlayerDelegate {

    func playerPlaybackDidEnd(_ player: AudioPlayer) {
        if playerIndex < 0 || playerIndex + 1 >= bookModel.pagesv2.count - 1 {
            return
        }
        let offsetX = UIScreen.width * CGFloat(playerIndex + 1)
        collectionView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: true)
    }
}
Copy the code

This is the end of reading the picture book