I am having performance issues and index out of range errors during some refreshes. Not all, but I am struggling to troubleshoot it.
Basically, the app will collect data from an RSS feed and display it in a tableview. This is my first time using the libraries that I have, and my first time trying to properly make tableview app.
I believe the refresh error has to do with where I am refresh()
as well as where I am calling projects.removeAll()
. I have tried moving them to other places and I still get the refresh issue.
I am not sure why all of a sudden I have scrolling lag. If anyone has time to quickly review my code and give me suggestions, as well as try and help me fix the refresh section of the code (to fix the array out of bounds error) that would be amazing.
Thanks.
Here is my complete code.
//
// 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()
}
}