Access contact image from address book based on name - iphone

Err,I have been pulling my hair thinking about a way from quite a few days.I have retrieved all contacts names and placed in an array using dictionary.
What I have is a model class holding a list of names,now I want to search the location of name in contacts list,depending on which I can retrieve the required contact image.
Initially googled and found out an unanswered question not pretty much similar to my requirement,the same can be glanced here
I tried several ways,the below is one way I have implemented:
EDIT
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self loadReminders];
ReminderClass *reminderToDisplay = [self.remindersArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
// Now create the cell to display the reminder data
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:17.0];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
}
tableView.backgroundColor = [UIColor clearColor];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc]init]autorelease];
[dateFormat setDateFormat:kDateFormat];
NSDate *reminderDate = [dateFormat dateFromString:reminderToDisplay.Date];
[dateFormat setDateFormat:kMinDateFormat];
NSString *dateString = [dateFormat stringFromDate:reminderDate];
NSString *valueString = [NSString stringWithFormat:#"%#'s %#",reminderToDisplay.Name,reminderToDisplay.Event];
NSString *onString = [NSString stringWithFormat:#" on %#",dateString];
NSString *reminderDetailsString = [valueString stringByAppendingString:onString];
//Get the contact image based on name index from contact list
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFStringRef reminderName = (CFStringRef)reminderToDisplay.Name;
CFArrayRef allPeople = ABAddressBookCopyPeopleWithName(addressBook, reminderName);
self.contactsList =[[[NSMutableArray alloc]init]autorelease];
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
NSString *contactFirstNamePart = (NSString *)ABRecordCopyValue(ref,kABPersonFirstNameProperty);
NSString *contactFirstName = [[[NSString alloc] initWithString:contactFirstNamePart]autorelease];
NSString *contactLastNamePart = (NSString *)ABRecordCopyValue(ref, kABPersonLastNameProperty);
if (contactLastNamePart == nil)
{
self.contactName = contactFirstName;
}
else
{
NSString *contactLastName = [[[NSString alloc] initWithString:contactLastNamePart]autorelease];
NSString *contactLastNameString = [NSString stringWithFormat:#" %#",contactLastName];
self.contactName = [contactFirstName stringByAppendingString:contactLastNameString];
CFRelease(contactLastNamePart);
}
NSDictionary *contactsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:self.contactName, kContactName, [NSNumber numberWithInt:i], kContactIndex, nil];
[self.contactsList addObject:contactsDictionary];
CFRelease(contactFirstNamePart);
}
NSDictionary *contactsDictionary = [self.contactsList objectAtIndex:indexPath.row];
self.contactName = [contactsDictionary objectForKey:kContactName];
int addressIndex = [[contactsDictionary objectForKey:kContactIndex]integerValue];
ABRecordRef recordReference = CFArrayGetValueAtIndex(allPeople, addressIndex);
if (ABPersonHasImageData(recordReference))
{
NSData *imageData = (NSData *)ABPersonCopyImageData(recordReference);
self.reminderImage = [UIImage imageWithData:imageData];
CFRelease(imageData);
}
CFRelease(allPeople);
CFRelease(addressBook);
UIImage *notificationImage = reminderImage;
if (notificationImage != nil)
{
UIImageView *imageView=[[[UIImageView alloc] initWithFrame:CGRectMake(240, 3, 70, 63)]autorelease];
imageView.backgroundColor=[UIColor clearColor];
[imageView setImage:notificationImage];
cell.accessoryView = imageView;
}
else
{
UIImageView *imageView=[[[UIImageView alloc] initWithFrame:CGRectMake(240, 3, 70, 63)]autorelease];
imageView.backgroundColor=[UIColor clearColor];
UIImage *defaultImage = [UIImage imageNamed:kDefaultImage];
[imageView setImage:defaultImage];
cell.accessoryView = imageView;
}
cell.textLabel.text = reminderDetailsString;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Bad Access Error Screen shot
But I was unable to accomplish the required task.Can any one please guide me.
Thanks all in advance :)

