2016-06-06 24 views
3

我试图从这个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子类。 我无法弄清楚是什么问题,为什么我得到这个错误。感谢您的时间。

+0

你的错误来自这行'if let name = entry [“im:image”]![0] as? [String:AnyObject]',当你使用可选绑定来试图将其强制转换为字典时,首先进行强制展开,当然由于某种原因该元素不存在。 –

+0

@VictorSigler谢谢,我该如何解决它? – Reem

+0

查看我的回答如下 –

回答

2

我总是建议您避免使用强制解包并采用更安全的代码方式(例如使用可选绑定)来避免运行时错误。所以,你可以更改您的代码下面的代码,避免运行时错误:

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) 
    } 
} 

在您避免使用武力,解缠上述方式。

我希望这对你有所帮助。

+1

非常感谢! :) – Reem