为 JSON Tableview 使用不同的 URL 链接 [英] Using different URL links for JSON Tableview

查看:34
本文介绍了为 JSON Tableview 使用不同的 URL 链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的是根据我的应用程序中发生的情况从不同的链接(4 个不同的链接)加载我的 JSON.这是一个具有 4 个不同广播电台的广播网络应用程序.我可以将当​​前正在播放的电台推送到我的 JSON ViewController,但问题是如何让 JSON 执行如果当前电台正在播放,则从此链接拉取:链接到 JSON 信息"?我知道这是可能的,但不知道如何实现它.这是我的 JSON TableviewViewController 代码:

What I'm trying to do is have my JSON loaded from different links (4 different links) depending on whats going on in my app. It's a radio network app with 4 different radio stations. I can push over what station is currently playing to my JSON ViewController but the problem is how do I get the JSON to do an "IF this current station is playing THEN pull from this link: LINK TO JSON INFO"? I know it's possible but don't know how to implement it. Here is my code for the JSON TableviewViewController:

    import UIKit

//----------
//MARK: JSON
//----------

//The Initial Response From The JSON
struct Response: Codable {

    var playHistory: Album

}

//The Album Received Which Is An Array Of Song Data
struct Album: Codable {
    var song: [SongData]

}

//The SongData From The PlayHistory Album
struct SongData: Codable{

    var album: String
    var artist: String
    var cover: String
    var duration: String
    var programStartTS: String
    var title: String
}


class TableViewController: UITableViewController {

    //1. Create An Array To Store The SongData
    var songs = [SongData]()
    var currentStation: RadioStation!
    var downloadTask: URLSessionDownloadTask?

    override func viewDidLoad() { super.viewDidLoad()


        self.tableView.delegate = self
        self.tableView.dataSource = self

        //2. Load The JSON From The Main Bundle

        guard let urlText = URL (string: currentStation.longDesc)
            else { return }


        do{
            //a. Get The Data From The From The File
            let data = try Data(contentsOf: urlText)

            //b. Decode The Data To Our Structs
            let albumData = try JSONDecoder().decode(Response.self, from: data)

            //c. Append The Songs Array With The PlayHistory
            albumData.playHistory.song.forEach { songs.append($0) }

            //d. Test Some Data
            print("""
                **The First Album Details**
                Album = \(songs[0].album)
                Artist = \(songs[0].artist)
                Cover = \(songs[0].cover)
                Duration = \(songs[0].duration)
                Start = \(songs[0].programStartTS)
                Title = \(songs[0].title)
                """)

            //3. Load The Data
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }catch{

            print(error)
        }

    }

    //-----------------
    //MARK: UITableView
    //-----------------


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return songs.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        //1. Create A Cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

        //2. Set It's Text
        cell.songTitle.text = songs[indexPath.row].title
        cell.artistLabel.text = songs[indexPath.row].artist

        //3. Get The Image
        if let imageURL = URL(string: songs[indexPath.row].cover){

            let request = URLSession.shared.dataTask(with: imageURL) { (imageData, response, error) in

                if let error = error{

                    print(error)

                }else{

                    guard let image = imageData else { return }

                    DispatchQueue.main.async {
                        cell.songCover.image = UIImage(data: image)
                        cell.setNeedsLayout()
                        cell.layoutIfNeeded()
                    }

                }
            }


            request.resume()
        }

        return cell

    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        print("""
            **Album \(indexPath.row) Selected**
            Album = \(songs[indexPath.row].album)
            Artist = \(songs[indexPath.row].artist)
            Cover = \(songs[indexPath.row].cover)
            Duration = \(songs[indexPath.row].duration)
            Start = \(songs[indexPath.row].programStartTS)
            Title = \(songs[indexPath.row].title)
            """)
    }

}

这是我的Now Playing ViewController"中的代码:

Here is code from my "Now Playing ViewController":

import UIKit
import MediaPlayer

//*****************************************************************
// NowPlayingViewControllerDelegate
//*****************************************************************

protocol NowPlayingViewControllerDelegate: class {
    func didPressPlayingButton()
    func didPressStopButton()
    func didPressNextButton()
    func didPressPreviousButton()
}

//*****************************************************************
// NowPlayingViewController
//*****************************************************************

class NowPlayingViewController: UIViewController {

    weak var delegate: NowPlayingViewControllerDelegate?

    // MARK: - IB UI

