parsingXML文件中的链接并将其推送到UIWebView

我一直在试图parsingXML文件,以便从使用后台获取的网站获取文章。

这个教程的链接在这里 。

我已经成功地完成了教程并parsing了我的XML文件,但是不是通过safari在外部推送链接,当用户点击文章时,我希望他们能够在UIWebView中看到它。

我将如何在我的代码中实现这个?

我的CODE:

NewsViewController.h(这个文件加载一个运行后台获取文章的uitableview):

#import <UIKit/UIKit.h> @interface NewsViewController : UIViewController<UITableViewDelegate, UITableViewDataSource> @property (weak, nonatomic) IBOutlet UITableView *tblNews; - (IBAction)removeDataFile:(id)sender; -(void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; @end 

NewsViewController.m:

  #import "NewsViewController.h" #define NewsFeed @"http://www.teamfortress.com/rss.xml" #import "XMLParser.h" @interface NewsViewController () @property (nonatomic, strong) UIRefreshControl *refreshControl; @property (nonatomic, strong) NSArray *arrNewsData; @property (nonatomic, strong) NSString *dataFilePath; -(void)refreshData; -(void)performNewFetchedDataActionsWithDataArray:(NSArray *)dataArray; @end @implementation NewsViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // 1. Make self the delegate and datasource of the table view. [self.tblNews setDelegate:self]; [self.tblNews setDataSource:self]; // 2. Specify the data storage file path. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docDirectory = [paths objectAtIndex:0]; self.dataFilePath = [docDirectory stringByAppendingPathComponent:@"newsdata"]; // 3. Initialize the refresh control. self.refreshControl = [[UIRefreshControl alloc] init]; [self.refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged]; [self.tblNews addSubview:self.refreshControl]; // 4. Load any saved data. if ([[NSFileManager defaultManager] fileExistsAtPath:self.dataFilePath]) { self.arrNewsData = [[NSMutableArray alloc] initWithContentsOfFile:self.dataFilePath]; [self.tblNews reloadData]; } } - (IBAction)removeDataFile:(id)sender { if ([[NSFileManager defaultManager] fileExistsAtPath:self.dataFilePath]) { [[NSFileManager defaultManager] removeItemAtPath:self.dataFilePath error:nil]; self.arrNewsData = nil; [self.tblNews reloadData]; } } -(void)refreshData{ XMLParser *xmlParser = [[XMLParser alloc] initWithXMLURLString:NewsFeed]; [xmlParser startParsingWithCompletionHandler:^(BOOL success, NSArray *dataArray, NSError *error) { if (success) { [self performNewFetchedDataActionsWithDataArray:dataArray]; [self.refreshControl endRefreshing]; } else{ NSLog(@"%@", [error localizedDescription]); } }]; } -(void)performNewFetchedDataActionsWithDataArray:(NSArray *)dataArray{ // 1. Initialize the arrNewsData array with the parsed data array. if (self.arrNewsData != nil) { self.arrNewsData = nil; } self.arrNewsData = [[NSArray alloc] initWithArray:dataArray]; // 2. Reload the table view. [self.tblNews reloadData]; // 3. Save the data permanently to file. if (![self.arrNewsData writeToFile:self.dataFilePath atomically:YES]) { NSLog(@"Couldn't save data."); } } -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.arrNewsData.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"idCellNewsTitle"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"idCellNewsTitle"]; } NSDictionary *dict = [self.arrNewsData objectAtIndex:indexPath.row]; cell.textLabel.text = [dict objectForKey:@"title"]; cell.detailTextLabel.text = [dict objectForKey:@"pubDate"]; return cell; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 80.0; } //THIS IS THE SECTION OF CODE THAT OPENS THE LINKS -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSDictionary *dict = [self.arrNewsData objectAtIndex:indexPath.row]; NSString *newsLink = [dict objectForKey:@"link"]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:newsLink]]; } //END OF THE SECTION -(void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ XMLParser *xmlParser = [[XMLParser alloc] initWithXMLURLString:NewsFeed]; [xmlParser startParsingWithCompletionHandler:^(BOOL success, NSArray *dataArray, NSError *error) { if (success) { NSDictionary *latestDataDict = [dataArray objectAtIndex:0]; NSString *latestTitle = [latestDataDict objectForKey:@"title"]; NSDictionary *existingDataDict = [self.arrNewsData objectAtIndex:0]; NSString *existingTitle = [existingDataDict objectForKey:@"title"]; if ([latestTitle isEqualToString:existingTitle]) { completionHandler(UIBackgroundFetchResultNoData); NSLog(@"No new data found."); } else{ [self performNewFetchedDataActionsWithDataArray:dataArray]; completionHandler(UIBackgroundFetchResultNewData); NSLog(@"New data was fetched."); } } else{ completionHandler(UIBackgroundFetchResultFailed); NSLog(@"Failed to fetch new data."); } }]; } @end 

XMLParser.h(该文件parsingXML以获取标题,发布date,链接等)

 #import <Foundation/Foundation.h> @interface XMLParser : NSObject <NSXMLParserDelegate> -(id)initWithXMLURLString:(NSString *)xmlUrlString; -(void)startParsingWithCompletionHandler:(void(^)(BOOL success, NSArray *dataArray, NSError *error))completionHandler; @end 

