2016-06-24 94 views
-1

我正在製作一個簡單的新聞應用程序,並嘗試在NSUserDefaults中保存(標題,描述,日期,圖像及其數據)以供離線閱讀。我希望當它將數據保存在NSUserDefaults中時,它會在脫機狀態下顯示,並且當新數據可用時,它將重寫或替換之前的數據。 我知道如何將字符串數組保存在NSUserDefaults中,但沒有正確地知道如何將圖像保存在NSUserDefaults中。我試圖製作保存數據的邏輯,並檢查它是否有新的數據可用,但沒有成功,啓動屏幕需要更多時間才能消失,是由於從服務器加載數據還是由於互聯網連接速度慢? 任何人都可以檢查我的代碼修復它。 感謝將XML數據保存在NSUserDefaults或文檔目錄中

class ViewController2: UIViewController ,NSXMLParserDelegate { 

    let newsDefaults = NSUserDefaults.standardUserDefaults() 

    @IBOutlet weak var tableView: UITableView! 

    var parser = NSXMLParser() 
    var posts = NSMutableArray() 
    var elements = NSMutableDictionary() 
    var element = NSString() 
    var title1 = NSMutableString() 
    var date = NSMutableString() 
    var link = NSMutableString() 
    var des = NSMutableString() 
    var img2 = NSMutableString() 


    var NSUserDefaultsTitle : [NSString] = [] 
    var NSUserDefaultsDate : [NSString] = [] 
    var NSUserDefaultsDes : [NSString] = [] 

    var NSUserDefaultsImage : [UIImage] = [] 

    typealias CompletionHandler = (image: UIImage) -> Void 

    var attrsUrl : [String : NSString]! 
    var urlPic : NSString? 

    var postLink: String = String() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.configure() 

     self.beginParsing() 
    } 

    override func viewWillAppear(animated: Bool) { 
//  if let HaveTitle = newsDefaults.objectForKey("t"){ 
//   NSUserDefaultsTitle = HaveTitle.mutableCopy() as! [NSString] 
//  } 
//  if let HaveDate = newsDefaults.objectForKey("d"){ 
//   NSUserDefaultsDate = HaveDate.mutableCopy() as! [NSString] 
//  } 
//  if let HaveDes = newsDefaults.objectForKey("des"){ 
//   NSUserDefaultsDes = HaveDes.mutableCopy() as! [NSString] 
//  } 
//  if let imageData = newsDefaults.objectForKey("imgData"){ 
//   NSUserDefaultsImage = imageData.mutableCopy() as! [UIImage] 
//  } 
// 
//  print(newsDefaults.objectForKey("d")) 
    } 

    func beginParsing() 
    { 
     posts = [] 
     parser = NSXMLParser(contentsOfURL:(NSURL(string: "http://www.voanews.com/api/zq$omekvi_"))!)! 
     parser.delegate = self 
     parser.parse() 

     tableView!.reloadData() 
    } 

    //XMLParser Methods 

    func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) 
    { 
     element = elementName 
     if (elementName as NSString).isEqualToString("item") 
     { 
      elements = NSMutableDictionary() 
      elements = [:] 
      title1 = NSMutableString() 
      title1 = "" 
      date = NSMutableString() 
      date = "" 
      link = NSMutableString() 
      link = "" 
      des = NSMutableString() 
      des = "" 
      img2 = NSMutableString() 
      img2 = "" 
     } 
     if elementName == "enclosure" { 
      attrsUrl = attributeDict as [String: NSString] 
      urlPic = attrsUrl["url"] 
      print(urlPic!, terminator: "") 

     } 
    } 

    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) 
    { 
     if (elementName as NSString).isEqualToString("item") { 
      if !title1.isEqual(nil) { 
       elements.setObject(title1, forKey: "title") 
      } 
      if !date.isEqual(nil) { 
       elements.setObject(date, forKey: "pubDate") 
      } 
      if !link.isEqual(nil) { 
       elements.setObject(link, forKey: "link") 
      } 
      if !des.isEqual(nil){ 
       elements.setObject(des, forKey: "description") 
      } 
      if !img2.isEqual(nil){ 
       elements.setObject(urlPic!, forKey: "enclosure") 
      } 

      posts.addObject(elements) 
// 
//   if let HaveData = newsDefaults.objectForKey("post"){ 
// 
//   }else{ 
//    
////    newsDefaults.setObject(self.posts.valueForKey("title"), forKey: "t") 
////    newsDefaults.setObject(self.posts.valueForKey("pubDate"), forKey: "d") 
////    newsDefaults.setObject(self.posts.valueForKey("description"), forKey: "des") 
//     
//    newsDefaults.setObject(posts, forKey: "post") 
//     
       print("elementName") 
//   } 
     } 
     print("didEndElement") 

    } 

    func parser(parser: NSXMLParser, foundCharacters string: String) 
    { 
     if element.isEqualToString("title") { 
      title1.appendString(string) 
     } else if element.isEqualToString("pubDate") { 
      date.appendString(string) 
      print(date) 
     } 
     else if element.isEqualToString("link"){ 
      link.appendString(string) 
     }else if element.isEqualToString("description"){ 
      des.appendString(string) 
     }else if element.isEqualToString("enclosure"){ 
      img2.appendString(string) 
     } 
     print("foundCharacter") 
    } 

    private func configure() { 
     self.navigationController?.navigationBar.titleTextAttributes = [NSFontAttributeName: UIFont.boldSystemFontOfSize(20.0), NSForegroundColorAttributeName: UIColor.whiteColor()] 

     self.tableView.registerNib(UINib(nibName: "2ImageCell", bundle: nil), forCellReuseIdentifier: "imageCell") 
     self.tableView.delegate = self 
     self.tableView.dataSource = self 

     self.fillNavigationBar(color: UIColor(red: 252.0/255.0, green: 0, blue: 0, alpha: 1.0)) 

    } 

    private func fillNavigationBar(color color: UIColor) { 
     if let nav = self.navigationController { 
      nav.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default) 
      nav.navigationBar.shadowImage = UIImage() 
      for view in nav.navigationBar.subviews { 
       if view.isKindOfClass(NSClassFromString("_UINavigationBarBackground")!) { 
        if view.isKindOfClass(UIView) { 
         (view as UIView).backgroundColor = color 
        } 
       } 
      } 
     } 
    } 
} 

