tableView.reloadData期间索引超出范围

时间:2017-10-17 06:00:50

标签: swift uitableview alamofire swxmlhash

在某些刷新过程中,我遇到了性能问题和索引超出范围的错误。不是全部,但我正在努力解决它。

基本上,应用程序将从RSS源收集数据并将其显示在tableview中。这是我第一次使用我拥有的库,以及我第一次尝试正确制作tableview应用程序。

我认为刷新错误与我refresh()的位置以及我呼叫projects.removeAll()的位置有关。我已经尝试将它们移动到其他地方,我仍然遇到刷新问题。

我不确定为什么突然间我有滚动滞后。如果有人有时间快速查看我的代码并给我建议,并尝试帮我修复代码的刷新部分(修复数组越界错误),这将是惊人的。

感谢。

这是我的完整代码。

//
//  FirstViewController.swift
//  
//

import UIKit
import SWXMLHash
import Alamofire
import SafariServices

class FirstViewController: UITableViewController, SFSafariViewControllerDelegate {
    var projects = [[String]]()
    var xmlToParse = String()
    var postTitle = String()
    var postLink = String()
    var postAuthor = String()
    var postThumbnail = String()
    var postComments = String()
    var postPublishDate = String()
    var postVotes = String()
    var postVotesNeg = String()

    var dateFormatter = DateFormatter()

    override func viewDidLoad() {
        super.viewDidLoad()
        httpRequest("https://www.test.com/rss") { response in
        }

        // set up the refresh control
        self.refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
        self.refreshControl?.addTarget(self, action: #selector(refresh), for: UIControlEvents.valueChanged)
        self.tableView?.addSubview(refreshControl!)

        self.dateFormatter.dateStyle = DateFormatter.Style.short
        self.dateFormatter.timeStyle = DateFormatter.Style.long
    }

    func setup() {
        tableView.reloadData()
        print("Refreshed")
    }

    @objc func refresh(sender:AnyObject) {
        let now = NSDate()
        let updateString = "Last Updated at " + self.dateFormatter.string(from: now as Date)
        self.refreshControl?.attributedTitle = NSAttributedString(string: updateString)
        if (self.refreshControl?.isRefreshing)!
        {
            self.refreshControl?.endRefreshing()
            projects.removeAll()

        }
            httpRequest("https://www.test.com/rss") { response in
        }
    }

    func enumerate(indexer: XMLIndexer, level: Int) {
        for child in indexer.children {
            let name = child.element!.name
            print("\(level) \(name)")

            enumerate(indexer: child, level: level + 1)
        }
    }

    func httpRequest(_ section: String, completion: @escaping (String) -> Void) {
        Alamofire.request(section, method: .get).responseString { response in

            self.xmlToParse = response.result.value!
            let xml = SWXMLHash.parse(self.xmlToParse)

            for elem in xml["rss"]["channel"]["item"].all {
                self.postTitle = elem["title"].element!.text
                self.postLink = elem["link"].element!.text
                self.postAuthor = elem["dc:creator"].element!.text
                self.postThumbnail = (elem["media:thumbnail"].element?.attribute(by: "url")?.text)!
                self.postComments = elem["comments"].element!.text
                self.postPublishDate = elem["pubDate"].element!.text
                self.postVotes = (elem["test:meta"].element?.attribute(by: "votes-pos")?.text)!
                self.postVotesNeg = (elem["test:meta"].element?.attribute(by: "votes-neg")?.text)!

                self.projects.append([self.postTitle, self.postLink, self.postAuthor, self.postThumbnail, self.postPublishDate, self.postComments, self.postVotes, self.postVotesNeg])
            }
            completion(response.result.value!)
            self.setup()

        }
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        if let url = URL(string: self.projects[indexPath.row][1]) {
            let vc = SFSafariViewController(url: url)
            vc.delegate = self

            present(vc, animated: true)
        }
    }

    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        dismiss(animated: true)
    }

    func makeAttributedString(title: String, subtitle: String) -> NSAttributedString {
        let titleAttributes = [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: .headline), NSAttributedStringKey.foregroundColor: UIColor.black]
        let subtitleAttributes = [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: .subheadline), NSAttributedStringKey.foregroundColor: UIColor.gray]

        let titleString = NSMutableAttributedString(string: "\(title)\n", attributes: titleAttributes)
        let subtitleString = NSAttributedString(string: subtitle, attributes: subtitleAttributes)

        titleString.append(subtitleString)

        return titleString
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        let project = projects[indexPath.row]
        cell.textLabel?.attributedText = makeAttributedString(title: project[0], subtitle: "Author: " + project[2] + "\nPost Date: " + project[4] + "\nUpvotes: " + project[6] + "\nDownvotes: " + project[7] )

        let imageURL = URL(string: project[3])
        let data = try? Data(contentsOf: imageURL!)

        if data != nil {
            let image = UIImage(data: data!)
            cell.imageView?.image = image
        }
        return cell
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

0 个答案:

没有答案