Search code examples
swiftxcodewebviewtableviewalamofire

How to push data generated by Alamofire from tableview to webview


I am somewhat new to the Swift language. Therefore, I need some advice on how to push online data generated by Alamofire from a tableview in one view controller to a webview, located in a different view controller. More specifically, in the JSON data there are a variety of elements with the tag "url." My goal is to match those url elements with the appropriate tableview cell, so that when the cell is clicked, it takes the user to the URL in a new view controller. While I understand how this would work with an array, the JSON data I am using is that of a dictionary. In return, I have fiddled with this for a while, searching the web for any tutorials that may exist. For reference, I included my code in this post. Any information on this problem would be greatly appreciated.

class TableViewController: UITableViewController {
    var responseArray = [[String:Any]]()
    var mySong = 0


    override func viewDidLoad() {
        super.viewDidLoad()
        Alamofire.request("https://rss.itunes.apple.com/api/v1/us/apple-music/top-songs/all/10/explicit.json").responseJSON { response in
            if let json = response.result.value as? [String:Any],
                let feed = json["feed"] as? [String:Any],
                let results = feed["results"] as? [[String:Any]] {
                print(results)
                self.responseArray = results
                self.tableView.reloadData()
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

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

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


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "top10", for: indexPath)
        let song = responseArray[indexPath.row]
        cell.textLabel?.text = song["name"] as? String
        cell.detailTextLabel?.text = song["artistName"] as? String
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        mySong = indexPath.row
        performSegue(withIdentifier: "iTunes", sender: self)
    }
}

Solution

  • You can use a dictionary pretty much like an array. Only difference is that accessing a dictionary value by subscript doesn't guarantee a result so the type of the returned value is optional.

    Coming back to your problem, I gather that you wish to open another ViewController with a WebView in it that navigates to a URL. This URL is determined by the cell that was clicked before navigating here.

    I looked into the API, since you haven't mentioned I will assume that you wish to load the webpage given as per the artistUrl key in the response.

    Just add the following code to the didSelectRowAt method :

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        // safely unwrap artistUrl
        // init WebViewController
        // set url for WebViewController
        if let artistUrl = responseArray[indexPath.row]["artistUrl"], let viewController = storyboard?.instantiateViewController(withIdentifier: "WebViewController") as? WebViewController {
            viewController.url = artistUrl
            present(viewController, animated: true, completion: nil)
        }
    }
    

    Make a WebViewController, if you already have one then just modify the code a bit.

    class WebViewController: UIViewController {
    
        @IBOutlet weak var webView: UIWebView!
    
        var url: String?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // safely unwrap url, then convert it to URL
            if let url = url, let urlForRequest = URL(string: url) {
                let request = URLRequest(url: urlForRequest)
                webView.loadRequest(request)
            }
        }
    }
    

    One last thing, for this API I noticed that all the URLs are HTTPS. Sometimes if you have non-HTTPS then you need to set AllowArbitraryLoads to YES in your plist.