Problem with NSMutableArray and custom NSObject - objective-c

I'm really desperate on this one. I'm trying to make a Framework which you can search and play YouTube videos with. But while testing it, I'm running in to a big problem.
In the search operation I'm adding YTVideos (a subclass of NSObject) to a NSMutableArray. When I loop thru it in the main(), I'm getting nil-objects:
Method
- (NSArray *)videosInRange:(NSRange)range {
if(range.length > 50) {
[NSException raise:#"Range lenth > 50"
format:#"The range of -videosInRange: can't be bigger than 50"];
return nil;
}
if((range.location + range.length) > 999) {
[NSException raise:#"Range to big"
format:#"The given range was to big (%d, %d)", range.location, range.length];
return nil;
}
NSString *searchURLString = [[self feedURL] absoluteString];
searchURLString = [searchURLString stringBySettingURLAttribute:#"start-index" value:[NSString stringWithFormat:#"%d",range.location + 1]];
searchURLString = [searchURLString stringBySettingURLAttribute:#"max-results" value:[NSString stringWithFormat:#"%d",range.length]];
NSLog(#"%#",searchURLString);
NSURL *url = [NSURL URLWithString:searchURLString];
NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:url
options:0
error:NULL];
if(!xmlDoc)
return nil;
NSArray *videoElements = [[xmlDoc rootElement] elementsForName:#"entry"];
NSMutableArray *videos = [[NSMutableArray alloc] initWithCapacity:[videoElements count]];
register int i;
for(i = 0; i < [videoElements count]; i++) {
NSAutoreleasePool *addPool = [[NSAutoreleasePool alloc] init];
YTVideo *vid = [[YTVideo alloc] initWithXMLElement:[videoElements objectAtIndex:i]];
[videos addObject:vid];
[vid release];
[addPool drain];
}
NSArray *retValue = [NSArray arrayWithArray:videos];
[videos release];
return retValue;
}
main()
int main(int argc, const char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
YTSearchFeed *feed = [[YTSearchFeed alloc] initWithSearch:#"Eminem"];
long long results = [feed videoCount];
NSLog(#"%lld videos for search", results);
long long i = 0;
while(results != 0) {
int length = (results >= 50) ? (50) : (results);
NSArray *videos = [feed videosInRange:NSMakeRange(i, length)];
NSLog(#"L: %d", [videos count]);
int z;
for(z = 0; z < [videos count]; z++, i++) {
YTVideo *vid = [videos objectAtIndex:z];
NSString *title = [vid title];
NSLog(#"%d: %#", i+1, title);
}
results -= length;
}
[pool drain];
return NSApplicationMain(argc, argv);
}
I hope someone can take the time to look at this, and if you need anymore information, just ask.
Thank you in advance,
ief2
EDIT: YTVideo
- (id)initWithXMLElement:(NSXMLElement *)element {
self = [super init];
if(self != nil) {
_XMLElement = [element copy];
}
return self;
}
- (NSString *)title {
if(!_title) {
NSString *str = [[[self XMLElement] firstElementWithName:#"title"] stringValue];
_title = [[str stringByDecodingHTMLEntities] retain];
}
return [[_title copy] autorelease];
}
I get the title (and other video information) only when it's requested. the -stringByDecodingHTMLEntities works fine (Category on NSString).

I've rewritten the code and initialized all instance variables in the -initmethod

Related

Objective-c recursion, advanced recursive method construction

I want to mimic NSDirectoryEnumerator with a simple recursive function, but my attempts so far have had my loops stopping prematurely.
The method needs to stop when there is no longer a directory or file present at an nth level.
How can I rearrange the method below to be a simple recursive function that will terminate accordingly?
Any help would be much appreciated. Thanks.
#import "MenuFromPathData.h"
#interface MenuFromPathData ()
#property (nonatomic,strong) NSFileManager *myFileManager;
#end
#implementation MenuFromPathData
#synthesize myFileManager=_myFileManager;
#define ROOT_DIRECTORY #"TextData"
//
////
//
- (void) simpleMenuArrayBuilder
{
NSArray *fileNamesLevel1 = [self fullArrayReturn:ROOT_DIRECTORY];
for(int i = 0; i < [fileNamesLevel1 count]; i++)
{
NSString *pathNameLevel2 = [NSString stringWithFormat:#"%#/%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i]];
NSArray *fileNamesLevel2 = [self fullArrayReturn:pathNameLevel2];
for(int j = 0; j < [fileNamesLevel2 count]; j++)
{
NSString *pathNameLevel3 = [NSString stringWithFormat:#"%#/%#/%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i],[fileNamesLevel2 objectAtIndex:j] ];
NSArray *fileNamesLevel3 = [self fullArrayReturn:pathNameLevel3];
for(int k = 0; k < [fileNamesLevel3 count]; k++)
{
NSString *pathNameLevel4 = [NSString stringWithFormat:#"%#/%#/%#/%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i],[fileNamesLevel2 objectAtIndex:j],[fileNamesLevel3 objectAtIndex:k] ];
NSArray *fileNamesLevel4 = [self fullArrayReturn:pathNameLevel4];
for(int l = 0; l < [fileNamesLevel4 count]; l++)
{
NSString *pathNameLevel5 = [NSString stringWithFormat:#"%#/%#/%#/%#/%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i],[fileNamesLevel2 objectAtIndex:j],[fileNamesLevel3 objectAtIndex:k],[fileNamesLevel4 objectAtIndex:l] ];
NSArray *fileNamesLevel5 = [self fullArrayReturn:pathNameLevel5];
for(int m = 0; m < [fileNamesLevel5 count]; m++)
{
NSString *pathNameLevel6 = [NSString stringWithFormat:#"%#/%#/%#/%#/%#/%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i],[fileNamesLevel2 objectAtIndex:j],[fileNamesLevel3 objectAtIndex:k],[fileNamesLevel4 objectAtIndex:l], [fileNamesLevel5 objectAtIndex:m] ];
NSArray *fileNamesLevel6 = [self fullArrayReturn:pathNameLevel6];
NSLog(#"-- LVL 6.0 %# -- ",pathNameLevel6);
for(int n = 0; n < [fileNamesLevel6 count]; n++)
{
NSString *pathNameLevel7 = [NSString stringWithFormat:#"%#/%#/%#/%#/%#/%#%#",ROOT_DIRECTORY,[fileNamesLevel1 objectAtIndex:i],[fileNamesLevel2 objectAtIndex:j],[fileNamesLevel3 objectAtIndex:k],[fileNamesLevel4 objectAtIndex:l], [fileNamesLevel5 objectAtIndex:m],[fileNamesLevel6 objectAtIndex:n] ];
NSArray *fileNamesLevel7 = [self fullArrayReturn:pathNameLevel7];
NSLog(#"-- LVL 7.0 %# -- ",pathNameLevel7);
}
}
}
}
}
}
}
//
////
//
- (NSString*) resourcePath : (NSString*) pathName {
return [[NSBundle mainBundle] pathForResource:pathName ofType:nil];
}
- (NSArray*) bundleArrayReturn : (NSString*)pathForResource {
NSError* error;
return [self.myFileManager contentsOfDirectoryAtPath:pathForResource error:&error];
}
- (NSArray*) fullArrayReturn : (NSString*) pathName {
return [self bundleArrayReturn:[self resourcePath: pathName]];
}
//
////
//
- (NSFileManager*) myFileManager {
if(!_myFileManager) {
_myFileManager = [NSFileManager defaultManager];
}
return _myFileManager;
}
#end
Something like this should work. Only trick is to add another parameter to your method to track current depth during the recursion.
- (void) simpleMenuArrayBuilderForPath:(NSString*)pathToDecend allowedDepth:(int)depth
{
// if we've defended far enough, then stop
if(depth == 0) return;
// otherwise, get the next directory listing at this level
NSArray *fileNamesNextLevel = [self fullArrayReturn:pathToDecend];
for(int i = 0; i < [fileNamesNextLevel count]; i++)
{
// find each path inside the directory we're looking at
NSString *nextLevelPathName = [pathToDecend stringByAppendingPathComponent:[fileNamesNextLevel objectAtIndex:i]];
// process it however you want...
NSLog(#"Looking at %#", nextLevelPathName);
// and recur into it
[self simpleMenuArrayBuilderForPath:nextLevelPathName allowedDepth:depth-1];
}
}
then, call it by:
[self simpleMenuArrayBuilderForPath:ROOT_DIRECTORY allowedDepth:5];

Understanding a logic in update/add - NSUserDefaults (Objective C)

I'm writing a nice class to handle call block in NSUserDefaults.
Haven't tested it yet, but I think I miss something regarding update/add by callBlockID.
My Code:
My Code:
#implementation UserDefaultHandler
+ (UserDefaultHandler *)sharedInstance
{
static UserDefaultHandler *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[UserDefaultHandler alloc] init];
});
return instance;
}
-(void)updateOrAddCallBlock:(NSMutableDictionary*)callBlockObject
{
NSString *callBlockID = [callBlockObject objectForKey:#"callBlockID"];
BOOL needToUpdate = NO;
NSInteger indexDict = 0;
NSMutableArray *arrayOfAllCallBlock = [[NSMutableArray alloc] init];
arrayOfAllCallBlock = (NSMutableArray*)[[NSUserDefaults standardUserDefaults] objectForKey:#"arrayOfAllCallBlock"];
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
if (arrayOfAllCallBlock.count <= 0 || arrayOfAllCallBlock == nil)
{
[arrayOfAllCallBlock addObject:callBlockObject];
}
else
{
for (int i = 0; i < arrayOfAllCallBlock.count; i++)
{
NSMutableDictionary *mutableDict = [arrayOfAllCallBlock objectAtIndex:i];
NSString *idFromDict = [mutableDict objectForKey:#"callBlockID"];
if ([idFromDict isEqualToString:callBlockID])
{
needToUpdate = YES;
indexDict = i;
newDict = mutableDict;
}
}
if (needToUpdate)
{
[arrayOfAllCallBlock removeObjectAtIndex:indexDict];
[arrayOfAllCallBlock insertObject:newDict atIndex:indexDict];
}
else
{
[arrayOfAllCallBlock addObject:callBlockObject];
}
}
[self saveGlobalDict:arrayOfAllCallBlock];
}
- (NSMutableDictionary *)getCallBlockByID:(NSString*)callBlockID
{
NSMutableArray *arrayOfAllCallBlock = (NSMutableArray*)[[NSUserDefaults standardUserDefaults] objectForKey:#"arrayOfAllCallBlock"];
BOOL isFound = NO;
NSInteger indexDict = 0;
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
for (int i = 0; i < arrayOfAllCallBlock.count; i++)
{
NSMutableDictionary *mutableDict = [arrayOfAllCallBlock objectAtIndex:i];
NSString *idFromDict = [mutableDict objectForKey:#"callBlockID"];
if ([idFromDict isEqualToString:callBlockID])
{
isFound = YES;
indexDict = i;
newDict = mutableDict;
}
}
if (isFound)
{
return newDict;
}
else
{
return nil;
}
}
- (NSMutableArray*)getAllCallBlock
{
NSMutableArray *arrayOfAllCallBlock = (NSMutableArray*)[[NSUserDefaults standardUserDefaults] objectForKey:#"arrayOfAllCallBlock"];
return arrayOfAllCallBlock;
}
- (void)clearCallBlockDB
{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"arrayOfAllCallBlock"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)saveGlobalDict:(NSMutableArray*)globalArray
{
self.globalArray = [[NSMutableArray alloc] init];
self.globalArray = globalArray;
[self clearCallBlockDB];
[[NSUserDefaults standardUserDefaults] setObject:self.globalArray forKey:#"arrayOfAllCallBlock"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)clearSingleCallBlock:(NSString*)callBlockID
{
NSMutableArray *array = [[NSMutableArray alloc] init];
array = [self getAllCallBlock];
NSMutableDictionary *specificDict = [[NSMutableDictionary alloc] init];
NSInteger getIndex = [self getIndexForCallBlock:array specificDict:specificDict];
[array removeObjectAtIndex:getIndex];
[self saveGlobalDict:array];
}
- (NSInteger)getIndexForCallBlock:(NSMutableArray*)arrayOfAllCallBlock specificDict:(NSMutableDictionary*)specificDict
{
NSInteger getIndex = 0;
for (int i = 0; i < arrayOfAllCallBlock.count; i++)
{
NSMutableDictionary *mutableDict = [arrayOfAllCallBlock objectAtIndex:i];
NSDictionary *dict_one = [specificDict copy];
NSDictionary *dict_two = [mutableDict copy];
if ([dict_two isEqualToDictionary:dict_one])
{
getIndex = i;
}
}
return getIndex;
}
#end
I'll explain: I've a UITableView and when I add a row to it, I've a new window to put details, save and present back in UITableView.
Also, I've an edit button so I can edit and update a row in the table.
Adding a row to table create a unique string (callBlockID).
I'm not sure how to handle it and whether or not my code is enough.
Any ideas?

uisearchbar in grouped section uitable

I've pieced together several tutorials to create a grouped table with sections and I'm now trying to get a uisearchbar to work. the problem I'm having is how to search within the grouped sections.
I've read the similar questions this post suggested but can't
This is the code to create the grouped sections
#import "Job.h" // A model for the data
#import "Address.h" // Another model for the data
- (void)viewDidLoad
{
[super viewDidLoad];
self.theTable.delegate = self;
self.theTable.dataSource =self;
_searchBar.delegate = (id)self;
FMDBDataAccess *db = [[FMDBDataAccess alloc] init];
jobs = [[NSMutableArray alloc] init];
jobs = [db getJobs:1];
_sections = [[NSMutableDictionary alloc] init];
NSMutableArray *jobsTempArray = [db getJobsAsDictionary:1];
BOOL found;
// Loop through the books and create our keys
for (NSDictionary *book in jobsTempArray)
{
NSString *cLong = [book objectForKey:#"addrAddress"];
NSString *c = [cLong substringToIndex:1];
found = NO;
for (NSString *str in [_sections allKeys])
{
if ([str isEqualToString:c])
{
found = YES;
}
}
if (!found)
{
[_sections setValue:[[NSMutableArray alloc] init] forKey:c];
}
}
// Loop again and sort the books into their respective keys
for (NSDictionary *book in jobsTempArray)
{
[[_sections objectForKey:[[book objectForKey:#"addrAddress"] substringToIndex:1]] addObject:book];
}
// Sort each section array
for (NSString *key in [_sections allKeys])
{
[[_sections objectForKey:key] sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"addrAddress" ascending:YES]]];
}
}
And this is the code that searches
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
_isFiltered = FALSE;
}
else
{
_isFiltered = true;
_filteredjobs = [[NSMutableArray alloc] init];
//for (Job* book in jobs)
//for (Job* book in [_sections allKeys])
//for (NSString *food in [_sections allKeys])
for (NSDictionary* book in [_sections allKeys])
{
NSString *addrStr = [book objectForKey:#"addrAddress"];
NSString *postStr = [book objectForKey:#"addrPostcode"];
//NSRange nameRange = [book.jobAddress rangeOfString:text options:NSCaseInsensitiveSearch];
NSRange nameRange = [addrStr rangeOfString:text options:NSCaseInsensitiveSearch];
//NSRange descriptionRange = [book.jobPostcode rangeOfString:text options:NSCaseInsensitiveSearch];
NSRange descriptionRange = [postStr rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound)
{
[_filteredjobs addObject:book];
}
}
}
[self.theTable reloadData];
}
I've got as far as realising I need to change for (Job* food in jobs) to for (NSDictionary* book in [_sections allKeys]) but I'm stuck how to search within [_sections allKeys]
Specifically this line
NSRange nameRange = [addrStr rangeOfString:text options:NSCaseInsensitiveSearch];
which crashes with
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x692e200
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]:
unrecognized selector sent to instance 0x692e200':
Any ideas? PS Treat me as a noob, I'll need some code as well as explanation - I'm still learning obj-c
Check the Link.It shows the UISearchBar With Grouped Section Tableview.Its a simple Tutorial..Hope its useful for you
I found the answer in
UISearchBar - search a NSDictionary of Arrays of Objects and reading up on allkeys.
Basically loop through the grouped NSDictionary and extract the NSArrays, then loop through again searching...
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
_isFiltered = FALSE;
}
else
{
_isFiltered = true;
_filteredjobs = [[NSMutableArray alloc] init];
NSString *currentLetter = [[NSString alloc] init];
for (int i=0; i<[_sections count]; i++)
{
currentLetter = [[_sections allKeys] objectAtIndex:i];
NSArray *jobsForKey = [ [NSArray alloc] initWithArray:[_sections objectForKey:[[_sections allKeys] objectAtIndex:i]] ];
for (int j=0; j<[jobsForKey count]; j++)
{
NSDictionary *book = [jobsForKey objectAtIndex:j];
NSRange titleResultsRange = [[book objectForKey:#"addrAddress"] rangeOfString:text options:NSCaseInsensitiveSearch];
if(titleResultsRange.location != NSNotFound)
{
[_filteredjobs addObject:book];
}
}
}
}
[self.theTable reloadData];
}

Trouble to show route between points Google Directions API. iOS 6

I have a problem when displaying a route in MapView if route has waypoints. I use DIRECTIONS GOOGLE API:
https://developers.google.com/maps/documentation/directions/
The route is not drawn using the road.
Any help? Thanks!!
The trouble images:
The code:
reponse = [self getRouteFromGoogleApiWithPoints:arrayOfCoords andMode:#"driving" error:error];
if(reponse == nil)
{
UIAlertView *succes= [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"txtError", nil) message:NSLocalizedString(#"ServerError", nil) delegate: self cancelButtonTitle: #"OK" otherButtonTitles: nil];
[succes show];
}
else
{
NSArray *routes = [reponse objectForKey:#"routes"];
NSDictionary *route = [routes objectAtIndex:0];
NSDictionary *polylineOverview = [route objectForKey:#"overview_polyline"];
NSString *polylinePoints = [polylineOverview objectForKey:#"points"];
NSArray *decodedPolyline = [self decodePolyLine:polylinePoints];
CLLocationCoordinate2D coords[[decodedPolyline count]];
int i=0;
for(CLLocation* loc in decodedPolyline)
{
CLLocationCoordinate2D c;
c.latitude = loc.coordinate.latitude;
c.longitude = loc.coordinate.longitude;
coords[i]=c;
i++;
}
MKPolyline *line = [MKPolyline polylineWithCoordinates:(CLLocationCoordinate2D*)coords count:decodedPolyline.count];
[mapview addOverlay:line];
[mapview setNeedsDisplay];
}
}
}
+ (NSMutableArray *)decodePolyLine: (NSString *)encoded {
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len) {
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
+(NSDictionary*)getRouteFromGoogleApiWithPoints:(NSArray*)arrayOfPoints andMode:(NSString*)mode error:(NSError **)error
{
NSDictionary *result = nil;
NSString *waypoints = #"";
CLLocation* origin = [arrayOfPoints objectAtIndex:0];
CLLocation* destination = [arrayOfPoints objectAtIndex:arrayOfPoints.count - 1];
// Create the waypoints
for(int i = 1; i < arrayOfPoints.count - 2; i++)
{
CLLocation* current = [arrayOfPoints objectAtIndex:i];
waypoints = [waypoints stringByAppendingString:[NSString stringWithFormat:#"%f,%f%%7C",current.coordinate.latitude,current.coordinate.longitude]];
}
CLLocation* lastWaypoint = [arrayOfPoints objectAtIndex:arrayOfPoints.count - 2];
waypoints = [waypoints stringByAppendingString:[NSString stringWithFormat:#"%f,%f",lastWaypoint.coordinate.latitude,lastWaypoint.coordinate.longitude]];
NSString *urlString =[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&waypoints=%#&sensor=true&mode=%#",origin.coordinate.latitude,origin.coordinate.longitude,destination.coordinate.latitude,destination.coordinate.longitude,waypoints,mode];
NSDictionary* response = [self getDictionaryFromURLString:urlString withParameters:nil error:error];
if (response != nil)
{
if ([[response objectForKey:#"status"] isEqualToString:#"OK"])
{
result = response;
NSLog(#"%#",response);
}
else
{
if (error)
{
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:[response objectForKey:#"status"] forKey:NSLocalizedDescriptionKey];
*error = [[NSError alloc] initWithDomain:#"AppName" code:2 userInfo:details];
}
}
}
else
{
if(error)
{
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:NSLocalizedString(#"ErrorServidor", nil) forKey:NSLocalizedDescriptionKey];
*error = [NSError errorWithDomain:#"AppName" code:1 userInfo:details];
return nil;
}
}
return result;
}
First off, according to the Google Terms & Conditions you're not allowed to use their directions/data on someone else's maps.
Secondly, the first is partly imposed because people have different data, place roads in different spots, break the roads into different segments etc etc and thus instructions don't line up.
If you want to show directions in your map you'll have to find another source. Maybe you should consider the CloudMade API.
Now you could use Google Maps SDK for iOS. That's the only legal option if you need to display Google Directions API under iOS6.
You can use Mapkit direction request API.
Direction request api has some limitation for consecutive calls made otherwise it works similar as google direction api.
There are ways to fetch direction for driving, walking and transit.
Also there is a way to get alternate routes.
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:SourceCLLocationCorodinate).coordinate addressDictionary:nil];
MKMapItem *sourceMapItem = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark];
[request setSource:sourceMapItem];
MKPlacemark *destPlacemark = [[MKPlacemark alloc] initWithCoordinate:destCLLocationCoordinate addressDictionary:nil];
MKMapItem *destMapItem = [[MKMapItem alloc] initWithPlacemark:destPlacemark];
[request setDestination:destMapItem];
[request setTransportType:MKDirectionsTransportTypeAny];
request.requestsAlternateRoutes = NO;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
if(![directions isCalculating])
{
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error)
{
// Handle Error
NSLog(#"Error for this particular call");
}
else
{
for (MKRoute * route in response.routes)
{
//Add the route.polyline to the mapkit overlay
}
}];
}

getting NCFString error while searching the tableview using searchbar

i ve got a table view parsed from json string.everthing works good .if i m to type a character in my search bar i m getting this error '-[__NSCFString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x1d52ac50'below is the code.were the below variable name data is NSMutableArray.could u guys help me out.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controllershouldReloadTableForSearchString:(NSString *)searchString
{
[searchData removeAllObjects];
NSArray *group;
for(group in nameData)
{
NSLog(#"wat am i doing here:%#",group);
NSMutableArray *newGroup = [[NSMutableArray alloc] init];
NSString *element;
for(element in group)
{
NSRange range = [element rangeOfString:searchString options:NSCaseInsensitiveSearch];
if (range.length > 0) {
[newGroup addObject:element];
}
}
if ([newGroup count] > 0) {
[searchData addObject:newGroup];
}
}
return YES;
}
Please check out this code
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
NSMutableArray *array=[[NSMutableArray alloc]init];
NSDictionary *naming= [self.friendsDictionary objectForKey:#"data"];
NSLog(#"ggg %#",[self.friendsDictionary objectForKey:#"data"]);
for(int i =0 ; i< [[self.friendsDictionary objectForKey:#"data"] count]; i++){
[array addObject:[[[self.friendsDictionary objectForKey:#"data"] objectAtIndex:i] objectForKey:#"name"]];
}
NSLog(#"Array %#", array);
if(self.searchDisplayController.searchBar.text.length>0)
{
NSString *strSearchText = self.searchDisplayController.searchBar.text;
NSMutableArray *group = [[NSMutableArray alloc]init];
for (int i=0; i<array.count; i++) {
NSString *strData = [array objectAtIndex:i];
NSLog(#"string Data:%#",strData);
NSRange rng = [strData rangeOfString:strSearchText options:NSCaseInsensitiveSearch];
if(rng.location != NSNotFound)
{
if(rng.location== 0)//that is we are checking only the start of the names.
{
[group addObject:strData];
}
}
}
if ([group count] > 0)
{
searchData = [[NSMutableArray alloc] init];
[searchData addObjectsFromArray:group];
NSLog(#"Sear %#", searchData);
}
}
return YES;
}