前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swift 学习Using Swift mix and match, network: 写rss读者

Swift 学习Using Swift mix and match, network: 写rss读者

作者头像
全栈程序员站长
发布2022-07-06 10:49:16
1.3K0
发布2022-07-06 10:49:16
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是全栈君。

有使用第三方库。因此,需要使用mix and match财产。

请指出错误,谢谢!

rss 阅读器,非常easy的代码。仅仅是为了学习swift语言而写。

1、BaseViewController.swift:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
#import "GDataXMLNode.h"
#import "JSONKit.h"

11.源码:

该样品的源入口

版权声明:本文博客原创文章,博客,未经同意,不得转载。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/117208.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月9,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档