在表视图单元格选择上打开URL(RSS阅读器)

时间:2015-11-02 13:41:28

标签: ios swift uitableview url nsxmlparser

我有一个带有表视图的场景:

enter image description here

这里我做了一个RSS阅读器,我得到的每个元素:标题,日期,描述和我的网址。在表视图单元格上单击我要打开浏览器/导航器并传递新单击的URL。

我这样做了:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let myWebView = self.storyboard!.instantiateViewControllerWithIdentifier("ActualitesViewController") as! ActualitesViewController

    myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("url"))

    self.presentViewController(myWebView, animated: true, completion: nil)


}

但是我收到了这个错误:

/Users/.../ActualitesViewController.swift:144:25: Cannot invoke initializer for type 'NSURL' with an argument list of type '(string: AnyObject?)'

完整代码:

import UIKit

@objc
protocol ActualitesViewControllerDelegate {
    optional func toggleLeftPanel()
    optional func collapseSidePanels()
}

class ActualitesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSXMLParserDelegate {
    @IBOutlet var tableView: UITableView!

    var parser = NSXMLParser()
    var posts = NSMutableArray()
    var elements = NSMutableDictionary()
    var element = NSString()
    var title1 = NSMutableString()
    var date = NSMutableString()
    var dscrptn = NSMutableString()
    var url = NSMutableString()

    override func viewDidLoad()
    {
        super.viewDidLoad()
        self.navigationController?.navigationBar.barTintColor = UIColor(red: 38.0/255.0, green: 51.0/255.0, blue: 85.0/255.0, alpha: 1.0)
        self.navigationController?.navigationBar.titleTextAttributes = [NSFontAttributeName: UIFont(name: "Gotham", size: 13)!, NSForegroundColorAttributeName : UIColor.whiteColor()]
        self.title = "ACTUALITÉS"

        self.beginParsing()

    }

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

    func beginParsing()
    {
        posts = []
        parser = NSXMLParser(contentsOfURL:(NSURL(string:"url"))!)!
        parser.delegate = self
        parser.parse()

        tableView!.reloadData()
    }

    //XMLParser Methods

    func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
    {
        element = elementName
        if (elementName as NSString).isEqualToString("item")
        {
            elements = NSMutableDictionary()
            elements = [:]
            title1 = NSMutableString()
            title1 = ""
            date = NSMutableString()
            date = ""
            dscrptn = NSMutableString()
            dscrptn = ""
            url = NSMutableString()
            url = ""
        }
    }

    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
    {
        if (elementName as NSString).isEqualToString("item") {
            if !title1.isEqual(nil) {
                elements.setObject(title1, forKey: "title")
            }
            if !date.isEqual(nil) {
                elements.setObject(date, forKey: "date")
            }
            if !dscrptn.isEqual(nil) {
                elements.setObject(dscrptn, forKey: "dscrptn")
            }
            if !url.isEqual(nil) {
                elements.setObject(url, forKey: "url")
            }

            posts.addObject(elements)
        }
    }

    func parser(parser: NSXMLParser, foundCharacters string: String)
    {
        if element.isEqualToString("title") {
            title1.appendString(string)
        } else if element.isEqualToString("pubDate") {
            date.appendString(string)
        } else if element.isEqualToString("description") {
            dscrptn.appendString(string)
        } else if element.isEqualToString("link") {
            url.appendString(string)
        }
    }

    //Tableview Methods

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

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        let myWebView = self.storyboard!.instantiateViewControllerWithIdentifier("ActualitesViewController") as! ActualitesViewController

        myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("url"))

        self.presentViewController(myWebView, animated: true, completion: nil)


    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 10
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        return basicCellAtIndexPath(indexPath)
    }


    func basicCellAtIndexPath(indexPath:NSIndexPath) -> ActuTblCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! ActuTblCell

        setTitleForCell(cell, indexPath: indexPath)
        setDateForCell(cell, indexPath: indexPath)
        setDescriptionForCell(cell, indexPath: indexPath)
        return cell
    }

    func setTitleForCell(cell:ActuTblCell, indexPath:NSIndexPath) {
        cell.titleActuCell?.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
    }

    func setDateForCell(cell:ActuTblCell, indexPath:NSIndexPath) {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
        let dateString = posts.objectAtIndex(indexPath.row).valueForKey("date") as! NSString as String
        if let dateAdded = dateFormatter.dateFromString(dateString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()))
        {
            dateFormatter.dateFormat = "dd/MM/yyyy"
            cell.dateActuCell?.text = "\(dateFormatter.stringFromDate(dateAdded))"
        }
        //cell.dateActuCell?.text = posts.objectAtIndex(indexPath.row).valueForKey("date") as! NSString as String
    }

    func setDescriptionForCell(cell:ActuTblCell, indexPath:NSIndexPath) {
        cell.descriptionActuCell?.text = (posts.objectAtIndex(indexPath.row).valueForKey("dscrptn") as! NSString as String).stripHTML()
    }
}
let     htmlReplaceString   :   String  =   "<[^>]+>"

extension NSString {
    func stripHTML() -> NSString {
        return self.stringByReplacingOccurrencesOfString(htmlReplaceString, withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: NSRange(location: 0,length: self.length)) as NSString
    }
}


extension String {
    func stripHTML() -> String {
        return self.stringByReplacingOccurrencesOfString(htmlReplaceString, withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
    }
}

修改

的变化:

var url = NSURL()
var urlString = NSMutableString()


//XMLParser Methods

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
{
    element = elementName
    if (elementName as NSString).isEqualToString("item")
    {
        elements = NSMutableDictionary()
        elements = [:]
        title1 = NSMutableString()
        title1 = ""
        date = NSMutableString()
        date = ""
        dscrptn = NSMutableString()
        dscrptn = ""
        url = NSURL()
        urlString = NSMutableString()
        urlString = ""
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
    if (elementName as NSString).isEqualToString("item") {
        if !title1.isEqual(nil) {
            elements.setObject(title1, forKey: "title")
        }
        if !date.isEqual(nil) {
            elements.setObject(date, forKey: "date")
        }
        if !dscrptn.isEqual(nil) {
            elements.setObject(dscrptn, forKey: "dscrptn")
        }
        if !urlString.isEqual(nil) {
            elements.setObject(urlString, forKey: "urlString")
        }

        posts.addObject(elements)
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String)
{
    if element.isEqualToString("title") {
        title1.appendString(string)
    } else if element.isEqualToString("pubDate") {
        date.appendString(string)
    } else if element.isEqualToString("description") {
        dscrptn.appendString(string)
    } else if element.isEqualToString("link") {
        urlString.appendString(string)
    }
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let myWebView = self.storyboard!.instantiateViewControllerWithIdentifier("ActualitesViewController") as! ActualitesViewController
    print(urlString)

    myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("urlString") as! String)!

    self.presentViewController(myWebView, animated: true, completion: nil)


}

urlString打印正确,但我在这一行收到错误:

myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("urlString") as! String)!

错误:

fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)

在浏览器中打开:

let trimUrl = posts.objectAtIndex(indexPath.row).valueForKey("urlString") as! String

UIApplication.sharedApplication().openURL(NSURL(string: trimUrl.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()))!)

1 个答案:

答案 0 :(得分:0)

valueForKey返回AnyObject?,这是一个可选的任何对象。如果您确定在这种情况下它实际上将返回String,那么您可以强制将其向下转换为String

所以

myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("url"))

变为

myWebView.url = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("url") as! String)

虽然更好的方法是创建一个模型对象,该对象具有诸如titleurl等内容的属性。然后使posts成为一组数组模型对象的类型posts: [Model],然后在你调用objectAtIndex之后,编译器都会知道你正在返回一个Model对象,此时你可以调用{{1}之类的东西直接{}}和title,无需使用url并强制转发。