0

我正在尝试在应用程序内为我的网站制作 RSS 提要。我正在努力做到这一点,以便当用户单击我的 TableView 中的一个单元格时,它会将您带到已解析的特定帖子的链接。正在解析链接,但控制台给了我这个错误:

应用程序试图在 target 上推送一个 nil 视图控制器。

这是我的代码:

WebViewController.h

#import <Foundation/Foundation.h>

@interface WebViewController : UIViewController

@property (nonatomic, readonly) UIWebView *webView;

@end

WebViewController.m

#import "WebViewController.h"

@implementation WebViewController

-(void)loadView
{
    CGRect screenFrame = [[UIScreen mainScreen] applicationFrame];
    UIWebView *wv = [[UIWebView alloc] initWithFrame:screenFrame];
    [wv setScalesPageToFit:YES];

    [self setView:wv];
}

-(UIWebView *)webView
{
    return (UIWebView *)[self view];
}

@end

MasterViewController.h我的 TableView

#import <UIKit/UIKit.h>

// A forward declaration; we'll import the header in the .m
@class RSSChannel;
@class WebViewController;

@interface MasterViewController : UITableViewController
<NSXMLParserDelegate>
{
    NSURLConnection *connection;
    NSMutableData *xmlData;

    RSSChannel *channel;
}
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) IBOutlet UINavigationItem *navigationBar;
@property (nonatomic, strong) WebViewController *webViewController;

- (void)fetchEntries;

@end

主视图控制器.m

#import "MasterViewController.h"
#import "WebViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"


@interface MasterViewController () {
    NSMutableArray *_objects;
}
@end

@implementation MasterViewController
@synthesize tableView = _tableView;
@synthesize navigationBar;
@synthesize webViewController;



- (void)awakeFromNib
{
    [super awakeFromNib];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self fetchEntries];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

#pragma mark - Table View

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIImage *myImage = [UIImage imageNamed:@"SephardiJewsHeader.png"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:myImage];
    imageView.frame = CGRectMake(0,-1,320,93);

    return imageView;

}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 93;
}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSLog(@"The amount of items in the table: %u", [[channel items] count]);
    return [[channel items] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                      reuseIdentifier:@"UITableViewCell"];

    }
     RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];

    [[cell textLabel] setText:[item title]];
    [[cell detailTextLabel] setText:[item date]];
    return cell;

}


- (void)fetchEntries
{
    // Create a new data container for the stuff that comes back from the service
    xmlData = [[NSMutableData alloc] init];

    // Construct a URL that will ask the service for what you want -
    // Note we can concatenate literal strings together on multiple lines in this way it 
    // results in a single NSString instance
    NSURL *url = [NSURL URLWithString:
                  @"http://sephardijews.com/feed/"];

    // Putting the URL we made into an NSURLRequest, so we can connect to the url data that we specifed
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    // Creating a connecting that will exchange this request for the data from the URL we specifed
    connection = [[NSURLConnection alloc] initWithRequest:req
                                                 delegate:self 
                                         startImmediately:YES];
}

- (void)parser:(NSXMLParser *)parser
    didStartElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI
   qualifiedName:(NSString *)qualifedName 
    attributes:(NSDictionary *)attributeDict
{
    NSLog(@"%@ found a %@ element", self, elementName);
    if ([elementName isEqual:@"channel"]) {

        // If the parser saw a channel, create new instance, store in our ivar
        channel = [[RSSChannel alloc] init];

        // Give the channel object a pointer back to ourselves for later
        [channel setParentParserDelegate:self];

        // Set the parser's delegate to the channel object
        [parser setDelegate:channel];
    }
}


// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
    // Add the incoming chunk of data to the container we are keeping
    // The data always comes in the correct order
    [xmlData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
    // Create the parser object with the data received from the web service
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];

    // Give it a delegate - don't worry about the warning
    [parser setDelegate:self];

    // Tell it to start parsing - the documet will be parsed and the delegate of NSXMLParser will get all of its delegate messages sent to it before this line finishes execution - it is blocking
    [parser parse];

    // Get rid of the XML data as we no longer need it
    xmlData = nil;

    // Get rid of the connection, no longer need it
    connection = nil;

    // Reload the table
    [[self tableView] reloadData];
    NSLog(@"%@\n %@\n %@\n", channel, [channel title], [channel infoString]);

}

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
    // Release the connection object, we are done with it cause' there is no connection
    // Setting the connection to nil will stop the connection because it is nothing/0
    connection = nil;

    // Release the xmlData object. We stopped to connection to put the data in the xmlData object, so we set it to nil also
    xmlData = nil;

    // Grab the description of the error object passed to us, so we can tell the user
    NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];

    // Create and show an alert view to the user with the error string to tell them the error in the process of the connection
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error" 
                                                 message:errorString
                                                delegate:nil 
                                       cancelButtonTitle:@"OK"
                                       otherButtonTitles:nil];

    [av show];
}
/*  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    WebViewController *aWebViewController = [[WebViewController alloc] init];
    self.webViewController = aWebViewController;
    [self.navigationController pushViewController:self.webViewController animated:YES];
    RSSItem *entry = [[channel items] objectAtIndex:[indexPath row]];
    NSURL *url = [NSURL URLWithString:[entry link]];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    [[webViewController webView] loadRequest:req];
    [[webViewController navigationItem] setTitle:[entry title]];

} */



- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showPost"]) {
        WebViewController *awebViewController = [segue destinationViewController];
        self.webViewController = awebViewController;
        NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow];
        RSSItem *entry = [[channel items] objectAtIndex:[selectedRow row]];
        NSURL *url = [NSURL URLWithString:[entry link]];
        NSURLRequest *req = [NSURLRequest requestWithURL:url];
        [[webViewController webView] loadRequest:req];
        [[webViewController navigationItem] setTitle:[entry title]];
    }
}
@end

谢谢你的帮助!

4

1 回答 1

1

您的 WebViewController 没有在任何地方初始化。在你的试试这个tableView:didSelectRowAtIndexPath:

WebViewController *aWebViewController = [WebViewController alloc] init];
self.webViewController = aWebViewController;
[self.navigationController pushViewController:self.webViewController animated:YES];
[aWebViewController release];

如果您使用 Storyboard,请添加一个视图控制器并将其类更改为 WebViewController。在 Storyboard 中的 MasterViewController 中,右键单击一个单元格并将 push segue 连接到 WebViewController。单击 push segue 并将其标识符更改为“showPost”之类的东西。

返回MasterViewController.m并从中删除您的代码tableView:didSelectRowAtIndexPath:并添加以下内容:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showPost"]) {
        WebViewController *aWebViewController = [segue destinationViewController];
        NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow];
        RSSItem *entry = [[channel items] objectAtIndex:[selectedRow row]];
        NSURL *url = [NSURL URLWithString:[entry link]];
        NSURLRequest *req = [NSURLRequest requestWithURL:url];
        [aWebViewController.webView loadRequest:req];
        aWebViewController.title = entry.title
    }
}
于 2012-07-29T01:54:06.467 回答