我试图从这个data source解析数据,标题解析正确并显示,但解析图像时发生问题,我得到一个错误:“致命错误:意外地发现无同时展开的可选值” 这是我的代码:解析图像从iTunes使用JSON到tableviewcontroller
ViewModel.swift
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
}
}
而且我有一个包含一个UILabel和一个UIImageView的UITableViewCell的类MyTableViewCell子类。 我无法弄清楚是什么问题,为什么我得到这个错误。感谢您的时间。
你的错误来自这行'if let name = entry [“im:image”]![0] as? [String:AnyObject]',当你使用可选绑定来试图将其强制转换为字典时,首先进行强制展开,当然由于某种原因该元素不存在。 –
@VictorSigler谢谢,我该如何解决它? – Reem
查看我的回答如下 –