标签:
这个App是用来读取 Official Google Blog 的内容,然后显示出来。
用了新建工程时用了 Master-Detail Application 这个模板。用了Core Data用来存储内容,不过每次启动App还是会删除内容,然后重新下载最新的20条。所以如果没有网络的时候打开不显示内容。
在原工程的基础上,我在Core Data中增加了date这项,为了排列时按照时间排列。获取的内容中有published和updated两个时间,用published好一些。这里只简单的转了String而不是Date类型。
//
// MasterViewController.swift
// Blog Reader
//
// Created by zcdll on 16/1/24.
// Copyright © 2016年 ZC. All rights reserved.
//
import UIKit
import CoreData
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var detailViewController: DetailViewController? = nil
var managedObjectContext: NSManagedObjectContext? = nil
override func viewDidLoad() {
super.viewDidLoad()
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let url = NSURL(string: "https://www.googleapis.com/blogger/v3/blogs/10861780/posts?key=AIzaSyCxL3Iltcd-oLc-dFUtdDG9TTuJGWilsYw")!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { (data, response, error) -> Void in
if error != nil {
print(error)
} else {
if let data = data {
//print(NSString(data: data, encoding: NSUTF8StringEncoding))
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
if jsonResult.count > 0 {
if let items = jsonResult["items"] as? NSArray {
let request = NSFetchRequest(entityName: "BlogItems")
request.returnsObjectsAsFaults = false
do {
let results = try context.executeFetchRequest(request)
if results.count > 0 {
for result in results {
context.deleteObject(result as! NSManagedObject)
do { try context.save() } catch {}
}
}
} catch {
print("Context fetched failed")
}
for item in items {
if let title = item["title"] as? String {
if let content = item["content"] as? String {
if let date = item["published"] as? String {
let updatedDate = date.componentsSeparatedByString("-08:00")[0]
print(updatedDate)
//print(title)
//print(content)
let newPost: NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName("BlogItems", inManagedObjectContext: context)
newPost.setValue(title, forKey: "title")
newPost.setValue(content, forKey: "content")
newPost.setValue(updatedDate, forKey: "date")
}
}
}
//print(items)
}
}
}
} catch {}
}
}
}
task.resume()
// Do any additional setup after loading the view, typically from a nib.
if let split = self.splitViewController {
let controllers = split.viewControllers
self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
}
override func viewWillAppear(animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.collapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Segues
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
self.configureCell(cell, atIndexPath: indexPath)
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let context = self.fetchedResultsController.managedObjectContext
context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//print("Unresolved error \(error), \(error.userInfo)")
abort()
}
}
}
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
cell.textLabel!.text = object.valueForKey("title")!.description
}
// MARK: - Fetched results controller
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("BlogItems", inManagedObjectContext: self.managedObjectContext!)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//print("Unresolved error \(error), \(error.userInfo)")
abort()
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
case .Move:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
/*
// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed.
func controllerDidChangeContent(controller: NSFetchedResultsController) {
// In the simplest, most efficient, case, reload the table view.
self.tableView.reloadData()
}
*/
}
//
// DetailViewController.swift
// Blog Reader
//
// Created by zcdll on 16/1/24.
// Copyright © 2016年 ZC. All rights reserved.
//
import UIKit
class DetailViewController: UIViewController {
@IBOutlet weak var webview: UIWebView!
var detailItem: AnyObject? {
didSet {
// Update the view.
self.configureView()
}
}
func configureView() {
// Update the user interface for the detail item.
if let detail = self.detailItem {
if let postWebView = self.webview {
postWebView.loadHTMLString(detail.valueForKey("content")!.description, baseURL: NSURL(string: "https://googleblog.blogspot.com/"))
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.configureView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
标签:
原文地址:http://www.cnblogs.com/zcdll/p/5154965.html