Question

Im trying to make the search filter work for my tableview, it crashes the app when i click the search bar and comes back with this error

2014-03-30 14:44:08.676 BookStore[16156:90b] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PFObject rangeOfString:options:]: unrecognized selector sent to instance 0x9da1a40' * First throw call stack:

here is the code:

//
//  PDFTableViewController.m
//  BookStore
//
//  Created by Danijel Kujundzic on 3/23/14.
//  Copyright (c) 2014 Danijel Kujundzic. All rights reserved.
//

#import "PDFTableViewController.h"
#import "PDFDetailViewController.h"
@interface PDFTableViewController ()<UISearchBarDelegate , UISearchDisplayDelegate>
{
  NSMutableArray * filteredStrings;
    BOOL isFiltered;
}

@end

@implementation PDFTableViewController




@synthesize PDFtableView;


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

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self performSelector:@selector(RetrievePDFParseData)];
    self.SearchBar.delegate =self;
    self.PDFtableView.delegate=self;
    self.PDFtableView.dataSource =self;
    filteredStrings = [[NSMutableArray alloc] initWithArray:PDFArray];
}



- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchText.length ==0) {
        isFiltered= NO;
        [filteredStrings removeAllObjects];
        [self.tableView reloadData];
        [searchBar resignFirstResponder];
    }
    else
    {
        isFiltered = YES;
        if([PDFArray count]!=0)
        {
            NSPredicate *p=[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
                NSString *s=evaluatedObject;
                return ([s rangeOfString:searchBar.text options:NSCaseInsensitiveSearch].location !=NSNotFound);
            }];
            filteredStrings= [NSMutableArray arrayWithArray:[PDFArray filteredArrayUsingPredicate:p]];
            //table reload
            [self.tableView reloadData];
        }

    }
}




-(void) RetrievePDFParseData {
    PFQuery * getPDF = [PFQuery queryWithClassName:@"PDFTableView"];

    [getPDF findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if(!error) {
           PDFArray =[[NSArray alloc] initWithArray: objects];

        }
        [PDFtableView reloadData];

    }];

}




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

#pragma mark - Table view data source





- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (isFiltered) {
        return [filteredStrings count];
    }


    return [PDFArray count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString * CellIdentifier = @"Cell";
        UITableViewCell * cell = [PDFtableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell ==nil) {
            cell = [[ UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
        }

        if (!isFiltered) {
            PFObject * tempObject = [PDFArray objectAtIndex:indexPath.row];
            cell.textLabel.text = [tempObject objectForKey:@"PDFName"];
            cell.detailTextLabel.text= [tempObject objectForKey:@"Author"];
        }

        if (isFiltered)


        {
            PFObject *filteredObject= [[filteredStrings objectAtIndex:indexPath.row]initWithArray:PDFArray];
            cell.textLabel.text =[filteredObject objectForKey:@"PDFName"];
            cell.detailTextLabel.text= [filteredObject objectForKey:@"Author"];
            NSLog(@"%@", filteredObject);
        }


        return cell;

    }


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"detailSegue" sender:self];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

    if([segue.identifier isEqualToString:@"detailSegue"]){

        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        PDFDetailViewController *detailVC = (PDFDetailViewController *)segue.destinationViewController;
        NSLog(@"Bookarray=%@", PDFArray);
        NSLog(@"BookIndex=%@", [PDFArray objectAtIndex:indexPath.row]);
        detailVC.PDFna=[[PDFArray objectAtIndex:indexPath.row]objectForKey:@"PDFName"];
        detailVC.PDFdes= [[PDFArray objectAtIndex:indexPath.row]objectForKey:@"About"];
        detailVC.downloadfile=[[PDFArray objectAtIndex:indexPath.row]objectForKey:@"PDFFile"];


    }
}


@end
Was it helpful?

Solution

The array of objects that you think are NSStrings are actually PFObjects. PDFArray contains an array of PFObject's. You probably want to be grabbing a certain property in the predicate you created in your UISearchBarDelegate method,

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

Something like NSString *s = evaluatedObject[@"PDFName"];, or something to that effect will make it so that you're actually filtering along the name of the PDF file.

OTHER TIPS

The error is in searchBar:textDidChange: method. The predicate returns PFObject in this case, not a NSString. So you must search evaluatedObject object for a NSString object that you need.

Those are the problematic lines:

NSString *s=evaluatedObject;
return ([s rangeOfString:searchBar.text options:NSCaseInsensitiveSearch].location !=NSNotFound);

The exception is thrown on the rangeOfString, because PFObject does not respond to rangeOfString.

In other languages compiler would sometimes warn you of this situation. In Objective-C you must be careful when working with objects of any type: id. Compiler doesn't make checks if a specific object responds to the message at compile time. But when Objective-C runtime does this at runtime, you get a crash.

Read more about objects and messages in Objective-C at: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top