- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试解析 XML 文件,以便使用后台提取从网站获取文章。
教程的链接是here .
我已经成功完成了教程并解析了我的 XML 文件,但是当用户单击文章时,我希望他们在 UIWebView 中看到它,而不是通过 safari 将链接推送到外部。
我如何在我的代码中实现这个?
我的代码:
NewsViewController.h(此文件加载一个 uitableview,该 View 运行后台获取以获取文章):
#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(此文件解析 XML 以获取标题、发布日期、链接等)
#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 here 上找到它
注意使用链接时,Xcode 项目位于“Your Guide to 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
将 NSMutableDictionary
和 NSMutableStrring
添加到您的解析器 header :
@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"];
在你的 foundCharacters 中:
else if ([self.currentElement isEqualToString:@"link"]){
self.newsLink = string;
[self.currentLink appendString:string];
}
在你的 Storyboard中:将你的 tableviewcontroller 嵌入到导航 Controller 中,从你的 tableview 添加一个 push segue 到详细 View ,添加标识符“detail”。
同时将更改提交到您的 git。
关于ios - 解析 XML 文件中的链接并将其推送到 UIWebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22888880/
我正在寻找一种方法来观察 UIWebView 中文本选择已开始或结束的通知。一旦出现大头针和蓝色选择覆盖,它会自动更新 Javascript 选择和范围对象,但是当您点击选择并结束时,似乎没有一种干净
我需要获取 UIWebView 的 url在用户单击一次后显示。 我尝试在 UIWebView 下放置一个按钮,该按钮调用确定 url 的方法。 ,但这样按钮不起作用。我试过在 UIWebView 上
我正在使用 AFNetworking UIWebView 类别,我想知道是否有任何方法可以通过证书固定检查加载 url。 最好的问候, 最佳答案 UIWebView 没有向它公开任何直接 API,但它
我想从应用程序中禁用长触摸。我无法控制在 WebView 上加载的 HTML。 最佳答案 在 webViewDidFinishLoad委托(delegate)我在加载的 html 页面上运行一个禁用长
每个人: 我可以通过将scalesPageToFit 设置为YES 来启用缩放。但是,我如何知道 UIWebView 是否正在缩放? 有人知道吗? 提前致谢。 最佳答案 已解决。 向 XXXViewC
我在每个单元格中都有几个自定义单元格和 WebView 。现在,我的要求是找到要在 webview 上加载的 HTML 字符串的高度,然后根据此更改自定义单元格高度和 webview 高度。 我知道可
我想嵌入一个 UIWebView进入我的 MonoTouch 应用程序,用于尚未本地实现的区域。 为了对网站进行身份验证,我想设置一个包含当前 session key 的 cookie。 我尝试创建一
我的应用程序使用 UIWebview,它在 iOS 5 和 iOS 6 中运行良好。但是,当我在 Xcode 5 中构建并运行相同的代码时,它不会在 iOS 7 中加载网页。 - (void)web
我有一个嵌入式网站,有很多链接,但 WebView 窗口相当小,允许放大和缩小列表上方的较大图像。如果可能的话,我需要 webview 响应到带有第二个嵌入式 UIWebView 的新 Control
我正在 Monotouch 上构建 iPhone 应用程序。我的项目的一部分使用本地网站内容。我将网站使用的所有 html、js、css 和图像复制到一个文件夹中,并将其导入到我的 monotouch
在下面的示例中,infoScroller 是一个UIWebView,println(HTMLDescription) 打印一个可爱的 HTML 字符串。但是,尝试 loadHTMLString 会出现
我有一个包含多个 UIWebView 的应用程序。我有一个 UIWebView 保存所有业务逻辑和其他 UIWebViews 用于显示目的。但是,我发现如果 UIWebView 不是最后一个加载的,断
我的一个包含链接的 View Controller 底部有一个 Web View 。我想要做的是,当用户单击 Web View 中的一个链接时,它会打开一个 Web View ,该 View 占据屏幕
我已经在 webview 中实现了 ScrollView 的委托(delegate)。由于,iOS 5 默认 ScrollView 不再响应 didZoom 事件。为什么会出现这种行为? 最佳答案 i
我正在使用新的 Xcode UI Testing来自 XCTest Framework与 Xcode 7 GM .我有一个带有简单 UIWebView 的应用程序(它只是一个带有 web View 和
我无法从 UIWebView 响应中获取 header ,因为响应显然没有被缓存。有解决方法吗?我试过来自 here 的代码. 我的应用程序使用混合的原生 iOS View Controller 和
我想制作一个简单的应用程序,其中具有自定义内容的 UIWebView 将具有多个指向具有类似内容的其他页面的链接(顶部有一个导航栏,只有一个后退按钮)。我阅读了this的答案问题,但是我不确定是否应该
我制作了一个简单的测试项目,其中仅包含一个 UIWebView,其中 UIView 填充了窗口。当 UIWebView 的宽度与 UIView 相同时,一切正常。当UIWebView的宽度小于容器的宽
在我的 iPad 应用程序中,有一个显示文本内容的 UIWebview。当我按住并选择一个文本时,应该会弹出一个带有 2 个自定义菜单的菜单。 说,|菜单 1 |菜单2 | 但似乎 COPY 菜单也会
是否可以在 uiwebview.js 中加载应用商店链接。我尝试在 uiwebview 中打开它,但它没有加载到那里。我不希望用户在单击我的应用程序中的网址时离开我的应用程序。可能吗? 问候 潘卡杰
我是一名优秀的程序员,十分优秀!