Ios 使用JSON将图像从iTunes解析到tableviewcontroller
我正试图从中解析数据,标题被正确解析并显示,但解析图像时出现问题,我得到一个错误:“致命错误:在展开可选值时意外发现nil” 这是我的密码: ViewModel.swiftIos 使用JSON将图像从iTunes解析到tableviewcontroller,ios,swift,Ios,Swift,我正试图从中解析数据,标题被正确解析并显示,但解析图像时出现问题,我得到一个错误:“致命错误:在展开可选值时意外发现nil” 这是我的密码: ViewModel.swift import Foundation class ViewModel { let urlString = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topsongs/limit=30/json" var titles = [Stri
import Foundation
class ViewModel {
let urlString = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topsongs/limit=30/json"
var titles = [String]()
var images = [String]()
func fetchTitles(success:() -> ()) {
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let url = NSURL(string: urlString)
let task = session.dataTaskWithURL(url!) { (data, response, error) -> Void in
let parser = JSONParser()
self.titles = parser.titlesFromJSON(data!)
success()
}
task.resume()
}
func fetchImages(success:() -> ()) {
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let url = NSURL(string: urlString)
let task = session.dataTaskWithURL(url!) { (data, response, error) -> Void in
let parser = JSONParser()
self.images = parser.imagesFromJSON(data!)
success()
}
task.resume()
}
func numberOfSections() -> Int {
return 1
}
func numberOfItemsInSection(section: Int) -> Int {
return titles.count
}
func titleForItemAtIndexPath(indexPath: NSIndexPath) -> String {
return titles[indexPath.row]
}
}
和MyTableViewController.swift
import UIKit
class MyTableViewController: UITableViewController {
let viewModel = ViewModel()
var imageCache = [String:UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
self.refresh()
self.refreshControl = UIRefreshControl()
self.refreshControl?.addTarget(self, action: #selector(MyTableViewController.refresh), forControlEvents: .ValueChanged)
}
func refresh() {
viewModel.fetchTitles {
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
viewModel.fetchImages {
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.viewModel.numberOfSections()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.viewModel.numberOfItemsInSection(section)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MyTableViewCell
cell.songTitle.text = self.viewModel.titleForItemAtIndexPath(indexPath)
let urlString = self.viewModel.titleForItemAtIndexPath(indexPath)
//found nil
let imgURL: NSURL = NSURL(string: urlString)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(
request, queue: NSOperationQueue.mainQueue(),
completionHandler: {(response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
if error == nil {
cell.songImage.image = UIImage(data: data!)
}
})
return cell
}
和JSONParser.swift
import Foundation
class JSONParser {
func titlesFromJSON(data: NSData) -> [String] {
var titles = [String]()
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject],
let feed = json["feed"] as? [String: AnyObject],
entries = feed["entry"] as? [[String: AnyObject]] {
for entry in entries {
if let name = entry["im:name"] as? [String: AnyObject],
label = name["label"] as? String {
titles.append(label)
}
}
}
} catch {
print("error parsing JSON: \(error)")
}
return titles
}
func imagesFromJSON(data: NSData) -> [String] {
var images = [String]()
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject],
let feed = json["feed"] as? [String: AnyObject],
entries = feed["entry"] as? [[String: AnyObject]] {
for entry in entries {
if let name = entry["im:image"]![0] as? [String: AnyObject],
label = name["label"] as? String {
images.append(label)
}
}
}
} catch {
print("error parsing JSON: \(error)")
}
return images
}
}
我有一个UITableViewCell的MyTableViewCell子类,包含一个UILabel和一个UIImageView。
我不知道是什么问题,为什么会出现这个错误。谢谢您的时间。我始终建议您避免使用强制展开,并采用更安全的代码方式(例如使用可选绑定)避免运行时错误。因此,您可以将代码更改为以下代码并避免运行时错误:
for entry in entries {
if let name = entry["im:image"], let value = name[0] as? [String: AnyObject],
label = value["label"] as? String {
images.append(label)
}
}
通过上述方法,可以避免使用强制展开
我希望这对您有所帮助。如果让name=entry[“im:image”],您的错误来自这一行
![0]作为?[String:AnyObject]
,当您首先使用可选绑定尝试强制转换为字典时,您正在进行强制展开,当然由于某些原因元素不存在。@VictorSigler谢谢,我如何修复它?请参阅下面的答案