extension ViewController2: UITableViewDelegate, UITableViewDataSource { 

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     self.tableView.deselectRowAtIndexPath(indexPath, animated: true) 

     let view = ImageModalView2.instantiateFromNib() 
     view.des.text = posts.objectAtIndex(indexPath.row).valueForKey("description") as? String 

     downloadFileFromURL(NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!, completionHandler:{(img) in 
      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       view.image = img 
      }) 
     }) 

     let window = UIApplication.sharedApplication().delegate?.window! 
     let modal = PathDynamicModal.show(modalView: view, inView: window!) 
     view.closeButtonHandler = {[weak modal] in 
      modal?.closeWithLeansRandom() 
      return 
     } 
    } 

    @IBAction func printData(sender: AnyObject) { 
     print(NSUserDefaultsImage) 

    } 

    func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     return 80.0 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return posts.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = self.tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as! ImageCell2 
//  if let picURL = user["picture"].string, url = NSURL(string: picURL) { 
//   if let data = NSData(contentsOfURL: url) { 
//    cell!.imageView?.image = UIImage(data: data) 
//   } 
     cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String 
//  if NSUserDefaultsImage    { 
//   cell.sideImageView.image = NSUserDefaultsImage[indexPath.row] 
//  }else{ 
     downloadFileFromURL(NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!, completionHandler:{(img) in 
      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       cell.sideImageView.image = img 
//    self.NSUserDefaultsImage.append(img) 
//    print(img) 
//    self.newsDefaults.setObject(self.NSUserDefaultsImage, forKey: "imgData") 
      }) 
     }) 
// } 
     //cell.date.text = posts.objectAtIndex(indexPath.row).valueForKey("pubDate") as? String 
     //cell.sideImageView?.contentMode = UIViewContentMode.ScaleAspectFit 
     //cell.sideImageView?.image = image 
     cell.titleLabel.userInteractionEnabled = false 
     cell.titleLabel.editable = false 
     cell.titleLabel.selectable = false 
     return cell 
    } 


    func downloadFileFromURL(url1: NSURL?,completionHandler: CompletionHandler) { 
     // download code. 
     if let url = url1{ 
      let priority = DISPATCH_QUEUE_PRIORITY_HIGH 
      dispatch_async(dispatch_get_global_queue(priority, 0)) { 
       let data = NSData(contentsOfURL: url) 
       if data != nil { 
        print("image downloaded") 
        completionHandler(image: UIImage(data: data!)!) 
       } 
      } 
     } 
    } 


} 

回答

0

爲了將圖像保存到NSUserDefaults,您需要將它轉換爲NSData,因爲只有某些類型允許在那裏。

至於在那裏存儲信息離線觀看的想法....這聽起來更像是應用程序文檔目錄的工作。您應該能夠在對象中使用NSCoding協議,並通過在主對象上調用 NSKeyedArchiver:archiveRootObject:toFile將所有信息寫入磁盤,並且它將調用所有子對象上的encodeWithCoder。

0

在保存在NSUserDefault大型數據不推薦蘋果,我們不應該保存大量的數據。我們使用NSUserDefault或Keychain來存儲「用戶名」,「密碼」等少量信息。

您可以使用CoreDataSqlite對Data進行操作。