RSS Reader for MAC Code

该项目代码来自于王志刚 《软件创富密码:iPhone应用程序开发攻略之深入浅出Objective-C 2.0》一书,这是一个图例很丰富的书,适合入门阅读。

 

首先给出最终接图,接着给代码:

 

代码

//
//  AppController.h
//  RSS Reader
//
//  Created by longx-app on 13-9-14.
//  Copyright (c) 2013年 longx-app. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface AppController : NSTableView <NSTableViewDataSource>
{
    NSXMLDocument* document;
    
    IBOutlet id linkTextField;
    IBOutlet id titleTextField;
    IBOutlet id urlTextField;
    
    IBOutlet NSTableView *tableView;
}

- (IBAction)readURL:(id)sender;

@end

 

//
//  AppController.m
//  RSS Reader
//
//  Created by longx-app on 13-9-14.
//  Copyright (c) 2013年 longx-app. All rights reserved.
//

#import "AppController.h"

@implementation AppController

// NSTableView数据资源
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    if (!document) {
        return 0;
    }
    
    // 取得 “/rss/channel/item” 节点
    NSArray*    nodes;
    nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL];
    if ([nodes count] == 0) {
        // 取得 “/rdf:RDF/item” 节点
        nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL];
    }
    if ([nodes count] == 0) {
        // 取得 “/feed/entry” 节点
        nodes = [document nodesForXPath:@"/feed/entry" error:NULL];
    }
    
    // 返回节点的个数
    return [nodes count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    
    // 判断实例变量document是否有效,无效则退出处理
    if (!document) {
        return nil;
    }
    
    // 使用identifier方法取得参数tableColumn的识别符,此识别符会用于后面列的判别
    id identifier;
    identifier = [tableColumn identifier];
    // 对 XML 文档使用 nodesForXPath: 方法取得 item 节点数组
    // 取得 “/rss/channel/item” 节点
    NSArray*    nodes;
    nodes = [document nodesForXPath:@"/rss/channel/item" error:NULL];
    if ([nodes count] == 0) {
        // 取得 “/rdf:RDF/item” 节点
        nodes = [document nodesForXPath:@"/rdf:RDF/item" error:NULL];
    }
    if ([nodes count] == 0) {
        // 取得 “/feed/entry” 节点
        nodes = [document nodesForXPath:@"/feed/entry" error:NULL];
    }
    
    // 根据行参数row取得指定行的item节点
    NSXMLNode*  node;
    node = [nodes objectAtIndex:row];
    // 以下使用识别符来判断具体的列,首先是title列,从item节点中取得title节点,找到
    // title的值后,返回此值
    if ([identifier isEqual:@"title"]) {
        // 取得 “title” 的字符串
        nodes = [node nodesForXPath:@"title" error:NULL];
        if ([nodes count] == 1) {
            node = [nodes objectAtIndex:0];
            return [node stringValue];
        }
    }
    
    // 其次是link列,从item节点,找到后返回link值。
    if ([identifier isEqual:@"link"]) {
        // 取得 ”link“ 的字符串
        nodes = [node nodesForXPath:@"link" error:NULL];
        if ([nodes count] == 1) {
            node = [nodes objectAtIndex:0];
            return [node stringValue];
        }
    }
    
    return nil;
}

- (IBAction)readURL:(id)sender
{
    NSURL* url;
    url = [NSURL URLWithString:[urlTextField stringValue]];
    
    // 创建XML文档,这里的URL如果是远程文件的话,必须以http://或ftp://开头,如果是
    // 本地的,必须以file:///开头
    document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:0 error:NULL];
    if (!document) {
        return;
    }
    
    // 取得 “/rss/channel/title” 节点
    NSArray*    nodes;
    nodes = [document nodesForXPath:@"/rss/channel/title" error:NULL];
    if ([nodes count] == 0) {
        // 取得 “/rdf:RDF/channel/title” 节点
        nodes = [document nodesForXPath:@"/rdf:RDF/channel/title" error:NULL];
    }
    if ([nodes count] == 0) {
        // 取得 “/feed/title” 节点
        nodes = [document nodesForXPath:@"/feed/title" error:NULL];
    }
    
    if ([nodes count] == 1) {
        NSXMLNode* titleNode;
        titleNode = [nodes objectAtIndex:0];
        
        // 设置RSS文档的标题
        NSString*   title;
        title = [titleNode stringValue];
        [titleTextField setStringValue:title];
    }
    
    // 取得 “/rss/channel/link” 节点
    nodes = [document nodesForXPath:@"/rss/channel/link" error:NULL];
    if ([nodes count] == 0) {
        // 取得 “/rdf:RDF/channel/link” 节点
        nodes = [document nodesForXPath:@"/rdf:RDF/channel/link" error:NULL];
    }
    if ([nodes count] == 0) {
        // 取得 “/feed/link” 节点
        nodes = [document nodesForXPath:@"/feed/link" error:NULL];
    }
    
    if ([nodes count] == 1) {
        NSXMLNode* linkNode;
        linkNode = [nodes objectAtIndex:0];
        
        // 设置RSS文档对应网页的URL
        NSString* link;
        link = [linkNode stringValue];
        [linkTextField setStringValue:link];
    }
    
    // 表格数据读入
    [tableView reloadData];
}

@end

 

其中,readURL:动作主要完成对远程RSS文档的读取,因为RSS文档的版本众多,为取得RSS文档的标题以及URL,方法中进行了多重判断处理,请参照RSS版本说明来阅读上述代码。

 
posted @ 2013-09-14 20:52  loveq369  阅读(219)  评论(0编辑  收藏  举报