Ios 使用JSON将图像从iTunes解析到tableviewcontroller

Ios 使用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

我正试图从中解析数据,标题被正确解析并显示,但解析图像时出现问题,我得到一个错误:“致命错误:在展开可选值时意外发现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 = [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谢谢,我如何修复它?请参阅下面的答案