Unexpectedly found nil. While passing url from one controller to another

Viewed 50

My project is to create a split view where master is TableViewController and Detail is WebKit. My main problem is that when I pass an Url from my TableView it turns out as hill while unwrapping it in Webkit Controller. I also use struct List with variables name:Strin? and url: URL!

Here is my code for tableViewController:

import UIKit
import WebKit

class WebBrowsers: UITableViewController {
    private var list:[List] = [
        List(name: "google.com", url: URL(string:"google.com"))
    ]
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return list.count
    }

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
        cell.textLabel?.text = list[indexPath.row].name
        // Configure the cell...

        return cell
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "showDetail"{
            if let destination = segue.destination as? infoBrowser{
                if let row = tableView.indexPathForSelectedRow?.row{
                    destination.detailUrl = list[row].url
                }
            }
        }
        
    }  
    }

here is my webkit ViewController

import UIKit
import WebKit
class infoBrowser: UIViewController {
    
    var detailUrl: URL!
    
    @IBOutlet weak var showPage: WKWebView!  
    override func viewDidLoad() {
        super.viewDidLoad()
        let request = URLRequest(url: detailUrl!)
        showPage.load(request)
        // Do any additional setup after loading the view.

    }
    
    override func viewWillAppear(_ animated: Bool) {
       
    }
}
2 Answers

Issue is with this line of code:

if let row = tableView.indexPathForSelectedRow?.row{
   destination.detailUrl = list[row].url
}

tableView.indexPathForSelectedRow? will always be nil as there is no implementation for the didSelectRow delegate for tableView. Either shift your navigation code to didSelect of tableView or implement this just to select row.

URL(string:"google.com") this returns an optional URL which means, if the String passed is not a valid url then it will return nil and in your infoBrowser you have declared detailUrl as implicit optional which means when it tries to access this variable while creating URLRequest, if the value is nil it will crash,

so change var detailUrl: URL? also before creating URL request add a check to ensure URL is not nil

override func viewDidLoad() {
    super.viewDidLoad()
    guard let url = detailUrl else { return }
    let request = URLRequest(url: url)
    showPage.load(request)
}
Related