在开始之前,我想我应该让大家知道我是一个没有正式背景的自学初学者。
我的目标:将解析后的HTML数据从www.3v3live.com显示到我的应用中的各种视图中。
总体实施计划:我将创建一个可重用的方法,我可以调用它来解析网站的不同页面。它将有三个参数,包括:url,Xpath查询和数据类型(作为字符串输入并通过方法转换为类)。该方法应在数组中以数据类型(来自第三个参数)返回收集的数据。
我的错误:1)"没有已知的选择器类方法parseData :::' 2)"选择器没有已知的类方法' stringFromArray:'
我的OutPut:无
我尝试修复错误:1)我已将它们添加到.h文件和.m界面 2)我已经添加了一个协议(这里的答案推荐) 3)我已将方法转换为实例方法(并返回) 4)我已经清理并运行了项目
注意:错误位于" textSet"中的行。最底层的方法,以及" makeSlideShow"和" getText"方法是我的新方法的前兆错误(前兆也是错误的)。
我的代码(忽略评论):
(ViewController.h
#import <UIKit/UIKit.h>
@protocol dataParsingVC <NSObject>
+ (id) stringFromArray: (NSArray*) arr;
+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn;
@end
@interface ViewController : UIViewController <NSURLConnectionDataDelegate>
// Drop Down Menu Buttons
@property (weak, nonatomic) IBOutlet UIButton *scheduleButton;
@property (weak, nonatomic) IBOutlet UIButton *newsButton;
@property (weak, nonatomic) IBOutlet UIButton *photosButton;
@property (weak, nonatomic) IBOutlet UIButton *docsButton;
@property (weak, nonatomic) IBOutlet UIButton *stagesButton;
@property (weak, nonatomic) IBOutlet UIButton *faqsButton;
@property (weak, nonatomic) IBOutlet UIButton *resultsButton;
@property (weak, nonatomic) IBOutlet UIButton *contactButton;
@property (weak, nonatomic) IBOutlet UIButton *finderButton;
- (IBAction)menuButton:(UIBarButtonItem *)sender;// Menu Button Open & Close
// WV = Web View; use as few as possible
@property (weak, nonatomic) IBOutlet UIWebView *hostATournamentWV; // for the poll
// SV = scroll view
@property (weak, nonatomic) IBOutlet UIScrollView *menuSV;
@property (weak, nonatomic) IBOutlet UIScrollView *homeSideTabsSV;
// Slide Show Image View
@property (weak, nonatomic) IBOutlet UIImageView *ssIV;
// TV = text view
@property (weak, nonatomic) IBOutlet UITextView *skillLevelsTV;
@property (weak, nonatomic) IBOutlet UITextView *homeTV;
@property (weak, nonatomic) IBOutlet UITextView * rulesTV;
// CV = container view
@property (weak, nonatomic) IBOutlet UIView *sideTabsCV;
// Arrays
@property (weak,nonatomic) NSMutableArray * _ssImagesArray;
@property (weak,nonatomic) NSMutableArray * _textArray;
// Error handling
@property (strong, nonatomic) NSMutableData * _responseData; // got warning in .m when prop was weak
// parsing related methods
+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn;
+ (id) stringFromArray: (NSArray*) arr;
@end
ViewController.m
#import "ViewController.h"
#import "TFHpple.h"
#import "TFHppleElement.h"
@interface ViewController ()
+ (id) parseData:(NSString *)urlS :(NSString *)path :(NSString *)typeOfDataToReturn;
+ (id) stringFromArray:(NSArray *)arr;
@end
@implementation ViewController
@synthesize _responseData;
@synthesize menuSV;
@synthesize homeSideTabsSV;
@synthesize homeTV;
@synthesize ssIV;
@synthesize hostATournamentWV;
@synthesize rulesTV;
@synthesize skillLevelsTV;
@synthesize _ssImagesArray;
@synthesize _textArray;
@synthesize scheduleButton;
@synthesize newsButton;
@synthesize photosButton;
@synthesize docsButton;
@synthesize stagesButton;
@synthesize faqsButton;
@synthesize resultsButton;
@synthesize contactButton;
@synthesize finderButton;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction) menuButton:(UIBarButtonItem *)sender {// When Drop Down Menu is pressed
//self.menuSV.contentSize = CGSizeMake(160, 160); // Make it so Scroll View (contains buttons) can scroll
if (self.homeSideTabsSV.hidden) // if buttons aren't showing, then uncover them
{
self.homeSideTabsSV.hidden = false;
} else if (self.homeSideTabsSV.hidden == false) // else (they're showing) hide them
{
self.homeSideTabsSV.hidden = true;
}
}
+ (id) stringFromArray : (NSArray *) arr // creates a string when given an array
{
NSString * result = [arr description];
return result;
}
+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn
{
// Set up request
NSURL * url = [NSURL URLWithString:urlS];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
NSURLResponse * response = nil;
NSError * error = nil;
// Send request
NSData * gatheredData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error) {return error;}
// 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;
}
- (void) textSet // setText already exists, so this one is textSet
{
// set homeTV's text = the string form (from "stringFromArray") of the array from "parseData"
[self.homeTV setText:[NSString stringFromArray:[ NSArray parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]]];
}
// call method with url & path to get text
- (id) getText:(NSURL*) url :(NSString*) path
{
NSData * gatheredText = [NSData dataWithContentsOfURL:url];
TFHpple * textParser = [TFHpple hppleWithHTMLData: gatheredText];
NSArray * textNodes = [textParser searchWithXPathQuery:path];
NSMutableArray * textArray = [[NSMutableArray alloc]initWithCapacity:0];
for (TFHppleElement * element in textNodes)
{
NSString * text = [[element firstChild] content]; // set text's value
[textArray addObject:text]; // add text to textArray
}
int z = [_textArray count]; // set z = end of _textArray
NSRange range = NSMakeRange(z, [textArray count]); // make a range from z to end of textArray
NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; // make an indexSet from range
[_textArray insertObjects:textArray atIndexes:indexSet]; // insert new parsed info at end of _textArray
return textArray;
}
- (void) makeSlideShow { // gets images for Slide Show
NSURLRequest * imagesURL = [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.3v3live.com"]]; // request connection
NSURLResponse * response = nil;
NSError * error = nil;
NSData * gatheredImages = [NSURLConnection sendSynchronousRequest:imagesURL returningResponse:&response error:&error];// get raw data
if (error == nil)
{
// Parse data here
TFHpple *imageParser1 = [TFHpple hppleWithHTMLData:gatheredImages]; // parses for almost all images in slide show
TFHpple *imageParser2 = [TFHpple hppleWithHTMLData:gatheredImages]; // parses for displayed image
NSString * parsePath1 = @"//div[@class ='newsSlideShow-article']"; // not shown pics path
NSString * parsePath2 = @"//div[@class = 'newsSlideShow-article current']"; // shown pic path
NSArray * Nodes = [imageParser1 searchWithXPathQuery:parsePath1]; // not shown pics array
NSArray * currentArticleArray = [imageParser2 searchWithXPathQuery:parsePath2]; // stores shown image
UIImage * currentArticle = [currentArticleArray objectAtIndex:0]; // displayed image in slide show should be first in the above array
[_ssImagesArray addObject:currentArticle ]; // add in displayed pic
int x = 1;
for (TFHppleElement * element in Nodes)// seperate collected data into pics; inserts rest of pics into imagesArray
{
x++;
UIImage * image = [UIImage imageWithData:[NSURL URLWithString:[element objectForKey:@"href"]]]; // set image's value
[_ssImagesArray addObject:image]; // add it to imagesArray
}
}
};
int j = 1; // counter for loopSlideShow
- (void) loopSlideShow // runs the slide show with gathered images from createSlideShow
{
int delayTime = 5; // how long each pic is shown
while (self.ssIV) // while the slideShowPic exists
{
if (j == [_ssImagesArray count]) // if it's reached the last pic, loop back to beggining of Slide Show
{
j = 1;
} else // else go on to next pic
{
j++;
};
[ssIV setImage:[_ssImagesArray objectAtIndex:j]]; // tell slide show which pic to display
[self performSelector:@selector(loopSlideShow) withObject:self afterDelay:delayTime]; // show each picture for X seconds
}
};
@end
答案 0 :(得分:1)
看起来-[ViewController parseData:::]
实际上是ViewController
上的一种方法,所以如果你在NSArray
上调用它就没有意义
如果你把它作为一个类方法,你应该用
来调用它[self.class parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]
或将其更改为实例方法并使用
调用它[self parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]
无论哪种方式,这都是一个命名非常糟糕的方法,似乎缺少一些基本的面向对象编程概念。 Apple在开始Objective-C和iOS开发方面拥有一些非常好的资源。