Swift 学习Using Swift mix and match, network: 写rss读者
有使用第三方库。因此,需要使用mix and match财产。
请指出错误,谢谢!
rss 阅读器,非常easy的代码。仅仅是为了学习swift语言而写。
1、BaseViewController.swift:
import Foundation
import UIKit //
// @brief Each controller must directly or indirectly inherit from BaseViewController to
// configure.
// @author huangyibiao
//
class BaseViewController : UIViewController {
// use to config ios7 or later and below ios7
var _originX: CGFloat = 0.0
var _screenHeight: CGFloat = 480.0
var _isIOS7Version = true override func viewDidLoad() {
super.viewDidLoad() _isIOS7Version = UIDevice.currentDevice().systemVersion >= "7.0"
// 难道坐标系统变化了?这么写法反面适配失败了
//_originX = _isIOS7Version ? 64.0 : 0.0
// 获取到的屏幕的高度怎么也仅仅有self.view的高度。不是整个屏幕的高度了?
_screenHeight = UIScreen.mainScreen().bounds.size.height
} override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// config navigations
let dict = [UITextAttributeTextColor: UIColor.whiteColor()]
self.navigationController.navigationBar.titleTextAttributes = dict
self.navigationController.navigationBar.barTintColor = UIColor.orangeColor()
}
}
2. need a model: FeedModel.swift
import Foundation //
// @brief Feed data model, just stores datas
// @author huangyibiao
//
class FeedModel : NSObject, NSCoding {
var _name: String?
var _url: String? // designated initializer
init(name: String? , url: String?) {
super.init()
_name = name
_url = url
} //
// The following functions are NSCoding protocol methods
//
// encode
func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeObject(_name, forKey: "_name")
aCoder.encodeObject(_url, forKey: "_url")
} // decode
init(coder aDecoder: NSCoder!) {
_name = aDecoder.decodeObjectForKey("_name") as? String
_url = aDecoder.decodeObjectForKey("_url") as? String
}
}
3. write an extension: Extension.swift
import Foundation
import UIKit //------------------------------------------------------------------------------------------
// @brief extension UIAlertView, making easily to use
// @author huangyibiao
//
extension UIAlertView {
// @brief Shows an alert view, default showing with "cancel" and "ok" buttons
// @param title: non-nil String object, shows the title
// @param message: non-nil String object, shows the message
// @return return non-nil UIAlertView object
class func showAlertView(title: String!, message: String!) -> UIAlertView! {
// in fact, swift provides UIAlerController to do the same thing
// in the future, it may be replaced by UIAlertController
let alert = UIAlertView()
alert.title = title
alert.message = message
alert.addButtonWithTitle("Cancel")
alert.addButtonWithTitle("Ok")
alert.show() return alert
}
} //------------------------------------------------------------------------------------------
// @brief 扩展String结构体。追加获取feed缓存路径的方法
// @author huangyibiao
//
extension String {
// @brief 获取缓存路径
// @param check: default value is true, meaning that needs to check is exist
// @return Optional String type, if nil, means no value at all, otherwise, returns path
//
static func feedCachePath(isCheck check: Bool = true) -> String? {
let path = NSHomeDirectory() + "/Documents/data"
if check {
if NSFileManager.defaultManager().fileExistsAtPath(path) {
return path
}
}
return path
}
}
4. need a feed manager: FeedManager.swift
import Foundation //
// @brief Here FeedManager is a singleton, use to manage feed data objects
// @author huangyibiao
// // never use this global variable directly, because directly using it may not
// has a value.
// I don't know how to make it invisible outside in swift
var g_sharedFeedManager: FeedManager! class FeedManager {
var _dataSource = NSMutableArray() // use to store FeedModel objects // singleton
class func sharedFeedManager() -> FeedManager! {
if g_sharedFeedManager == nil { // no value
g_sharedFeedManager = FeedManager()
}
return g_sharedFeedManager
} // designated initializer
init() { } // return the numbers of feed models
func count() -> Int {
return _dataSource.count
} // add model
func addFeedModel(feedModel: FeedModel!) {
// found whether is exist
for model: AnyObject in _dataSource {
let feedModelObject = model as FeedModel
if feedModelObject._name == feedModel._name {
return
}
}
_dataSource.addObject(feedModel)
saveAllFeeds()
} // remove model
func removeFeedModel(atIndex index: Int) {
assert(index >= 0 && index < count(), "out of range in array", file: "Extension.swift", line: 57) _dataSource.removeObjectAtIndex(index)
saveAllFeeds() // update local datas
} // obtain
func feedModel(atIndex index: Int) -> FeedModel {
assert(index >= 0 && index < count(), "out of range in array", file: "Extension.swift", line: 57) return _dataSource[index] as FeedModel
} func saveAllFeeds() {
let path = String.feedCachePath(isCheck: false)
if path { // 若已经存在。先清除
NSFileManager.defaultManager().removeItemAtPath(path, error: nil)
}
// 归档
NSKeyedArchiver.archiveRootObject(_dataSource, toFile: path)
} func loadAllFeeds() {
let path = String.feedCachePath()// default isCheck is true
if path {
let feedModels = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? NSArray
if feedModels {
_dataSource.addObjectsFromArray(feedModels)
}
}
}
}
5.need a HttpRequest: HttpRequest.swift
import Foundation @objc protocol HttpRequestDelegate {
// @brief when request finished, and will call this delegate method if comforms to
// @param request: an non-nil HttpRequest object
// @param downloadedData: you can do something with the parameter,
// which is the data downloaded from ns service
@optional func requestFinished(request: HttpRequest!, downloadedData: NSMutableData!) // @brief fail to download
@optional func requestFailed(request: HttpRequest!)
} //
// @brief 网络请示类,这里仅仅是简单实现,没有做缓存处理
// @author huangyibiao
//
class HttpRequest : NSObject, NSURLConnectionDelegate {
var _delegate: HttpRequestDelegate?
var _urlString: String?
var _connection: NSURLConnection?
var _downloadData: NSMutableData? init() {
super.init()
_downloadData = NSMutableData()
} // begin to request data
func startRequest(delegate: HttpRequestDelegate?, urlString: String!) {
cancelRequest() // cancel current request before a new request _delegate = delegate
_urlString = urlString // clear _downloadData
_downloadData!.resetBytesInRange(NSRange(location: 0, length: _downloadData!.length))
_downloadData!.length = 0 // update length var url = NSURL(string: _urlString)
var request = NSURLRequest(URL: url)
_connection = NSURLConnection(request: request, delegate: self)
_connection!.start()
} func cancelRequest() {
if _connection {
_connection!.cancel()
_connection = nil
}
} //
// The following funcs are NSURLConnectionDelegate methods
// download fail
func connection(connection: NSURLConnection!, didFailWithError error: NSError!){
_downloadData!.resetBytesInRange(NSRange(location: 0,length: _downloadData!.length));
_downloadData!.length = 0; _delegate?.requestFailed?(self)
} // receive data and append to the downloaded data
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
_downloadData!.appendData(data);
} // download finished
func connectionDidFinishLoading(connection: NSURLConnection!){
_delegate?.requestFinished!(self, downloadedData: _downloadData!);
}
}
7.write a root controller: RootViewController.swift
import Foundation
import UIKit class RootViewController : BaseViewController, UITableViewDelegate, UITableViewDataSource {
var _tableView: UITableView? override func viewDidLoad() {
self.title="网易Rss" let addButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 40))
addButton.setTitle("加入", forState: UIControlState.Normal)
addButton.titleLabel.font = UIFont.systemFontOfSize(12);
addButton.setTitleColor(UIColor.blackColor(), forState: .Normal);
addButton.addTarget(self, action: "onAddButtonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
var addButtonItem = UIBarButtonItem(customView: addButton);
super.navigationItem.rightBarButtonItem = addButtonItem; var aboutButton = UIButton(frame: CGRect(x: 0,y: 0,width: 50,height: 40))
aboutButton.setTitle("关于", forState: .Normal)
aboutButton.titleLabel.font = UIFont.systemFontOfSize(12);
aboutButton.setTitleColor(UIColor.blackColor(), forState: .Normal);
aboutButton.addTarget(self, action: "onAboutButtonClicked:", forControlEvents: .TouchUpInside)
var aboutButtonItem = UIBarButtonItem(customView: aboutButton);
super.navigationItem.leftBarButtonItem = aboutButtonItem; _tableView = UITableView(frame: self.view.bounds);
_tableView!.dataSource = self;
_tableView!.delegate = self;
self.view.addSubview(_tableView);
} override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
_tableView!.reloadData()
} //
// The following are UIButton event methods
//
// clicke add button
func onAddButtonClicked(sender: UIButton!) {
let rss = FeedRssListViewController()
self.navigationController.pushViewController(rss, animated: true)
} // clicked about button
func onAboutButtonClicked(sender: UIButton!) {
// call extension method
UIAlertView.showAlertView("关于", message: "參考thilong。欢迎学习swift语言,请勿用于商业用途")
} //
// The following are UITableViewDataSource protocol methods
//
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
return FeedManager.sharedFeedManager().count()
} func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!{
let cellIdentifier = "cellIdentifier" ;
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell;
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: cellIdentifier);
cell!.selectionStyle = UITableViewCellSelectionStyle.None;
} let model = FeedManager.sharedFeedManager().feedModel(atIndex: indexPath.row)
cell!.textLabel.text = model._name;
return cell;
} //
// The following are UITableViewDelegate protocol methods
//
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){
let model = FeedManager.sharedFeedManager().feedModel(atIndex: indexPath.row)
let detail = RssDetailViewController(model)
detail.hidesBottomBarWhenPushed = true
self.navigationController.pushViewController(detail, animated:true);
}
}
8.FeedRssListViewController.swift
import Foundation
import UIKit //
// @brief Rss contents for selected
// @author huangyibiao
//
class FeedRssListViewController : BaseViewController, UITableViewDelegate, UITableViewDataSource {
var _tableView: UITableView?
var _dataSources: Array<FeedModel> = [
FeedModel(name:"网易新闻", url:"http://news.163.com/special/00011K6L/rss_newstop.xml"),
FeedModel(name:"网易科技", url:"http://tech.163.com/special/000944OI/headlines.xml"),
FeedModel(name:"网易NBA", url:"http://sports.163.com/special/00051K7F/rss_sportslq.xml"),
FeedModel(name:"网易英超", url:"http://sports.163.com/special/00051K7F/rss_sportsyc.xml"),
FeedModel(name:"网易娱乐", url:"http://ent.163.com/special/00031K7Q/rss_toutiao.xml"),
FeedModel(name:"网易电影", url:"http://ent.163.com/special/00031K7Q/rss_entmovie.xml"),
FeedModel(name:"网易互联网", url:"http://tech.163.com/special/000944OI/hulianwang.xml"),
FeedModel(name:"网易IT界", url:"http://tech.163.com/special/000944OI/kejiyejie.xml"),
FeedModel(name:"网易汽车", url:"http://auto.163.com/special/00081K7D/rsstoutiao.xml"),
FeedModel(name:"网易数码", url:"http://tech.163.com/digi/special/00161K7K/rss_digixj.xml"),
FeedModel(name:"网易笔记本", url:"http://tech.163.com/digi/special/00161K7K/rss_diginote.xml"),
FeedModel(name:"网易手机", url:"http://mobile.163.com/special/001144R8/mobile163_copy.xml"),
FeedModel(name:"网易时尚", url:"http://lady.163.com/special/00261R8C/ladyrss1.xml"),
FeedModel(name:"网易星运", url:"http://lady.163.com/special/00261R8C/ladyrss4.xml"),
FeedModel(name:"网易游戏", url:"http://game.163.com/special/003144N4/rss_gametop.xml"),
FeedModel(name:"网易旅游", url:"http://travel.163.com/special/00061K7R/rss_hline.xml")
] override func viewDidLoad() {
super.viewDidLoad() self.title = "Feed Models" // config tableview
_tableView = UITableView(frame: self.view.bounds);
self.view.addSubview(_tableView);
_tableView!.dataSource = self
_tableView!.delegate = self;
} //
// @brief The following funcs are UITableViewDataSource protocol methods
//
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
return _dataSources.count;
} func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!{
let cellIdentifier = "cellIdentifier" ;
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell;
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: cellIdentifier);
cell!.selectionStyle = UITableViewCellSelectionStyle.None;
}
let model = _dataSources[indexPath.row] as FeedModel
cell!.textLabel.text = model._name;
return cell;
} //
// @brief The following funcs are UITableViewDelegate protocol methods
//
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){
let model = _dataSources[indexPath.row] as FeedModel;
FeedManager.sharedFeedManager().addFeedModel(model)
self.navigationController.popViewControllerAnimated(true);
}
}
9.RssDetailViewController.swift
import Foundation
import UIKit //
// @brief Detail rss content
// @author huangyibiao
//
class RssDetailViewController : BaseViewController, HttpRequestDelegate {
var _httpRequest: HttpRequest?
var _webView: UIWebView?
var _feedModel: FeedModel? init(_ feedModel: FeedModel) {
super.init(nibName: nil, bundle: nil) _feedModel = feedModel
} override func viewDidLoad() {
super.viewDidLoad() self.title = _feedModel!._name
_webView = UIWebView(frame: self.view.bounds)
self.view.addSubview(_webView) _httpRequest = HttpRequest()
_httpRequest!.startRequest(self, urlString: _feedModel!._url)
} //
// @brief The following funcs are HttpRequestDelegate protocol methods
//
func requestFinished(request: HttpRequest!, downloadedData: NSMutableData!) {
let doc = GDataXMLDocument(data: downloadedData, options: 0, error: nil)
if doc == nil {
UIAlertView.showAlertView("error", message: "read xml file error")
return;
}
var rootElement = doc.rootElement();
var titleNode = rootElement.nodeForXPath("/rss/channel/title", error: nil);
var linkNode = rootElement.nodeForXPath("/rss/channel/link", error: nil);
var channelNode = rootElement.nodeForXPath("/rss/channel", error: nil);
var items = doc.nodesForXPath("/rss/channel/item", error:nil);
var entrysBuilder : NSMutableString = NSMutableString();
var baseHTMLPath : NSString = NSBundle.mainBundle().pathForResource("FeedEntryList",ofType: "html");
var finalHTML : NSString = NSString.stringWithContentsOfFile(baseHTMLPath,
encoding: NSUTF8StringEncoding,error: nil);
for (var i = 0; i < items.count; i++){
var item = items[i] as GDataXMLElement;
var itemTitleNode = item.elementsForName("title")[0] as GDataXMLElement;
var itemDescriptionNode = item.elementsForName("description")[0] as GDataXMLElement;
var itemUrlNode : GDataXMLElement = item.elementsForName("guid")[0] as GDataXMLElement; var entryBuilder : NSMutableString = NSMutableString();
entryBuilder.appendString("<a href='");
// link here
var urlString : NSString! = itemUrlNode.stringValue();
var stringS = urlString.componentsSeparatedByString("/");
var finalString : NSString? = stringS[stringS.count - 1] as? NSString;
if finalString && finalString!.hasSuffix(".html"){
urlString = NSString(string:"http://3g.163.com/touch/article.html? docid=");
var docid : NSString = NSString(string:finalString!.stringByReplacingOccurrencesOfString(".html", withString:""));
urlString = urlString.stringByAppendingFormat("%@",docid);
} entryBuilder.appendString(urlString);
entryBuilder.appendString("'><div class='entry'><div class='entryTitle'>");
//title here
entryBuilder.appendString(itemTitleNode.stringValue());
entryBuilder.appendString("</div><div class='entryDescription'>");
//description here
var description : NSString = itemDescriptionNode.stringValue();
entryBuilder.appendString(description);
entryBuilder.appendString("</div></div></a>"); entrysBuilder.appendString(entryBuilder);
}
finalHTML = finalHTML.stringByReplacingOccurrencesOfString("[[ENTRYLIST]]",
withString: entrysBuilder); _webView!.loadHTMLString(finalHTML,baseURL: nil);
} // fail to download
func requestFailed(request: HttpRequest!) {
println("request failed" + _feedModel!._url!)
}
}
10.mix and match: SwiftRssReader-Bridging-Header
#import "GDataXMLNode.h"
#import "JSONKit.h"
11.源码:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Swift 学习Using Swift mix and match, network: 写rss读者的更多相关文章
- 【Swift学习】Swift编程之旅(三)
元组(tuples) tuples是将多个单一的值组合为一个复合的值.它可以包含任何类型的值,而不需要都是相同类型. 一.元组的创建 1. let http404error = (,"NOT ...
- 【Swift学习】Swift编程之旅(一)
学习一门新语言最经典的例子就是输出“Hello World!” print("Hello World!") swift就是这样来输出的. 如果你使用过其他语言,那么看上去是非常的熟 ...
- Swift 学习 用 swift 调用 oc
开发过程中 很可能 把swift不成熟的地方用成熟的oc 代码来弥补一下 , 下面简单来学习一下,我也是照着视频 学习的 卖弄谈不上 就是一次学习笔记, 具体问题还是具体分析吧. 需求 给展出出来的 ...
- 【Swift学习】Swift编程之旅---可选链(二十一)
可选链Optional Chaining是一种可以在当前值可能为nil的可选值上请求和调用属性.方法及下标的方法.如果可选值有值,那么调用就会成功:如果可选值是nil,那么调用将返回nil.多个调用可 ...
- 【Swift学习】Swift编程之旅---ARC(二十)
Swift使用自动引用计数(ARC)来跟踪并管理应用使用的内存.大部分情况下,这意味着在Swift语言中,内存管理"仍然工作",不需要自己去考虑内存管理的事情.当实例不再被使用时, ...
- 【Swift学习】Swift编程之旅---析构方法(十九)
在一个类的实例内存被释放之前,析构方法被立即调用.使用deinit关键字来声明析构方法,类似于构造方法用init来声明.析构方法只适用于类类型. 析构方法原理 Swift会自动释放不再需要的实例以 ...
- 【Swift学习】Swift编程之旅---构造方法(十八)
初始化是为了使用某个类.结构体或枚举类型的实例而进行的准备过程.这个过程包括为每个存储的属性设置一个初始值,然后执行新实例所需的任何其他设置或初始化. 初始化是通过定义构造器(Initialize ...
- 【Swift学习】Swift编程之旅---继承(十七)
在 Swift 中,继承是区分「类」与其它类型的一个基本特征.swift不支持多重继承.类可以调用和访问超类的方法,属性和subscripts下标,并且可以重写(override)这些方法,属性和附属 ...
- 【Swift学习】Swift编程之旅---方法(十五)
在Swift中结构体和枚举也能够定义方法,而在 Objective-C 中,类是唯一能定义方法的类型. 实例方法 实例方法是属于某个特定类.结构体或者枚举类型实例的方法,实例方法提供访问和修改实例属性 ...
随机推荐
- 讨论asp.net通过机器cookie仿百度(google)实现搜索input搜索提示弹出框自己主动
为实现自己主动弹出通过用户输入关键词相关的搜索结果,在这里,我举两个解决方案,对于两个不同的方案. 常用的方法是建立一个用户数据库中查找关系表.然后输入用户搜索框keyword异步调用数据表中的相关数 ...
- hdu 2074 堆放篮 好开心图纸标题
堆放篮 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 银行家算法java实现
关于银行家算法的理论知识,课本或者百度上有好多资料,我就不再多说了,这里把我最近写的银行家算法的实现带码贴出来. 由于这是我们的一个实验,对系统资源数和进程数都指定了,所以这里也将其指定了,其中系统资 ...
- 小米2S 中文和英文支持TWRP,真实双系统支持
经过我几天的努力小米2S的TWRP 的功能已经完美了. 支持功能 : 中文和英文显示能相互切换 真实双系统功能已经完成95%. 刷入手机方法.由于时间原因我只制作了img文件.没有制作成卡刷包格式. ...
- gcc #define 学习记录
//test.c #include <stdio.h> #include <stdlib.h> //字符串化运算符 #define EXPAND(name) ({ \ prin ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- [INS-32052] Oracle基文件夹和Oracle主文件夹位置同样
1.错误描写叙述 [INS-32052] Oracle基文件夹和Oracle主文件夹位置同样 2.错误原因 Oracle基文件夹和Oracle主文件夹位置同样 3.解决的方法 Oracle ...
- 采用Sambaserver由win平台,linux平台上传文件
1.构造yum [root@db /]# cd /etc/yum.repos.d/ [root@db yum.repos.d]# vi yum.repo --改动光盘挂载位置,enabled设置为启动 ...
- 集合hashCode()方法和equals()办法
1.哈希码: Object中的HashCode方法会返回该对象的的内存真实地址的整数化表示,这个形象的不是真正抵制的整数值就是哈希码. 2.利用哈希码向集合中插入数据的顺序? ...
- 写一个 docker 打击一系列手册
感谢您的关注,分享也再次给自己一个学习的.机会组织和总结.对未来一段时间内准备一个关于 docker 一系列的实际应用,其中的一些内容此前曾宣布.准备再次修改和整理. 以下是主要的文件夹中的一个: 创 ...