XMLParser.m:

  #import "XMLParser.h" @interface XMLParser() @property (nonatomic, strong) NSXMLParser *xmlParser; @property (nonatomic, strong) NSOperationQueue *operationQueue; @property (nonatomic, strong) NSMutableArray *arrParsedData; @property (nonatomic, strong) NSString *currentElement; @property (nonatomic, strong) NSString *newsTitle; @property (nonatomic, strong) NSString *newsPubDate; @property (nonatomic, strong) NSString *newsLink; @property (nonatomic, strong) void (^completionHandler)(BOOL, NSArray *, NSError *); @property (nonatomic) BOOL isNewsItem; @property (nonatomic) BOOL allowedData; -(void)parse; -(void)endParsingWithError:(NSError *)error; @end @implementation XMLParser -(id)initWithXMLURLString:(NSString *)xmlUrlString{ self = [super init]; if (self) { self.xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:xmlUrlString]]; self.xmlParser.delegate = self; self.operationQueue = [NSOperationQueue new]; self.currentElement = @""; self.isNewsItem = NO; self.allowedData = NO; } return self; } #pragma mark - Public method implementation -(void)startParsingWithCompletionHandler:(void (^)(BOOL, NSArray *, NSError *))completionHandler{ self.completionHandler = completionHandler; NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(parse) object:nil]; [self.operationQueue addOperation:operation]; } #pragma mark - Private method implementation -(void)parse{ if (self.xmlParser != nil) { [self.xmlParser parse]; } } -(void)endParsingWithError:(NSError *)error{ BOOL success = (error == nil) ? YES : NO; self.completionHandler(success, self.arrParsedData, error); } #pragma mark - NSXMLParserDelegate method implementation -(void)parserDidStartDocument:(NSXMLParser *)parser{ if (self.arrParsedData != nil) { [self.arrParsedData removeAllObjects]; self.arrParsedData = nil; } self.arrParsedData = [[NSMutableArray alloc] init]; } -(void)parserDidEndDocument:(NSXMLParser *)parser{ [self performSelectorOnMainThread:@selector(endParsingWithError:) withObject:nil waitUntilDone:NO]; } -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ if ([elementName isEqualToString:@"item"]) { self.isNewsItem = YES; } if (self.isNewsItem) { if ([elementName isEqualToString:@"title"] || [elementName isEqualToString:@"pubDate"] || [elementName isEqualToString:@"link"]) { self.allowedData = YES; } } self.currentElement = elementName; } -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ if ([elementName isEqualToString:@"item"]) { self.isNewsItem = NO; NSDictionary *dict = @{@"title": self.newsTitle, @"pubDate": self.newsPubDate, @"link": self.newsLink }; [self.arrParsedData addObject:dict]; } if (self.isNewsItem) { if ([elementName isEqualToString:@"title"] || [elementName isEqualToString:@"pubDate"] || [elementName isEqualToString:@"link"]) { self.allowedData = NO; } } } -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if (self.allowedData) { if ([self.currentElement isEqualToString:@"title"]) { self.newsTitle = string; } else if ([self.currentElement isEqualToString:@"pubDate"]){ self.newsPubDate = string; } else if ([self.currentElement isEqualToString:@"link"]){ self.newsLink = string; } } } -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ [self performSelectorOnMainThread:@selector(endParsingWithError:) withObject:parseError waitUntilDone:NO]; } -(void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError{ [self performSelectorOnMainThread:@selector(endParsingWithError:) withObject:validationError waitUntilDone:NO]; } @end 

如果你想自己运行这个项目,你可以在Github上find它

注意当使用链接时,Xcode项目在“您的TF2指南”下。

感谢任何人的帮助!

添加一个UIViewController ,包含一个UIWebView 。 改变你didSelectRowAtIndexPath

 - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ } - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([segue.identifier isEqualToString:@"detail"]){ DetailViewController *detail = segue.destinationViewController; NSIndexPath *indexPath = [self.tblNews indexPathForSelectedRow]; detail.item = [self.arrNewsData objectAtIndex:indexPath.row]; } } 

在你的Detailview头文件中:

 #import <UIKit/UIKit.h> @interface DetailViewController : UIViewController<UIWebViewDelegate> { NSDictionary *item; } @property (retain, nonatomic) NSDictionary *item; @property (retain, nonatomic) IBOutlet UIWebView *itemSummary; @end 

在你的实现中:

 #import "DetailViewController.h" @interface DetailViewController () @end @implementation DetailViewController @synthesize item; @synthesize itemSummary = _itemSummary; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; _itemSummary.delegate = self; _itemSummary.scalesPageToFit = YES; NSURL* url = [NSURL URLWithString:[item objectForKey:@"link"]]; [_itemSummary loadRequest:[NSURLRequest requestWithURL:url]]; // Do any additional setup after loading the view. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end 

NSMutableDictionaryNSMutableStrring添加到parsing器头文件中:

 @interface XMLParser : NSObject <NSXMLParserDelegate> { NSMutableDictionary *item; NSMutableString * currentLink; } @property (retain, nonatomic) NSMutableString *currentLink; 

在你的实现中:

在你的didStartElement中:

 if ([elementName isEqualToString:@"item"]) { item = [[NSMutableDictionary alloc] init]; self.currentLink = [[NSMutableString alloc] init]; self.isNewsItem = YES; } 

在你的didEndElement中:

 if ([elementName isEqualToString:@"item"]) { self.isNewsItem = NO; [item setObject:self.currentLink forKey:@"link"]; 

在你find的字符:

 else if ([self.currentElement isEqualToString:@"link"]){ self.newsLink = string; [self.currentLink appendString:string]; } 

在你的故事板:将你的tableviewcontrollerembedded到导航控制器中,从你的tableview中添加一个push segue到详细视图,添加“detail”的标识符。

还对你的git进行了修改。