    @IBOutlet weak var albumHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var albumImageView: SpringImageView!
    @IBOutlet weak var artistLabel: UILabel!
    @IBOutlet weak var playingButton: UIButton!
    @IBOutlet weak var songLabel: SpringLabel!
    @IBOutlet weak var stationDescLabel: UILabel!
    @IBOutlet weak var volumeParentView: UIView!
    @IBOutlet weak var previousButton: UIButton!
    @IBOutlet weak var nextButton: UIButton!
    @IBOutlet weak var recentlyPlayed: UIButton!

    // MARK: - Properties

    var currentStation: RadioStation!
    var currentTrack: Track!

    var newStation = true
    var nowPlayingImageView: UIImageView!
    let radioPlayer = FRadioPlayer.shared

    var mpVolumeSlider: UISlider?

    //*****************************************************************
    // MARK: - ViewDidLoad
    //*****************************************************************

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create Now Playing BarItem
        createNowPlayingAnimation()

        // Set AlbumArtwork Constraints
        optimizeForDeviceSize()

        // Set View Title
        self.title = currentStation.name


        // Set UI
        albumImageView.image = currentTrack.artworkImage
        stationDescLabel.text = currentStation.desc
        stationDescLabel.isHidden = currentTrack.artworkLoaded

        // Check for station change
        newStation ? stationDidChange() : playerStateDidChange(radioPlayer.state, animate: false)

        // Setup volumeSlider
        setupVolumeSlider()