I am sharing the sample code snippet I used in one of my recent app. I have modified to fit it ur requirements and also please note that I have edited this in notepad and may have some typo errors.(Currently I dnt have mac to test it..:P)
Basic idea is to fill the datasource in viewDidLoad method and use that dataSource to update the tableView. Hope this will be an input to solve your problem.
viewDidLoad
contactsToBeAdded=[[NSMutableArray alloc] init];
ABAddressBookRef addressbook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressbook);
CFIndex numPeople = ABAddressBookGetPersonCount(addressbook);
bool hasPhoneNumber = false;
for (int i=0; i < numPeople; i++) {
hasPhoneNumber = false;
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
ABMutableMultiValueRef phonelist = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex numPhones = ABMultiValueGetCount(phonelist);
if(numPhones > 0){
hasPhoneNumber = true;
}
if(hasPhoneNumber){
NSString *firstName=(NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName=(NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
CFTypeRef ABphone = ABMultiValueCopyValueAtIndex(phonelist, 0);
NSString *personPhone = (NSString *)ABphone;
NSMutableDictionary *dictToAdd = [[[NSMutableDictionary alloc]init]autorelease];
if(firstName != nil && firstName != NULL){
[dictToAdd setObject:firstName forKey:#"firstName"];
CFRelease(firstName);
}
else{
[dictToAdd setObject:#"" forKey:#"firstName"];
}
if(lastName != nil && lastName != NULL){
[dictToAdd setObject:lastName forKey:#"lastName"];
CFRelease(lastName);
}
else{
[dictToAdd setObject:#"" forKey:#"lastName"];
}
if(personPhone != nil && personPhone != NULL){
[dictToAdd setObject:personPhone forKey:#"mobile"];
CFRelease(ABphone);
}
else{
[dictToAdd setObject:#"" forKey:#"mobile"];
}
//Get the first name and last name added to dict and combine it to full name
NSString *firstName = [dictToAdd objectForKey:#"firstName"];
NSString *lastName = [dictToAdd objectForKey:#"lastName"];
NSString *fullName = [firstName stringByAppendingString:lastName];
//Now check whether the full name is same as your reminderToDisplay.Name
if(reminderToDisplay.Name isEqualToString:fullName )
{
CFDataRef imageData = ABPersonCopyImageData(person);
UIImage *image = [UIImage imageWithData:(NSData *)imageData];
if(image != nil && image != NULL){
[dictToAdd setObject:image forKey:#"image"];
CFRelease(imageData);
}
else{
[dictToAdd setObject:[UIImage imageNamed:TEMP_IMG] forKey:#"image"];
}
}
[contactsToBeAdded addObject:dictToAdd];
}
CFRelease(phonelist);
}
CFRelease(allPeople);
CFRelease(addressbook);
[self.tableView reloadData];
numberOfRowsInSection
return contactsToBeAdded.count;
cellForRowAtIndexPath
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];
}
NSDictionary *contactToAdd;
//This way you can get the data added in viewDidLoad method
contactToAdd = [contactsToBeAdded objectAtIndex:indexPath.row];
NSString *fName = (NSString *)[contactToAdd objectForKey:#"firstName"];
NSString *lName = (NSString *)[contactToAdd objectForKey:#"lastName"];
UIImage *contactImg = (UIImage*)[contactToAdd objectForKey:#"image"];

when you use 'ABAddressBookCopyArrayOfAllPeople' you get an array of persons in the addressbook. I believe they are type of ABPerson.
You can now loop over them list like you are. For each one record call 'ABPersonCopyImageData' and that will give you the image data as a CFDataRef.
And remember CFDataRef is a tool free bridge to NSData.

Just try changing your code like this. You are adding dictionary items to ur contactsList, so get each dictionary and check whether it contains a key matching your reminderToDisplay.Name, if yes then do ur stuff..
for (NSDictionary* dict in contactsList)
{
if(nil != [dict objectForKey:reminderToDisplay.Name])
{
//take image here
}
}
UPDATE:
//This is the reminder's name you want to get contact image
ReminderClass *reminderToDisplay = [self.remindersArray objectAtIndex:indexPath.row];
//Here you are adding your contacts with full name as object and kName as key, but check ur kName here
NSDictionary *contactsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:self.contactName, kName, [NSNumber numberWithInt:i], kIndex, nil];
[self.contactsList addObject:contactsDictionary];
//I dont think this part is needed in ur code
NSDictionary *contactsDictionary = [self.contactsList objectAtIndex:indexPath.row];
self.contactName = [contactsDictionary objectForKey:kName];
int addressIndex = [[contactsDictionary objectForKey:kIndex]intValue];
Now you have your contact names as a dictionary in contactsList array, iterate the array and check whether the dictionary contains your reminderToDisplay.Name as key.
for (NSDictionary* dict in contactsList)
{
//Please note that your dict contains key as kName and object as contact name.
if(nil != [dict objectForKey:reminderToDisplay.Name])
{
}
}
Also, I feel like you can do this in one single loop, like when you are iterating the addressbook itself, you can check whether the contact name is in your reminderlist and if available then extract image.
Hope this helps..all the best...

Related

show contact images along with contact name in tableview

I want to show phone contacts along with the pic in table view in alphabetic order.
I have managed to show contact name in correct order but unable to show images in correct order.
I have been trying these for few days but couldn't succeed .
I know how to sort array but don't know how to sort the image data.
please help me guys.
here is my demo code:
NSArray *sortedFirstNames;
- (void)getPersonDetails
{
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
NSMutableArray *firstNames = [[NSMutableArray alloc] init];
NSMutableArray *firstimages = [[NSMutableArray alloc] init];
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName;
if (lastName == nil)
{
fullName = [NSString stringWithFormat:#"%#", firstName];
[firstNames addObject: fullName];
}
else if(firstName ==nil)
{
fullName = [NSString stringWithFormat:#"%#", lastName];
[firstNames addObject: fullName];
}
else
{
fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
[firstNames addObject: fullName];
}
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
//email
imgdata=(__bridge NSData*)ABPersonCopyImageDataWithFormat(contactPerson, kABPersonImageFormatThumbnail);
NSLog(#"newstris%#",imageStr);
if(imgdata==nil)
{
}
else
{
[firstimages addObject:imgdata];
}
[self.tableData addObject:person];
}
sortedFirstNames = [firstNames sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
CFRelease(addressBook);
}
code for showing images in cell:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *image1;
// cell.imageView.frame = CGRectMake(0, 0, 50, 50);
if (person.imgdata==nil) {
image1=[UIImage imageNamed:#"default_profile_pic.jpg"];
}
else
{
image1 = [UIImage imageWithData:person.imgdata];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image1];
imageView.frame = CGRectMake(6.5, 6.5, 45., 45.);
dispatch_sync(dispatch_get_main_queue(), ^{
[cell addSubview:imageView];
});
});
Thanks..
Answer is pretty simple.
Add a field in your Person class which stores a NSData.
Like:
#property (nonatomic, strong) NSData *imageData;
And use:
person.imageData = imgdata;
I too faced same issue. I have fixed this issue by associate object like this.
while loading source array:
objc_setAssociatedObject(hDetails, #"imageUrl", record, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
in cell for row at indexpath :
Record *record = objc_getAssociatedObject(hDetails,#"imageUrl");
for more reference see this :
How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?

Reverse array content?

I am populating a table view with information, but would like it to be populated in reverse, so that any newly added cells (new email messages) would appear on the top, not the bottom.
What am I doing wrong?
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MailCell";
MailCell *cell = (MailCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MailCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
// SLICK
// Anything that should be the same on EACH cell should be here.
UIView *myBackView = [[UIView alloc] initWithFrame:cell.frame];
myBackView.backgroundColor = [UIColor colorWithRed:15.0/255.0 green:140.0/255.0 blue:198.0/255.0 alpha:1];
cell.selectedBackgroundView = myBackView;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.messageText.textAlignment = NSTextAlignmentLeft;
cell.messageText.lineBreakMode = NSLineBreakByTruncatingTail;
}
NSUInteger row = [indexPath row];
// Extract Data
// Use the message object instead of the multiple arrays.
CTCoreMessage *message = [[self allMessages] objectAtIndex:row];
// Sender
CTCoreAddress *sender = [message sender];
NSString *senderName = [sender name];
// Subject
NSString *subject = [message subject];
if ([subject length] == 0)
{
subject = #"(No Subject)";
}
// Body
BOOL isPlain = YES;
NSString *body = [message bodyPreferringPlainText:&isPlain];
body = [body stringByReplacingOccurrencesOfString:#"\n" withString:#" "];
body = [body stringByReplacingOccurrencesOfString:#"\r" withString:#" "];
// Populate Cell
[[cell nameText] setText:senderName];
[[cell subjectField] setText:subject];
[[cell messageText] setText:body];
if ([message isUnread])
{
UIColor *myColor = [UIColor colorWithRed:15.0/255.0 green:140.0/255.0 blue:198.0/255.0 alpha:1.0];
cell.nameText.textColor = myColor;
}
else
{
cell.nameText.textColor = [UIColor blackColor];
}
return cell;
}
How I am loading the array:
- (NSMutableArray *)allMessages
{
if (_allMessages == nil)
{
_allMessages = [[NSMutableArray alloc] init];
}
return _allMessages;
}
You are pulling from NSArray Index [indexPath row] meaning you are starting at index 0 and going to n. Which means you are not in reverse order. You need to reverse your array first. A simple way would be:
- (void)viewWillAppear:(BOOL)animated
{
NSArray *allMessages = [self allMessages];
NSArray* reversedMessages = [[allMessages reverseObjectEnumerator] allObjects];
}
Then in your cellForRowAtIndexPath method you can do:
CTCoreMessage *message = [reversedMessages objectAtIndex:row];

iOS Address Book error on ABMultiValueRef

I'm facing a problem accessing the address book of my iPad 2. In particular I have problems retrieving the email of my contacts. What I want to do is to access the address book, retrieve my contacts and show them in a table view. Everything seems work fine since the name and the surname of the contacts are shown. The problem is with the email property since when I try to retrieve it I get an "EXC_BAD_ACCESS".
The code i wrote to show the tableview record is the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *tableIdentifier = #"tableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableIdentifier] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
NSUInteger row = [indexPath row];
NSString *firstName = (NSString *)ABRecordCopyValue([contacts objectAtIndex:row], kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue([contacts objectAtIndex:row], kABPersonLastNameProperty);
NSString *name = [[NSString alloc] initWithFormat:#"%# %#", lastName,firstName];
[firstName release];
[lastName release];
cell.textLabel.text = name;
[name release];
NSArray *emails = [[self getEmailForPerson:row] retain];
/*......*/
return cell;
}
While the function to get the email of my contacts is the following:
- (NSArray *)getEmailForPerson:(NSInteger)index{
//Create the array where emails will be stored
NSMutableArray *m = [[[NSMutableArray alloc] init] autorelease];
//Get the email properties
ABMultiValueRef mails = ABRecordCopyValue([self.contacts objectAtIndex:index], kABPersonEmailProperty);
//Iterate in the multi-value properties
for (int i=0; i<ABMultiValueGetCount(mails); i++) {
//Get the email
NSString *mail = (NSString *) ABMultiValueCopyValueAtIndex(mails, i);
//Add the email to the array previously initializated
[m addObject:mail];
[mail release];
}
CFRelease(mails);
return m;
}
When I run the debugger after this statement
ABMultiValueRef mails = ABRecordCopyValue([self.contacts objectAtIndex:index], kABPersonEmailProperty);
mails seems not initialized since its adress is 0x0 but I cannot understand why.
I hope somebody can help me.
Thanks in advance
ABMultiValueRef mails = ABRecordCopyValue([self.contacts objectAtIndex:index], kABPersonEmailProperty);
It works fine in my app.
Check framework & self.contacts.
My app use two frameworks.
#import <AddressBook/AddressBook.h>
#import <AddressBook/ABAddressBook.h>

UISearchBar in iPhone/iPad application

I have data like this...(All the data comes from .plist file...)
Searching Array - (
{
FirstName = "Ramesh";
LastName = "Bean";
EmpCode = 1001;
},
{
FirstName = "Rohan";
LastName = "Rathor";
EmpCode = 102;
},
{
FirstName = "Priya";
LastName = "Malhotra";
EmpCode = 103;
},
{
FirstName = "Mukesh";
LastName = "Sen";
EmpCode = 104;
},
{
FirstName = "Priya";
LastName = "Datta";
EmpCode = 105;
}
)
I want implement search data from this array on the basis of FirstName (key).
I am able to search data with the "FirstName(Key)"
but after filtering data suppose i clicked Row( in the data) which is displayed in the TableView. It Navigate me to New-Controller with all the information of that particular employee (like: FirstName,LastName,EmpCode).
How can i get information?
As i gone through the search sample codes.
Here is my search code...
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
NSInteger TotalNoOfRecords=[self.SearchtableDataSource count];
for (int i=0;i<TotalNoOfRecords;i++)
{ NSDictionary *dictionary = [self.SearchtableDataSource objectAtIndex:i];
NSArray *array = [dictionary objectForKey:#"FirstName"];
[searchArray addObject:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
{
[copyListOfItems addObject:sTemp];
}
}
How can i improve this code?....Please guide me... [searchArray release]; searchArray = nil;
How we maintain all the "Keys(FirstName,LastName,EmpCode)" in the searchArray please help me out? Thanks...
I think the best approach would be to make an array of NSDictionary which has value for three keys namely "FirstName", "LastName", "EmpCode"
now to filter the data according to "FirstName" use NSPredicate instead of for loop,
NSString *searchText = searchBar.text;
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"FirstName like[cd] %#",searchText];
NSArray* filteredArray = [self.SearchtableDataSource filteredArrayUsingPredicate:predicate];
In method cellForRowAtIndexPath
NSDictionary* currentEmp = [filteredArray objectAtIndex:inddexPath.row];
display the information in this currentEmp.
Similarly in didSelectRowAtIndexPath
NSDictionary* currentEmp = [filteredArray objectAtIndex:inddexPath.row];
and pass this dictionary in the next ViewController in which u want to dispaly the detail of the current employ.
if u have two table views one that of searchDisplayController (showing the filtered result)
and one which is showing the whole result, then u can track this by having a BOOL variable tacking that is if filtering is active or not.
Here is what i have done and its working fine with me(tested it). I have taken one IBOutlet of UISearchBar so here is the code for ur .h file
#interface SearchForEmp : UIViewController<'UISearchDisplayDelegate,UISearchBarDelegate,UITableViewDelegate,UITableViewDataSource> {
IBOutlet UISearchBar* mySearchBar;
UISearchDisplayController* mySearchDisplayController;
NSMutableArray* allEmp;
NSMutableArray* filteredEmp;
BOOL isFilatering;
}
#end
Now in .m file
-(void)viewDidLoad
{
[super viewDidLoad];
mySearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
mySearchDisplayController.searchResultsDelegate = self;
mySearchDisplayController.searchResultsDataSource = self;
mySearchDisplayController.delegate = self;
isFilatering = NO;
filteredEmp = [[NSMutableArray alloc] init];
allEmp = [[NSMutableArray alloc] init];
NSDictionary *temp;
for (int i = 0; i < 30; i++) {
temp = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:#"FirstName_%d",i],#"FirstName",[NSString stringWithFormat:#"LastName_%d",i],#"LastName",[NSNumber numberWithInt:1000+i],#"EmpCode",nil];
[allEmp addObject:temp];
}
}
for e.g purpose i have thake an array of 30 Dictionaries, each with a unique name.For table view data source and delegate .....
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (isFilatering) {
return [filteredEmp count];
}
else {
return [allEmp count];
}
return [allEmp count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] init] autorelease];
}
NSDictionary* temp;
if (isFilatering) {
temp = [filteredEmp objectAtIndex:indexPath.row];
}
else {
temp = [allEmp objectAtIndex:indexPath.row];
}
cell.textLabel.text = [NSString stringWithFormat:#"%# %#",[temp objectForKey:#"FirstName"],[temp objectForKey:#"LastName"]];
return cell;
}
Now as far as searching is concerned here is what u need to do .......
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate* predicate = [[NSPredicate predicateWithFormat:#"self.FirstName contains %#",mySearchBar.text] retain];
filteredEmp = [[allEmp filteredArrayUsingPredicate:predicate] retain];
}
-(void) searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
isFilatering = YES;
}
-(void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
isFilatering = NO;
}
I hope that helps you understanding the things, dont forget to add retain in line
filteredEmp = [[allEmp filteredArrayUsingPredicate:predicate] retain];
because method filteredArrayUsingPredicate: is an accessor method and its retain count is handled by the NSArray so have access to the filtered array u need to pass a retain msg to it.

Iphone xcode simulator crashes when I move up and down on a table row

I can't get my head round this. When the page loads, everything works fine - I can drill up and down, however 'stream' (in the position I have highlighted below) becomes not equal to anything when I pull up and down on the tableview. But the error is only sometimes. Normally it returns key/pairs.
If know one can understand above how to you test for // (int)[$VAR count]} key/value pairs
in a NSMutableDictionary object
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell = #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
}
NSInteger row = [indexPath row];
//NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row];
NSString *level = self.atLevel;
if([level isEqualToString:#"level2"])
{
NSMutableDictionary *stream = [[NSMutableArray alloc] init];
stream = (NSMutableDictionary *) [dataList objectAtIndex:row];
// stream value is (int)[$VAR count]} key/value pairs
if ([stream valueForKey:#"title"] )
{
cell.textLabel.text = [stream valueForKey:#"title"];
cell.textLabel.numberOfLines = 2;
cell.textLabel.font =[UIFont systemFontOfSize:10];
NSString *detailText = [stream valueForKey:#"created"];
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.font= [UIFont systemFontOfSize:9];
cell.detailTextLabel.text = detailText;
NSString *str = #"http://www.mywebsite.co.uk/images/stories/Cimex.jpg";
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:str]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
cell.imageView.image = newsImage;
[stream release];
}
}
else
{
cell.textLabel.text = [dataList objectAtIndex:row];
}
return cell;
}
Thanks for your time
You are both leaking and over-releasing the stream dictionary:
NSMutableDictionary *stream = [[NSMutableArray alloc] init]; // <-- Create a new dictionary
stream = (NSMutableDictionary *) [dataList objectAtIndex:row]; // <-- Overwrite the reference with another dictionary. Previous dictionary is lost...
...
[stream release]; // <-- You are releasing an object you don't have the ownership.
You should remove the dictionary creation as it is useless and the release as you don't own the object.
I didn't really understand the question, but...
You can test for number of values in a dictionary by:
if ([[myDictionary allKeys] count] == someNumber) {
// do something...
}