我有一个表视图,可以从RSS提要中获取数据。表视图加载每个元素的标题字符串,但是当我选择一行去转到所选行的url时,由于在解开可选值时意外找到nil,它会崩溃。此外,图像未从图像URL加载。我已经证实这些与印刷声明不一致。我错过了什么?它在let safariVC = SFSafariViewController(URL: url!, entersReaderIfAvailable: true)
我确信表格视图中的每个项目都会有一个链接,所以强行解包不应该是一个问题。以下是其中一个网址的示例:linkString: http://kyfbnewsroom.com/state-ag-department-assisted-the-farm-community-through-a-month-marked-by-challenges/
但网址为零。
这是完整的代码。
import UIKit
import SafariServices
class NewsFeedTableViewController: UITableViewController, NSXMLParserDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate, UINavigationControllerDelegate, SFSafariViewControllerDelegate, APLSlideMenuViewControllerDelegate {
var urlString = NSString()
var parser = NSXMLParser()
var posts = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var itemTitle = NSMutableString()
var link = NSMutableString()
var thumbnailURL = NSMutableString()
var isActionAlert = false
var attributes = NSDictionary()
var connection: NSURLConnection?
var xmlData: NSMutableData?
var loadingIndicator = UIActivityIndicatorView()
var backgroundImage = UIImage()
var backgroundImageView = UIImageView()
let kfbBlue = UIColor(red: 8.0 / 255.0, green: 77.0 / 255.0, blue: 139.0 / 255.0, alpha: 0.7)
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerNib(UINib(nibName: "NewsCell", bundle: nil), forCellReuseIdentifier: "newsCell")
let menuButton = UIBarButtonItem(image: UIImage(named: "list_button"), style: .Done, target: self, action: "showMenu")
self.navigationItem.leftBarButtonItem = menuButton
let reloadButton = UIBarButtonItem(barButtonSystemItem: .Refresh, target: self, action: "reload")
self.navigationItem.rightBarButtonItem = reloadButton
backgroundImageView = UIImageView(image: backgroundImage)
tableView.backgroundView = backgroundImageView
let width = CGRectGetWidth(self.view.bounds)
let height = CGRectGetHeight(self.view.bounds)
loadingIndicator = UIActivityIndicatorView(frame: CGRectMake(width / 2, height / 2, 75, 75))
loadingIndicator.layer.cornerRadius = 10
loadingIndicator.backgroundColor = kfbBlue
loadingIndicator.center = CGPointMake(width / 2, height / 2 - 37)
loadingIndicator.activityIndicatorViewStyle = .WhiteLarge
loadingIndicator.hidesWhenStopped = true
tableView.addSubview(loadingIndicator)
loadingIndicator.startAnimating()
}
override func viewDidDisappear(animated: Bool) {
loadingIndicator.stopAnimating()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func showMenu() {
self.slideMenuController().showLeftMenu(true)
}
func beginParsing() {
posts = []
xmlData = NSMutableData()
let url = NSURL(string: self.urlString as String)
let req = NSURLRequest(URL: url!)
connection = NSURLConnection(request: req, delegate: self, startImmediately: true)!
}
func reload() {
loadingIndicator.startAnimating()
self.beginParsing()
}
// MARK: - NSURLConnection Methods
func connection(connection: NSURLConnection, didReceiveData data: NSData) {
xmlData!.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection) {
loadingIndicator.stopAnimating()
let effectImage = self.backgroundImage.applyDarkEffect()
self.backgroundImageView.image = effectImage
parser = NSXMLParser(data: self.xmlData!)
parser.delegate = self
parser.parse()
xmlData = nil
tableView.reloadData()
}
func connection(connection: NSURLConnection, didFailWithError error: NSError) {
self.connection = nil
self.xmlData = nil
loadingIndicator.stopAnimating()
let errorString = NSString(format: "Fetch failed: %@", error.localizedDescription)
TSMessage.showNotificationWithTitle("Network Error", subtitle: errorString as String, type: .Error)
}
// MARK: - XML Parser Methods
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
attributes = attributeDict
element = elementName
if ((elementName as NSString).isEqualToString("item")) {
elements = NSMutableDictionary()
elements = [:]
itemTitle = NSMutableString()
itemTitle = ""
link = NSMutableString()
link = ""
thumbnailURL = NSMutableString()
thumbnailURL = ""
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if (string == "Action Alert") {
self.isActionAlert = true
}
if (element.isEqualToString("title")) {
itemTitle.appendString(string)
} else if (element.isEqualToString("link")) {
link.appendString(string)
} else if (element.isEqualToString("media:thumbnail")) {
thumbnailURL.appendString(attributes.objectForKey("url") as! String)
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if (!isActionAlert) {
if ((elementName as NSString).isEqualToString("item")) {
if !itemTitle.isEqual(nil) {
elements.setObject(itemTitle, forKey: "title")
}
if !link.isEqual(nil) {
elements.setObject(link, forKey: "link")
}
if !thumbnailURL.isEqual(nil) {
elements.setObject(thumbnailURL, forKey: "thumbnail")
}
posts.addObject(elements)
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 136
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("newsCell", forIndexPath: indexPath) as! NewsCell
cell.newsTitle?.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as? String
cell.newsTitle!.textColor = UIColor.whiteColor()
if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) {
cell.newsTitle!.font = UIFont(name: "FranklinGothicStd-ExtraCond", size: 22.0)
} else {
cell.newsTitle!.font = UIFont(name: "FranklinGothicStd-ExtraCond", size: 30.0)
}
cell.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
var thumbString = posts.objectAtIndex(indexPath.row).valueForKey("thumbnail") as? String
thumbString = thumbString!.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
thumbString = thumbString!.stringByReplacingOccurrencesOfString("%09%09", withString:"")
print(String(format: "thumbString: %@", thumbString!))
// let thumbURL = NSURL(string: (posts.objectAtIndex(indexPath.row).valueForKey("thumbnail") as? String)!)
let thumbURL = NSURL(string: thumbString!)
cell.newsThumb?.sd_setImageWithURL(thumbURL, placeholderImage: UIImage(named: "placeholder"))
cell.newsThumb!.layer.cornerRadius = 45.0
cell.newsThumb!.clipsToBounds = true
cell.newsThumb!.layer.borderWidth = 2.0
cell.newsThumb!.layer.borderColor = UIColor.clearColor().CGColor
cell.newsThumb!.backgroundColor = UIColor.clearColor()
print(posts.objectAtIndex(indexPath.row).valueForKey("title"))
print(posts.objectAtIndex(indexPath.row).valueForKey("link"))
print(posts.objectAtIndex(indexPath.row).valueForKey("thumbnail"))
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let linkString = posts.objectAtIndex(indexPath.row).valueForKey("link") as? String
let url = NSURL(string: linkString!)
let safariVC = SFSafariViewController(URL: url!, entersReaderIfAvailable: true)
safariVC.view.tintColor = kfbBlue
self.navigationController?.presentViewController(safariVC, animated: true, completion: nil)
}
}
答案 0 :(得分:0)
这通常在强制展开可选值时发生:" optionalValue!"
尝试使用if let重写您的方法。 e.g。
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let linkString = posts.objectAtIndex(indexPath.row).valueForKey("link") as? String, url = NSURL(string: linkString) {
let safariVC = SFSafariViewController(URL: url, entersReaderIfAvailable: true)
safariVC.view.tintColor = kfbBlue
self.navigationController?.presentViewController(safariVC, animated: true, completion: nil)
}
}
答案 1 :(得分:0)
我有些人提到你试图使用!
运算符将强制展开作为可选值。但它发生的地方是有趣的一点。根据{{1}} NSURL
的构造函数Apple:
返回使用
init(string:)
初始化的NSURL
对象。如果网址字符串格式错误,请返回URLString
。
因此,当您尝试调用以下代码时:
nil
由于某些原因,let safariVC = SFSafariViewController(URL: url!, entersReaderIfAvailable: true)
为url
,您需要先使用可选绑定进行检查才能解开可选值,请参阅以下代码:
nil
在上面的代码中,应该更好地检查if let url = NSURL(string: linkString!) {
...do rest of your code here
}
的值{strong> optional-binding ,然后再打开它的值,在另一个答案中推荐:
linkString
我希望这对你有所帮助。
答案 2 :(得分:-1)
我通过添加
获得了链接linkString = linkString!.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
linkString = linkString?.stringByReplacingOccurrencesOfString("%09%09", withString:"")
即使我使用图片网址执行此操作,我仍然无法显示图像。看起来图像没有加载,因为图像URL被添加到thumbString两次。 thumbString: http://kyfbnewsroom.com/wp-content/uploads/2012/10/farm-to-school-150x120.jpeghttp://kyfbnewsroom.com/wp-content/uploads/2012/10/farm-to-school-150x120.jpeg