        // Hide / Show Next/Previous buttons
        previousButton.isHidden = hideNextPreviousButtons
        nextButton.isHidden = hideNextPreviousButtons
    }

    //*****************************************************************
    // MARK: - Setup
    //*****************************************************************

    func setupVolumeSlider() {
        // Note: This slider implementation uses a MPVolumeView
        // The volume slider only works in devices, not the simulator.
        for subview in MPVolumeView().subviews {
            guard let volumeSlider = subview as? UISlider else { continue }
            mpVolumeSlider = volumeSlider
        }

        guard let mpVolumeSlider = mpVolumeSlider else { return }

        volumeParentView.addSubview(mpVolumeSlider)

        mpVolumeSlider.translatesAutoresizingMaskIntoConstraints = false
        mpVolumeSlider.leftAnchor.constraint(equalTo: volumeParentView.leftAnchor).isActive = true
        mpVolumeSlider.rightAnchor.constraint(equalTo: volumeParentView.rightAnchor).isActive = true
        mpVolumeSlider.centerYAnchor.constraint(equalTo: volumeParentView.centerYAnchor).isActive = true

        mpVolumeSlider.setThumbImage(#imageLiteral(resourceName: "slider-ball"), for: .normal)
    }

    func stationDidChange() {
        radioPlayer.radioURL = URL(string: currentStation.streamURL)
        title = currentStation.name
    }

    //*****************************************************************
    // MARK: - Player Controls (Play/Pause/Volume)
    //*****************************************************************

    // Actions

    @IBAction func playingPressed(_ sender: Any) {
        delegate?.didPressPlayingButton()
    }

    @IBAction func stopPressed(_ sender: Any) {
        delegate?.didPressStopButton()
    }

    @IBAction func nextPressed(_ sender: Any) {
        delegate?.didPressNextButton()
    }

    @IBAction func previousPressed(_ sender: Any) {
        delegate?.didPressPreviousButton()
    }

    //*****************************************************************
    // MARK: - Load station/track
    //*****************************************************************

    func load(station: RadioStation?, track: Track?, isNewStation: Bool = true) {
        guard let station = station else { return }

        currentStation = station
        currentTrack = track
        newStation = isNewStation
    }

    func updateTrackMetadata(with track: Track?) {
        guard let track = track else { return }

        currentTrack.artist = track.artist
        currentTrack.title = track.title

        updateLabels()
    }

    // Update track with new artwork
    func updateTrackArtwork(with track: Track?) {
        guard let track = track else { return }

        // Update track struct
        currentTrack.artworkImage = track.artworkImage
        currentTrack.artworkLoaded = track.artworkLoaded

        albumImageView.image = currentTrack.artworkImage

        if track.artworkLoaded {
            // Animate artwork
            albumImageView.animation = "wobble"
            albumImageView.duration = 3
            albumImageView.animate()
            stationDescLabel.isHidden = true
        } else {
            stationDescLabel.isHidden = false
        }

        // Force app to update display
        view.setNeedsDisplay()
    }

    private func isPlayingDidChange(_ isPlaying: Bool) {
        playingButton.isSelected = isPlaying
        startNowPlayingAnimation(isPlaying)
    }

    func playbackStateDidChange(_ playbackState: FRadioPlaybackState, animate: Bool) {

        let message: String?

        switch playbackState {
        case .paused:
            message = "Station Paused..."
        case .playing:
            message = nil
        case .stopped:
            message = "Station Stopped..."
        }

        updateLabels(with: message, animate: animate)
        isPlayingDidChange(radioPlayer.isPlaying)
    }

    func playerStateDidChange(_ state: FRadioPlayerState, animate: Bool) {

        let message: String?

        switch state {
        case .loading:
            message = "Loading Station ..."
        case .urlNotSet:
            message = "Station URL not valide"
        case .readyToPlay, .loadingFinished:
            playbackStateDidChange(radioPlayer.playbackState, animate: animate)
            return
        case .error:
            message = "Error Playing"
        }

        updateLabels(with: message, animate: animate)
    }

    //*****************************************************************
    // MARK: - UI Helper Methods
    //*****************************************************************

    func optimizeForDeviceSize() {

        // Adjust album size to fit iPhone 4s, 6s & 6s+
        let deviceHeight = self.view.bounds.height

        if deviceHeight == 480 {
            albumHeightConstraint.constant = 106
            view.updateConstraints()
        } else if deviceHeight == 667 {
            albumHeightConstraint.constant = 230
            view.updateConstraints()
        } else if deviceHeight > 667 {
            albumHeightConstraint.constant = 260
            view.updateConstraints()
        }
    }

    func updateLabels(with statusMessage: String? = nil, animate: Bool = true) {

        guard let statusMessage = statusMessage else {
            // Radio is (hopefully) streaming properly
            songLabel.text = currentTrack.title
            artistLabel.text = currentTrack.artist
            shouldAnimateSongLabel(animate)
            return
        }

        // There's a an interruption or pause in the audio queue

        // Update UI only when it's not aleary updated
        guard songLabel.text != statusMessage else { return }

        songLabel.text = statusMessage
        artistLabel.text = currentStation.name

        if animate {
            songLabel.animation = "flash"
            songLabel.repeatCount = 3
            songLabel.animate()
        }
    }

    // Animations

    func shouldAnimateSongLabel(_ animate: Bool) {
        // Animate if the Track has album metadata
        guard animate, currentTrack.title != currentStation.name else { return }

        // songLabel animation
        songLabel.animation = "zoomIn"
        songLabel.duration = 1.5
        songLabel.damping = 1
        songLabel.animate()
    }

    func createNowPlayingAnimation() {

        // Setup ImageView
        nowPlayingImageView = UIImageView(image: UIImage(named: "NowPlayingBars-3"))
        nowPlayingImageView.autoresizingMask = []
        nowPlayingImageView.contentMode = UIViewContentMode.center

        // Create Animation
       // nowPlayingImageView.animationImages = AnimationFrames.createFrames()
       // nowPlayingImageView.animationDuration = 0.7

        // Create Top BarButton
        let barButton = UIButton(type: .custom)
        barButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        barButton.addSubview(nowPlayingImageView)
        nowPlayingImageView.center = barButton.center

        //let barItem = UIBarButtonItem(customView: barButton)
        //self.navigationItem.rightBarButtonItem = barItem
    }

    func startNowPlayingAnimation(_ animate: Bool) {
        animate ? nowPlayingImageView.startAnimating() : nowPlayingImageView.stopAnimating()
    }

    //*****************************************************************
    // MARK: - Segue
    //*****************************************************************





    @IBAction func shareButtonPressed(_ sender: UIButton) {
        let songToShare = "I'm listening to \(currentTrack.title) by: \(currentTrack.artist) on \(currentStation.name)"
        let activityViewController = UIActivityViewController(activityItems: [songToShare, currentTrack.artworkImage!], applicationActivities: nil)
        activityViewController.completionWithItemsHandler = {(activityType: UIActivityType?, completed:Bool, returnedItems:[Any]?, error: Error?) in
            if completed {
                    // do something on completion if you want
                            }
                    }
        present(activityViewController, animated: true, completion: nil)
    }
}

推荐答案

您需要将 currentStation 传递给 TableViewController

你说你在故事板中有一个 segue,从 NowPlayingViewControllerTableViewController.

You stated that you have a segue in the storyboard that goes from NowPlayingViewController to TableViewController.

在这种情况下,您需要在 NowPlayingViewController 中的 prepare(for segue:sender:) 中执行以下操作:

In that case, you need to do the following in prepare(for segue:sender:) in NowPlayingViewController as so:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let vc = segue.destination as? TableViewController {
        vc.currentStation = currentStation
    }
}

这篇关于为 JSON Tableview 使用不同的 URL 链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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