XML数据保存在NSUserDefaults或Documents Directory中

时间:2016-06-24 10:42:16

标签: ios swift swift2 nsuserdefaults nsdocumentdirectory

我正在创建一个简单的新闻应用程序,并尝试在NSUserDefaults中保存(标题,描述,日期,图像及其数据)以供离线阅读。我想在NSUserDefaults中保存数据时,它会在离线状态下显示,并且当新数据可用时,它会重写或替换以前的数据。 我知道如何在NSUserDefaults中保存字符串数组,但不清楚如何在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!)!)
                }
            }
        }
    }


}

2 个答案:

答案 0 :(得分:0)

在Apple不推荐的NSUserDefault中保存大数据,我们不应保存大数据。 NSUserDefault或Keychain我们用来存储“用户名”,“密码”等信息较少。

您可以使用CoreDataSqlite对数据进行操作。

答案 1 :(得分:0)

为了将图像保存到NSUserDefaults,您需要将其转换为NSData,因为那里只允许某些类型。

关于在那里存储信息以供离线查看的想法....这听起来更像是Applications Document目录的工作。您应该能够在对象中使用NSCoding协议,并通过调用将所有信息写入磁盘 NSKeyedArchiver:archiveRootObject:主对象上的toFile,它将在所有子对象上调用encodeWithCoder。