Last active
September 9, 2019 10:30
-
-
Save daryadariaa/ed166992784239385b83704620e66de3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
protocol ChangedTitleDelegate { | |
func titleChanged(title: String) | |
} | |
class DetailViewController: UIViewController { | |
var delegate : ChangedTitleDelegate? | |
var itemTitle = "" | |
var itemDescription = "" | |
let attributes : [NSAttributedString.Key: Any] = [ | |
.font: UIFont.systemFont(ofSize: 23), | |
.foregroundColor: UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5), | |
] | |
var attributedTitle: NSAttributedString { | |
return NSAttributedString(string: itemDescription.convertHtml().string, attributes: attributes) | |
} | |
@IBOutlet weak var tableView: UITableView! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
delegate?.titleChanged(title: itemTitle) | |
setupNavBar() | |
tableView.rowHeight = UITableView.automaticDimension | |
} | |
func setupNavBar() { | |
title = itemTitle | |
navigationItem.largeTitleDisplayMode = .always | |
} | |
} | |
// MARK: - Extensions | |
extension DetailViewController: UITableViewDelegate, UITableViewDataSource { | |
func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return 1 | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) | |
cell.textLabel?.attributedText = attributedTitle | |
cell.textLabel?.numberOfLines = 0 | |
return cell | |
} | |
} | |
extension String { | |
func convertHtml() -> NSAttributedString { | |
guard let data = data(using: .utf8) else { return NSAttributedString() } | |
do { | |
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) | |
} catch { return NSAttributedString() } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import CoreData | |
class NewsViewController: UIViewController { | |
private var items = [Item]() | |
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext | |
var isLoading = false | |
@IBOutlet weak var segmentedControl: UISegmentedControl! | |
@IBOutlet weak var tableView: UITableView! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
tableView.rowHeight = UITableView.automaticDimension | |
tableView.estimatedRowHeight = 120.0 | |
fetchData() | |
tableView.reloadData() | |
} | |
// MARK: - Fetching data | |
private func fetchData() { | |
let parser = FeedParser() | |
let queue = DispatchQueue.global(qos: .background) | |
let newsURL = url(category: self.segmentedControl.selectedSegmentIndex) | |
isLoading = true | |
queue.async { | |
parser.parseFeed(url: newsURL) { (rssItems) in | |
for item in rssItems { | |
let newItem = Item(context: self.context) | |
newItem.title = item.title | |
newItem.fdescription = item.description | |
newItem.category = item.category | |
self.items.append(newItem) | |
} | |
self.saveItems() | |
DispatchQueue.main.async { | |
self.isLoading = false | |
self.tableView.reloadData() | |
} | |
} | |
} | |
} | |
@IBAction func switchTableViewAction(_ sender: UISegmentedControl) { | |
fetchData() | |
tableView.reloadData() | |
} | |
private func url(category: Int) -> String { | |
let urlString: String | |
switch category { | |
case 0: urlString = "http://feeds.reuters.com/reuters/businessNews" | |
case 1: urlString = "http://feeds.reuters.com/reuters/entertainment" | |
default: urlString = "" | |
} | |
return urlString | |
} | |
// MARK: - Model manipulation methods | |
func saveItems() { | |
do { try context.save() } | |
catch { print("Error saving items: \(error)") } | |
} | |
func loadItems() { | |
let request : NSFetchRequest<Item> = Item.fetchRequest() | |
do { items = try context.fetch(request) } | |
catch { print("Error fetching data from context: \(error)") } | |
} | |
} | |
// MARK: - Extensions | |
extension NewsViewController: UITableViewDataSource, UITableViewDelegate { | |
func numberOfSections(in tableView: UITableView) -> Int { | |
switch segmentedControl.selectedSegmentIndex { | |
case 0: return 1 | |
case 1: return 2 | |
default: return 1 | |
} | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
if isLoading { | |
return 1 | |
} else { | |
return items.count | |
} | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
if isLoading { | |
let cell = tableView.dequeueReusableCell(withIdentifier: | |
"LoadingCell", for: indexPath) | |
let spinner = cell.viewWithTag(100) as! | |
UIActivityIndicatorView | |
spinner.startAnimating() | |
return cell | |
} else { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NewsTableViewCell | |
let item = items[indexPath.item] | |
cell.item = item | |
return cell | |
} | |
} | |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
let item = items[indexPath.row] | |
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController | |
vc.itemTitle = item.title! | |
vc.itemDescription = item.fdescription! | |
navigationController?.pushViewController(vc, animated: true) | |
tableView.deselectRow(at: indexPath, animated: true) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainTableViewController: UITableViewController, ChangedTitleDelegate { | |
var timer = Timer() | |
var timeString = "" | |
var titleLabel : String? | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(timeNowString), userInfo: nil, repeats: true) | |
} | |
// MARK: - Table view data source | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return 3 | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) | |
switch indexPath.row { | |
case 0: | |
cell.textLabel?.text = "My Name" | |
cell.detailTextLabel?.text = "Daria" | |
case 1: | |
cell.textLabel?.text = "Date and time" | |
cell.detailTextLabel?.text = timeNowString() as String | |
case 2: | |
cell.textLabel?.text = titleLabel | |
cell.detailTextLabel?.text = "" | |
default: | |
break | |
} | |
return cell | |
} | |
@objc func timeNowString() -> NSString { | |
let date = NSDate() | |
let formatter = DateFormatter() | |
formatter.locale = NSLocale(localeIdentifier:"en_US") as Locale | |
formatter.dateFormat = "MM/dd/yyyy, HH:mm:ss" | |
let timeString = formatter.string(from: date as Date) | |
return timeString as NSString | |
} | |
func titleChanged(title: String) { | |
titleLabel = title | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import UIKit | |
import CoreData | |
struct RSSItem { | |
var title : String | |
var link : String | |
var description : String | |
var category : String | |
var pubDate : String | |
} | |
class FeedParser: NSObject, XMLParserDelegate | |
{ | |
private var rssItems: [RSSItem] = [] | |
private var currentElement = "" | |
private var currentTitle: String = "" { | |
didSet { | |
currentTitle = currentTitle.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) | |
} | |
} | |
private var currentLink: String = "" { | |
didSet { | |
currentLink = currentLink.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) | |
} | |
} | |
private var currentDescription: String = "" { | |
didSet { | |
currentDescription = currentDescription.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) | |
} | |
} | |
private var currentCategory: String = "" { | |
didSet { | |
currentCategory = currentCategory.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) | |
} | |
} | |
private var currentPubDate: String = "" { | |
didSet { | |
currentPubDate = currentPubDate.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) | |
} | |
} | |
private var parserCompletionHandler: (([RSSItem]) -> Void)? | |
func parseFeed(url: String, completionHandler: (([RSSItem]) -> Void)?) | |
{ | |
self.parserCompletionHandler = completionHandler | |
let request = URLRequest(url: URL(string: url)!) | |
let urlSession = URLSession.shared | |
let task = urlSession.dataTask(with: request) { (data, response, error) in | |
guard let data = data else { | |
if let error = error { | |
print("Failure! \(error.localizedDescription)") | |
} else { | |
print("Success! \(response!)") | |
} | |
return | |
} | |
let parser = XMLParser(data: data) | |
parser.delegate = self | |
parser.parse() | |
} | |
task.resume() | |
} | |
// MARK: - XML Parser Delegate | |
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) | |
{ | |
currentElement = elementName | |
if currentElement == "item" { | |
currentTitle = "" | |
currentLink = "" | |
currentDescription = "" | |
currentCategory = "" | |
currentPubDate = "" | |
} | |
} | |
func parser(_ parser: XMLParser, foundCharacters string: String) | |
{ | |
switch currentElement { | |
case "title" : currentTitle += string | |
case "link" : currentLink += string | |
case "description" : currentDescription += string | |
case "category" : currentCategory += string | |
case "pubDate" : currentPubDate += string | |
default: break | |
} | |
} | |
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) | |
{ | |
if elementName == "item" { | |
let rssItem = RSSItem(title: currentTitle, link: currentLink, description: currentDescription, category: currentCategory, pubDate: currentPubDate) | |
self.rssItems.append(rssItem) | |
} | |
} | |
func parserDidEndDocument(_ parser: XMLParser) { | |
parserCompletionHandler?(rssItems) | |
} | |
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) | |
{ | |
print("Failure! \(parseError.localizedDescription)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment