gpt4 book ai didi

ios - 将 XML 文件中的链接加载到 UIWebView(SIGABRT 错误)

转载 作者:行者123 更新时间:2023-11-28 22:11:02 26 4
gpt4 key购买 nike

我一直在尝试解析 XML 文件,以便使用后台提取从网站获取文章。

有人给了我这个问题的答案here .

但是,他的回答导致了 SIGABRT 错误。

有人可以看看我的代码,看看我的问题是什么吗?提前致谢。

我的代码:

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;
}

- (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];

}
}


-(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> {
NSMutableDictionary *item;
NSMutableString * currentLink;
}

@property (retain, nonatomic) NSMutableString *currentLink;

-(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"]) {
item = [[NSMutableDictionary alloc] init];
self.currentLink = [[NSMutableString alloc] init];
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;

[item setObject:self.currentLink forKey:@"link"];


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;
[self.currentLink appendString: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

DetailViewController.h(这是包含包含我的 UIWebView 的 uiviewcontroller 的文件):

 #import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController<UIWebViewDelegate> {
NSDictionary *item;
}

@property (retain, nonatomic) NSDictionary *item;
@property (retain, nonatomic) IBOutlet UIWebView *itemSummary;

@end

DetailViewController.m:

 #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

如果您想自己运行该项目,可以在 Github 上找到它 here

注意 使用链接时,Xcode 项目位于“你的 TF2 指南”下。

感谢所有提供帮助的人!

崩溃日志

2014-04-08 16:33:05.611 Your Guide to TF2[499:70b] -[UINavigationController fetchNewDataWithCompletionHandler:]: unrecognized selector sent to instance 0x1090aa930
2014-04-08 16:33:05.755 Your Guide to TF2[499:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController fetchNewDataWithCompletionHandler:]: unrecognized selector sent to instance 0x1090aa930'
*** First throw call stack:
(
0 CoreFoundation 0x000000010189a795 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001015fd991 objc_exception_throw + 43
2 CoreFoundation 0x000000010192bbad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010188c09d ___forwarding___ + 973
4 CoreFoundation 0x000000010188bc48 _CF_forwarding_prep_0 + 120
5 Your Guide to TF2 0x0000000100004819 -[AppDelegate application:performFetchWithCompletionHandler:] + 345
6 UIKit 0x000000010026e0b5 -[UIApplication _handleOpportunisticFetchWithSequenceNumber:] + 170
7 UIKit 0x000000010025b200 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1761
8 UIKit 0x000000010025ebe8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
9 UIKit 0x000000010026faab -[UIApplication handleEvent:withNewEvent:] + 3092
10 UIKit 0x000000010026ff1e -[UIApplication sendEvent:] + 79
11 UIKit 0x00000001002602be _UIApplicationHandleEvent + 618
12 GraphicsServices 0x00000001039a2bb6 _PurpleEventCallback + 762
13 GraphicsServices 0x00000001039a267d PurpleEventCallback + 35
14 CoreFoundation 0x000000010181c819 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
15 CoreFoundation 0x000000010181c5ee __CFRunLoopDoSource1 + 478
16 CoreFoundation 0x0000000101845ab3 __CFRunLoopRun + 1939
17 CoreFoundation 0x0000000101844f33 CFRunLoopRunSpecific + 467
18 UIKit 0x000000010025e4bd -[UIApplication _run] + 609
19 UIKit 0x0000000100260043 UIApplicationMain + 1010
20 Your Guide to TF2 0x0000000100004ce3 main + 115
21 libdyld.dylib 0x0000000101f295fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

AppDelegate.m

 #import "AppDelegate.h"
#import "NewsViewController.h"
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
// Override point for customization after application launch.
// Uncomment to change the background color of navigation bar
[[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0xb35326)];

// Uncomment to change the color of back button
//[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

// Uncomment to assign a custom backgroung image
//[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"tf2_logo.png"] forBarMetrics:UIBarMetricsDefault];

// Uncomment to change the back indicator image
/*
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back_btn.png"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back_btn.png"]];
*/

// Uncomment to change the font style of the title
/*
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1);
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName,
shadow, NSShadowAttributeName,
[UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:21.0], NSFontAttributeName, nil]];
*/


return YES;
}

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NSDate *fetchStart = [NSDate date];

NewsViewController *viewController = (NewsViewController *)self.window.rootViewController;

[viewController fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
completionHandler(result);

NSDate *fetchEnd = [NSDate date];
NSTimeInterval timeElapsed = [fetchEnd timeIntervalSinceDate:fetchStart];
NSLog(@"Background Fetch Duration: %f seconds", timeElapsed);

}];
}

最佳答案

问题出在你的-[AppDelegate application:performFetchWithCompletionHandler:]这行是错误的:

NewsViewController *viewController = (NewsViewController *)self.window.rootViewController;

Root View Controller 是一个 UINavigationController,但您假设它是一个 NewsViewController。那应该是:

UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
NewsViewController *viewController = (NewsViewController *)[[navController viewControllers] objectAtIndex:0];

关于ios - 将 XML 文件中的链接加载到 UIWebView(SIGABRT 错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22925618/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com