将HTML数据加载到各种视图中

时间:2014-08-08 23:19:19

标签: ios objective-c xcode5 html-parsing

我正在尝试为网站3v3live.com创建原生应用,但我无法从网站加载数据(没有错误或警告;我正在使用Hpple)。例如,在我的第一个视图(“Home”)中,我想通过容器视图将3v3live.com主页中的所有文本加载到动态表视图中。所以我创建了一个UITableViewController(“homeTVClass”)的子类,并在我的Home视图中为表视图创建了一个.h文件中的IBOutlet。

我的.h文件:

#import <UIKit/UIKit.h>

@interface homeTVClass : UITableViewController

@property (weak,nonatomic) NSArray * homeArrayTVC;
- (id) fromURL: (NSString*) urlS ParseDataWithPath: (NSString*) path WithType: (NSString*) typeOfDataToReturn;
@property (strong, nonatomic) IBOutlet UITableView *homeText;

@end

我的.m文件:

#import "homeTVClass.h"
#import "ViewController.h"
#import "TFHpple.h"
#import "TFHppleElement.h"

@interface homeTVClass ()
- (id) fromURL: (NSString*) urlS ParseDataWithPath: (NSString*) path WithType: (NSString*) typeOfDataToReturn;
@end

@implementation homeTVClass

@synthesize homeArrayTVC;
@synthesize homeText;



- (id) fromURL: (NSString*) urlS ParseDataWithPath: (NSString*) path WithType: (NSString*) typeOfDataToReturn
{
    // Set up request
    NSURL * url = [NSURL URLWithString:urlS];
    NSData * gatheredData = [NSData dataWithContentsOfURL:url];

    // set up parser
    TFHpple * Parser = [TFHpple hppleWithHTMLData: gatheredData];

    // parse data
    NSArray * Nodes = [Parser searchWithXPathQuery:path];

    // Set up array to be returned
    NSMutableArray * array = [[NSMutableArray alloc]initWithCapacity:0];

    // Insert parsed data into "array"
    for (TFHppleElement * element in Nodes)
    {
        // tell returned data it's class
        id dataType = NSClassFromString(typeOfDataToReturn);
        id returnedData = [[dataType alloc] init];
        // set returnedData's value and insert it into "array"
        returnedData= [[element firstChild] content];
        [array addObject:returnedData];
    }
    return array;
    [self.tableView reloadData];// added for TV
}

- (void) getData
{
    // load data from website into an array that entire file can access
    [homeArrayTVC arrayByAddingObjectsFromArray:
     [self fromURL:@"http://www.3v3live.com" ParseDataWithPath: @"//div[@class = 'description']/h3" WithType:@"NSString"]]; // home
}



- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self getData];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [homeArrayTVC count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"myCell" forIndexPath:indexPath];

    // Configure the cell...
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCell"];
    }

    cell.textLabel.text = [homeArrayTVC objectAtIndex: indexPath.row]; // use data from homeArrayTVC to create cells
    return cell;
}



// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return NO;
}
@end

1 个答案:

答案 0 :(得分:0)

您的代码中存在很多问题。首先,在方法返回后不能调用任何方法。因此需要颠倒以下几行:

    return array;
    [self.tableView reloadData];// added for TV
}

但是,由于这是其他问题之一,暂时取消reloadTable:来电(您稍后会将其移至getData电话):

    // [self.tableView reloadData];// added for TV
    return array;
}

接下来,您的方法应该只返回NSArray而不是id。除非您有正当理由,否则不指定返回类型不是您应该做的事情,而您不是这样:

- (NSArray*) fromURL: (NSString*) urlS ParseDataWithPath: (NSString*) path WithType: (NSString*) typeOfDataToReturn

现在该方法在定义中具有正确的返回类型,通过在fromURL方法中更改此方法,更改方法以返回NSArray而不是NSMutableArray:

return [array copy]; // this returns an immutable copy of the NSMutableArray

接下来,您永远不会初始化homeArrayTVC。基本上它将是零,它将永远不会是零。只要你意识到它是一个不可变的数组,这意味着你不能改变内容(添加或删除数组中的东西)。鉴于下一个错误和我提供的修复,这可能没问题。

最后,您需要了解NSArrays的工作原理。以下方法对fromURL:调用的结果没有做任何事情:

- (void) getData
{
    // load data from website into an array that entire file can access
    [homeArrayTVC arrayByAddingObjectsFromArray:
     [self fromURL:@"http://www.3v3live.com" ParseDataWithPath: @"//div[@class = 'description']/h3" WithType:@"NSString"]]; // home
}

基本上,当你调用[arrayObj arrayByAddingObjectsFromArray:otherArray];时,它会返回一个包含两个数组内容的新数组。出于某种原因,您试图将Web调用的结果附加到nil数组,该数组返回nil。然后你不会对arrayByAddingObjectsFromArray:调用的结果做任何事情。所以它是零的事实并不重要。总而言之,我认为你真正想做的就是保存fromURL:电话的结果。要做到这一点,试试这个(我也会将不正确的reloadTable调用移到这里,因为在将结果分配给homeArrayTVC属性之前你不想这样做:

- (void) getData
{
    // load data from website into an array that entire file can access
    homeArrayTVC =
     [self fromURL:@"http://www.3v3live.com" ParseDataWithPath: @"//div[@class = 'description']/h3" WithType:@"NSString"]; // home
    [self.tableView reloadData];// added for TV
}