JamMySon
JamMySon

Reputation: 47

Arc Semantic Issue: No known class method for selector (method name here)

Before beginning, I thought I should let you all know that I'm a self-taught beginner with no formal background what so ever.

My Goal: To display parsed HTML data from www.3v3live.com into various views in my app.

General Plan for implementation: I will create a reusable method that I can call to parse different pages of the site. It will have three parameters, including: a url, an Xpath query, and a type of data (input as a string and converted into a class by the method). The method shall return the gathered data in the type of data (from third parameter) in an array.

My Errors: 1) "No known class method for selector 'parseData:::' 2) "No known class method for selector 'stringFromArray:'

My OutPut: none

My Attempts to fix the errors: 1) I've added them to the .h file and interface of .m 2) I've added in a protocol (recommended by an answer on here) 3) I've converted the methods to instance methods (and back) 4) I've cleaned and run the project

Note: The error is at the line in the "textSet" method towards the bottom, and the "makeSlideShow" and "getText" methods are the precursors to my new method that is erroring (the precursors errored too).

My Code (ignore comments):

(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

Upvotes: 0

Views: 4906

Answers (1)

Paul.s
Paul.s

Reputation: 38728

It looks like -[ViewController parseData:::] is actually a method on ViewController so it will not make sense if you call it on NSArray

If you keep it as a class method then you should call it with

[self.class parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]

or change it to an instance method and call it with

[self parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]

Either way this is a really poorly named method and it seems like some fundamental object oriented programming concepts are missing. Apple have some really good resources on getting started with Objective-C and iOS development.

Upvotes: 1

Related Questions