2

I have three arrays to make a tableView and a second ViewController. One displays headers for each section on the tableView, one displays titles, and one has the links for each cell. When I build and tap on one of the cells I get:

fatal error: unexpectedly found nil while unwrapping an Optional value

on this line:

 let url = URL(string: websiteURL)!

Now I believe this is because my prepareForSegue is not working, which means it's not sending over the array data to the second View Controller(ChannelViewController). I also tested this by, adding

print("hello")

to the prepareForSegue function and seeing if "hello" appears in the debugger. But it didn't.

So I'm guessing the main problem is making the prepareForSegue do what it's supposed to do.

Here is the FirstViewController code:

import UIKit




class FirstViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {



var headers = ["Bein Sports", "Sky Sports", "Alkass", "Other"]

var channels = [["Bein Sports 1","Bein Sports 2","Bein Sports 3","Bein Sports 4","Bein Sports 5","Bein Sports 6","Bein Sports 7","Bein Sports 8","Bein Sports 9","Bein Sports 10","Bein Sports News"],
                          ["Sky Sports 1","Sky Sports 2","Sky Sports 3","Sky Sports 4","Sky Sports 5"],
                          ["Alkass One", "Alkass Two", "Alkass Three", "Alkass Four", "Alkass Five"],
                          ["BT Sports 1", "BT Sports 2", "Real Madrid TV", "Real Madrid TV 2"]]

var links = [["https://www.google.ca","https://www.facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com"],
             ["https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com"],
             ["https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com","https://facebook.com"],
             ["http://twitter.com","http://facebook.com","http://www.google.com","http://www.instagram.com"]]

var myIndex : IndexPath = IndexPath()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return channels[section].count
}

func numberOfSections(in tableView: UITableView) -> Int {
    return channels.count //Rows
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return headers[section] //Sections
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = channels[indexPath.section][indexPath.row] //TextLabel
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    myIndex = IndexPath(row: indexPath.section, section: indexPath.row)
    performSegue(withIdentifier: "segue", sender: self)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    if (segue.identifier == "segue") {
        let viewController = segue.destination as! ChannelViewController
        // Now you have a pointer to the child view controller.
        // You can save the reference to it, or pass data to it.
        viewController.websiteURL = links[myIndex.section][myIndex.row]
        print("google")
    }
}
}

Here is the second View Controller code:

import UIKit
import WebKit
import AVKit
import AVFoundation

class ChannelViewController: UIViewController {


    var webView: WKWebView!
    var websiteURL = ""



override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.



    webView = WKWebView()
    webView.scrollView.isScrollEnabled = false


    view.addSubview(webView)
    let url = URL(string: websiteURL)!
    let req:URLRequest = URLRequest(url: url)
    webView.load(req)

    webView.translatesAutoresizingMaskIntoConstraints = false
    let width = NSLayoutConstraint(item: webView, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1.0, constant: 0) //Constraints

    let height = NSLayoutConstraint(item: webView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1.0, constant: 0)
    view.addConstraints([width,height]) //Constraints

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
Karrar Al-Mimar
  • 4,199
  • 3
  • 12
  • 15
  • Replace `func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)` with `func prepare(for segue: UIStoryboardSegue, sender: Any?)` since you seems to use Swift 3. If it works, then it's related to this: https://stackoverflow.com/questions/40491818/didselectrowatindexpath-not-working-swift-3 – Larme Jun 27 '17 at 22:42
  • As an aside, force unwrapping the `url` is asking for a crash. Use a conditional unwrap and display an appropriate message – Paulw11 Jun 27 '17 at 22:50

1 Answers1

8

The way you are using prepare for segue is not correct.

You should use

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

and also calling it by

self.performSegue(withIdentifier: "segue", sender: nil)
Behrad3d
  • 439
  • 1
  • 4
  • 13
  • Fixing the signature for `prepare(for:sender:)` will fix the issue. Setting the `sender` to `nil` won't make any difference. In fact `sender` should probably be `indexPath` and then the whole dance with `myIndex` can be avoided – Paulw11 Jun 27 '17 at 22:46
  • oh. Agree on sender stuff. I wrote that as a general term didn't. My bad. – Behrad3d Jun 27 '17 at 22:54
  • No problem. It was more a comment to the asker than yourself. – Paulw11 Jun 27 '17 at 22:55