0

I am trying to open a link inside app, but when I click the cell (didSelectRowAt), I get an error (Fatal error: Unexpectedly found nil while unwrapping an Optional value: file). If I change (titleLink = "he is the link"), it works. What should I change to get not an error?

The error is in didSelectRowAt, you can see it as a comment.

import UIKit
import SafariServices

class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, XMLParserDelegate {

@IBOutlet weak var tableView: UITableView!

var parser = XMLParser()
var post = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var title1 = NSMutableString()
var textLink = NSMutableString()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    parsingDataFromUrl()
}

func parsingDataFromUrl() {
    post = []
    parser = XMLParser(contentsOf: NSURL(string: "feedRssLinkHere")! as URL)!
    parser.delegate = self
    parser.parse()
    tableView.reloadData()
}

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    element = elementName as NSString
    if (elementName as NSString).isEqual(to: "item") {
        elements = NSMutableDictionary()
        elements = [:]
        title1 = NSMutableString()
        title1 = ""
        textLink = NSMutableString()
        textLink = ""
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    if element.isEqual(to: "title") {
        title1.append(string)
    } else if element.isEqual(to: "link") {
        textLink.append(string)
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if (elementName as NSString).isEqual(to: "item") {
        if !title1.isEqual(nil) {
            elements.setObject(title1, forKey: "title" as NSCopying)
        }
        if !textLink.isEqual(nil) {
            elements.setObject(textLink, forKey: "link" as NSCopying)
        }
        post.add(elements)
    }
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MainCell

    if cell.isEqual(NSNull()) {
        cell = Bundle.main.loadNibNamed("Cell", owner: self, options: nil)! [0] as! MainCell
    }

    cell.titleLabel.text = (post.object(at: indexPath.row) as AnyObject).value(forKey: "title") as! NSString as String
    return cell
}

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

    let titleLink = (post.object(at: indexPath.row) as AnyObject).value(forKey: "link") as! NSString as String

    let svc = SFSafariViewController(url: URL(string: titleLink)!) // Fatal error: Unexpectedly found nil while unwrapping an Optional value: file
    present(svc, animated: true, completion: nil)
}

}

awex
  • 130
  • 3
  • 7
  • Could you print `titleLink`? `URL(string: titleLink)` could be `nil` because `titleLink` contains invalid characters like spaces. Is that the case? – Larme Apr 20 '20 at 16:46
  • Not related, but if you are using Swift 3+, avoid NSStuff, prefers Stuff (Swift versions) when possible, like String instead of NSString. There is plenty of bad code. – Larme Apr 20 '20 at 16:48
  • When I print titleLink, I get the link. I use swift 5 – awex Apr 20 '20 at 16:56
  • That's not what I asked. do `let url = URL(string: titleLink); print(url)`, it's nil, no. Copy/paste that link into Safari.app (or Chrome or any browser) in you Mac. Does it work? If, yes, copy/paste that URL in that browser and compare if that the same (and that no percent characters appeared for instance, like a %20). – Larme Apr 20 '20 at 16:59
  • print(url) is nil – awex Apr 20 '20 at 17:02
  • and when I check the link in browser, it is working. – awex Apr 20 '20 at 17:03
  • https://stackoverflow.com/questions/7258940/nsurl-returns-nil-value https://stackoverflow.com/questions/5839877/nsurl-urlwithstringmystring-returns-nil https://stackoverflow.com/questions/40368389/swift-url-returning-nil https://stackoverflow.com/questions/46411038/url-is-always-nil-in-swift-3 etc. – Larme Apr 20 '20 at 17:04
  • Give the URL, or look for percent escaping, did you compare the URL once loaded in browser with the original one? – Larme Apr 20 '20 at 17:04
  • with "addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed" İ don't get an error, but the link is not working, when I compare the links, it is more character than original link.(original: www.link.com/link/, new one is: www.link.com/link/%0A%09%09%09%09%09") – awex Apr 20 '20 at 17:17
  • 1
    It means you have garbage characters (invisible) at the end of your URL. Garbage which aren't valid characters (which explains the nil), and which is converted into "%0A%09%09%09%09%09". For instance a tab ("\t") is "%09". Why do you have 5 tabs at the end of your url string ? And \n is a "%0A". So you have `www.link.com/link/\n\t\t\t\t\t`. Find out why, it can be a big issue on your next parsing. – Larme Apr 20 '20 at 18:06
  • Thank you for your answers. I will try to clean garbage. Your solution works and I found one more solution too: "replacingOccurrences(of: "%0A%09%09%09%09%09", with: "")" – awex Apr 20 '20 at 18:52
  • 1
    No, remove tabs & comments at the end: `titleLink = titleLink.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)` – Larme Apr 20 '20 at 20:08
  • Thank you for your answer, I did with "titleLink = titleLink.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)". It works perfectly. – awex Apr 21 '20 at 07:58
  • 1
    The good fix would be to do the trimming here: `elements.setObject(textLink, forKey: "link" as NSCopying)`. – Larme Apr 21 '20 at 09:06
  • Do you know, how to sort "title" alphabetically in tableview? – awex Apr 21 '20 at 09:17
  • By sorting `posts` depending on its title value. – Larme Apr 21 '20 at 12:10
  • I can get String, but not in Array, thats why "sorted(by: { $0 < $1 })" is not working. How can I make all values in an array? – awex Apr 21 '20 at 13:38

0 Answers0