Using core data to populate my table view. The thing I am not getting is that how can I delete a single entry from the core data.
Here is the code I am using:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == favouritesTable) {
cellValue = [licensePlateArray objectAtIndex:indexPath.row];
} else { // handle search results table view
cellValue = [filteredListItems objectAtIndex:indexPath.row];
}
static NSString *CellIdentifier = #"vlCell";
VehicleListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"Cell Created");
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"VehicleListCell" owner:nil options:nil];
for (id currentObject in nibObjects) {
if ([currentObject isKindOfClass:[VehicleListCell class]]) {
cell = (VehicleListCell *)currentObject;
}
}
UILongPressGestureRecognizer *pressRecongnizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(tableCellPressed:)];
pressRecongnizer.minimumPressDuration = 0.5f;
[cell addGestureRecognizer:pressRecongnizer];
[pressRecongnizer release];
}
cell.textLabel.font = [UIFont systemFontOfSize:10];
Favouritesdata *favdata = [licensePlateArray objectAtIndex:indexPath.row];
[[cell ignition] setImage:[UIImage imageNamed:#"ignition.png"]];
[[cell direction] setImage:[UIImage imageNamed:#"south.png"]];
cell.licPlate.text = [favdata licenseplate];
NSLog(#"cellvalue for cellforRow: %#", cell.licPlate.text);
return cell;}
In the method of UILongPressGestureRecognizer:
- (void)tableCellPressed:(UILongPressGestureRecognizer *)recognizer{
if (recognizer.state != UIGestureRecognizerStateBegan) {
return;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil] ;
[alert addButtonWithTitle:#"Remove from Favourites"];
[alert addButtonWithTitle:#"Take to Map"];
[alert show];}
In alert view method:
-(void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alert buttonTitleAtIndex:buttonIndex];
NSManagedObjectContext *contextFav = [app managedObjectContext];
Favouritesdata * favourites = [NSEntityDescription insertNewObjectForEntityForName:#"Favouritesdata" inManagedObjectContext:contextFav];
if([title isEqualToString:#"Remove from Favourites"])
{
NSLog(#"cellValueForLongPress: %#", cellValueForLongPress);
if (cellValueForLongPress <= 0) {
NSLog(#"No data to delete");
}
else {
favourites.licenseplate = cellValueForLongPress;
}
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
else if([title isEqualToString:#"Take to Map"])
{
NSLog(#"Go to MapView");
}
NSError *error;
if (![context save:&error]) {
NSLog(#"Error Occured");
}}
If you want to delete managed object from CoreData storage then you should have:
Reference to NSManagedObjectContext from where you will remove object : context
Reference to NSManagedObject that you want to delete: object
Then it will be very simple to remove object:
[context deleteObject:object];
You should know
index of the row to remove, for example, i.
retrieve it from your array: NSObject *object = [licensePlateArray objectAtIndex:i];
remove it from db : [context deleteObject:object];
remove it from array: [licensePlateArray removeObject:object];
You have to identify your NSManagedObject and then call deleteObject on your managedObjectContext. Then this object will be removed from your core data.
But you have to provide a mechanism to "somehow" get the object behind a specific tableview row.
Related
Using core data to populate my table view. The thing I am not getting is that how can I delete a single entry from the core data.
I am using uitableview not the controller.
Here is the code I am using:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == favouritesTable) {
cellValue = [licensePlateArray objectAtIndex:indexPath.row];
} else { // handle search results table view
cellValue = [filteredListItems objectAtIndex:indexPath.row];
}
static NSString *CellIdentifier = #"vlCell";
VehicleListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"Cell Created");
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"VehicleListCell" owner:nil options:nil];
for (id currentObject in nibObjects) {
if ([currentObject isKindOfClass:[VehicleListCell class]]) {
cell = (VehicleListCell *)currentObject;
}
}
UILongPressGestureRecognizer *pressRecongnizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(tableCellPressed:)];
pressRecongnizer.view.tag = indexPath.row;
pressRecongnizer.minimumPressDuration = 0.5f;
[cell addGestureRecognizer:pressRecongnizer];
[pressRecongnizer release];
}
cell.textLabel.font = [UIFont systemFontOfSize:10];
Favouritesdata *favdata = [licensePlateArray objectAtIndex:indexPath.row];
[[cell ignition] setImage:[UIImage imageNamed:#"ignition.png"]];
[[cell direction] setImage:[UIImage imageNamed:#"south.png"]];
cell.licPlate.text = [favdata licenseplate];
NSLog(#"cellvalue for cellforRow: %#", cell.licPlate.text);
return cell;}
In the method of UILongPressGestureRecognizer:
- (void)tableCellPressed:(UILongPressGestureRecognizer *)recognizer{
if (recognizer.state != UIGestureRecognizerStateBegan) {
return;
}
VehicleListCell* cell = (VehicleListCell *)[recognizer view];
cellValueForLongPress = cell.licPlate.text;
NSLog(#"cell value: %#", cellValueForLongPress);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil] ;
alert.tag = recognizer.view.tag;
[alert addButtonWithTitle:#"Remove from Favourites"];
[alert addButtonWithTitle:#"Take to Map"];
[alert show];}
here in alert view method the selected row will be deleted (if([title isEqualToString:#"Remove from Favourites"])):
-(void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alert buttonTitleAtIndex:buttonIndex];
NSManagedObjectContext *contextFav = [app managedObjectContext];
Favouritesdata * favourites = [NSEntityDescription insertNewObjectForEntityForName:#"Favouritesdata" inManagedObjectContext:contextFav];
if([title isEqualToString:#"Remove from Favourites"])
{
NSLog(#"cellValueForLongPress: %#", cellValueForLongPress);
///////// to remove the object from core data
[licensePlateArray removeObjectAtIndex:alert.tag];
}
else if([title isEqualToString:#"Take to Map"])
{
NSLog(#"Go to MapView");
}
NSError *error;
if (![context save:&error]) {
NSLog(#"Error Occured");
}
[favouritesTable reloadData];}
Write this in cellForRowAtIndexPath
UILongPressGestureRecognizer *pressRecongnizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(tableCellPressed:)];
pressRecongnizer.view.tag = indexPath.row;
pressRecongnizer.minimumPressDuration = 0.5f;
[cell addGestureRecognizer:pressRecongnizer];
[pressRecongnizer release];
and use alertview like this
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil] ;
alert.tag = recognizer.view.tag;
[alert addButtonWithTitle:#"Remove from Favourites"];
[alert addButtonWithTitle:#"Take to Map"];
[alert show];
then write this in -(void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
[YourArray removeObjectAtIndex:alert.tag];
[YourTable reloadData];
Please use this code at appropriate place in your code..
Happy Coding..
I made tableView with filteredReservations array wich contains Rezervacija objects.
I added custom button "board", and when button is clicked, I ask with alert view to confirm this and then sending request to server. When receive server's response I need to delete row from table and object from filteredReservations array.
When I delete first row it's ok, but after that in filteredReservations instead of Rezervacija object, I got UIButton objects! I don't know HOW :)
Code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return([filteredReservations count]);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
Reservation *reservation = [filteredReservations objectAtIndex:indexPath.row];
NSString *label = [[NSString alloc] initWithFormat:#"%# (%d)", reservation.name, reservation.seatsNumber];
cell.textLabel.text = label;
[label release];
[reservation release];
tableView.allowsSelection = FALSE;
UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cellButton setFrame:CGRectMake(430.0, 2.0, 106.0, 40.0)];
[cellButton setTitle:#"Board" forState:UIControlStateNormal];
[cellButton addTarget:self action:#selector(BoardPassengers:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:cellButton];
cellButton.tag = indexPath.row;
return cell;
}
-(void)BoardPassengers:(id)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Question" message:#"Do you want to board passengers?"
delegate:self cancelButtonTitle:#"Odustani" otherButtonTitles:#"Da", nil];
[alert show];
[alert release];
passengerForBoarding = [NSIndexPath indexPathForRow:((UIControl*)sender).tag inSection:1];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
NSLog(#"cancel");
}
else
{
Reservation *reservationNew = [filteredReservations objectAtIndex:passengerForBoarding.row];
NSString *reservationId = [[NSString alloc] initWithFormat:#"%d",reservationNew.reservationId];
params = [NSDictionary dictionaryWithObjectsAndKeys: #"1", #"tour_id", #"1", #"bus_number",reservationId, #"reservation_id", nil];
[[RKClient sharedClient] post:#"/service/boardingToBus.json" params:params delegate:self];
[DSBezelActivityView newActivityViewForView:self.view withLabel:#"Boarding..."];
}
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
if([[request resourcePath] isEqualToString:#"/service/boardingToBus.json"]){
if([[response bodyAsString] isEqualToString:#"ERROR"]){
[DSBezelActivityView removeViewAnimated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Error."
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}else{
[DSBezelActivityView removeViewAnimated:YES];
[filteredReservations removeObjectAtIndex:passengerForBoarding.row];
[self.tableView reloadData];
//[self.tableView beginUpdates];
//[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:passengerForBoarding]
// withRowAnimation:UITableViewRowAnimationFade];
// NSLog(#"%i", passengerForBoarding.row);
//[self.tableView endUpdates];
}
}
}
It sounds like you need to make sure the table view is explicitly aware of how many filtered reservations it needs to display.
// assuming only one section for your table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return([filteredReservations count]);
}
For more info:
http://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:
Hey you can get the value of "Reservation ID" By this.
-(void)BoardPassengers:(id)sender{
Reservation *reservationNew = [filteredReservations objectAtIndex:[sender tag]];
NSString *reservationId = [NSString StringWithFormat:#"%d",reservationNew.reservationId];}
Or you can use this value anywhere you want like you have mentioned via alert-box.
I'm stuck at the point of parsing a JSON array of dicts (http://www.cjs-design.nl/json.php) into a tableview. I just want to display the title's first, ill figure out detailviews later.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSString *rawJson = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.cjs-design.nl/json.php"]];
// No connection or file not found
if ([rawJson length] == 0) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Foutmelding" message:#"De URL kon niet worden gevonden" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
[rawJson release];
return;
}
SBJSON *parser = [[[SBJSON alloc] init] autorelease];
// 1. get the top level value as a dictionary
NSDictionary *jsonObject = [parser objectWithString:rawJson error:NULL];
// 2. get the object as an array
NSArray *list = [jsonObject objectForKey:#"book"];
// 3. iterate the array; each element is a dictionary.
for (NSDictionary *book in list)
{
// that contains a string for the key "title"
NSString *title = [book objectForKey:#"title"];
cell.textLabel.text = title;
}
return cell;
}
Somewhere i.e. viewDidLoad, you need to parse your JSON. Then implement UITableView's dataSource methods.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *book = [list objectAtIndex:indexPath.row];
NSString *title = [book objectForKey:#"title"];
cell.titleLabel.text = title;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *rawJson = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.cjs-design.nl/json.php"]];
// No connection or file not found
if ([rawJson length] == 0) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Foutmelding" message:#"De URL kon niet worden gevonden" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
[rawJson release];
return;
}
SBJsonParser *parser = [[SBJsonParser alloc] init];
// 1. get the top level value as a dictionary
NSDictionary *jsonObject = [parser objectWithString:rawJson error:NULL];
NSLog(#"Dict: %#",jsonObject);
list = [jsonObject objectForKey:#"book"];
NSLog(#"List: %#",list);
[rawJson release];
}
When I NSlog them, they both print Null, so the string doesnt get parsed? the string contains a dictionary of arrays tho.
I have designed a custom table cell. which displays product information.
When i implement CellForRowAtIndexPath I am doing this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *sectionTableCellIdentifier = [[NSString alloc] initWithFormat:#"GLItemTableCellIdentifierNumber%d",indexPath.section];
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"GLItemDetailsTableCellIdentifier"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:sectionTableCellIdentifier];
if (cell == nil)
{
NSDictionary *dict = [self.listData objectAtIndex:indexPath.row];
ItemsListTableCell *cell = (ItemsListTableCell *)[tableView dequeueReusableCellWithIdentifier:sectionTableCellIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ItemsListTableCell"
owner:self options:nil];
for (id oneObject in nib)
{
if ([oneObject isKindOfClass:[ItemsListTableCell class]])
{
cell = (ItemsListTableCell *)oneObject;
}
}
NSString *priceinfo = [[NSString alloc] initWithFormat:#"$%#",[dict objectForKey:#"CurrentPrice"]];
NSString *sizeinfo = [[NSString alloc] initWithFormat:#"Size: %#",[dict objectForKey:#"Size"]];
NSString *upcInfo = [[NSString alloc] initWithFormat:#"UPC: %#",[dict objectForKey:#"ID"]];
NSString *strQuantity = [[NSString alloc] initWithFormat:#"%#",[dict objectForKey:#"Quantity"]];
cell.lblProductName.text = [dict objectForKey:#"Name"];
cell.lblSize.text = sizeinfo;
cell.lblBrand.text = [dict objectForKey:#"BrandName"];
cell.lblProductCode.text = upcInfo;
cell.lblQuantity.text = strQuantity;
cell.lblPrice.text = priceinfo;
cell.lblStoreName.text = [dict objectForKey:#"StoreName"];
cell.isSelected = NO;
[cell.btnSelected addTarget:self action:#selector(cellButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[upcInfo release];
[priceinfo release];
[strQuantity release];
[sizeinfo release];
return cell;
}
return cell;
}
now for the click event I am doing
- (IBAction)cellButtonTapped:(id)sender
{
UIView *contentView = [sender superview];
ItemsListTableCell *cell = (ItemsListTableCell *)[contentView superview];
NSIndexPath *indexPath = [table indexPathForCell:cell];
NSUInteger buttonRow = [[self.table
indexPathForCell:cell] row];
NSUInteger buttonSection = [[self.table
indexPathForCell:cell] section];
NSLog(#"Index Path Row : %d",buttonRow);
NSLog(#"Index Path Section : %d",buttonSection);
ItemsListTableCell *buttonCell =
(ItemsListTableCell *)[table cellForRowAtIndexPath:indexPath];
if (buttonCell.isSelected == YES)
{
buttonCell.isSelected = NO;
UIImage *image = [[UIImage imageNamed:#"checkbox-empty.png"] autorelease];
[buttonCell.btnSelected setImage:image forState:UIControlStateNormal];
}
else
{
buttonCell.isSelected = YES;
UIImage *image = [[UIImage imageNamed:#"checkbox-full.png"] autorelease];
[buttonCell.btnSelected setImage:image forState:UIControlStateNormal];
}
self.txtQuantity.text = buttonCell.lblQuantity.text;
NSString *buttonTitle = buttonCell.lblProductName.text;
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"You tapped the button"
message:[NSString stringWithFormat:
#"You tapped the button for %#", buttonTitle]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
The Problem is when i click on check button it is going to the event. but I am unable to detect what is the parent cell . as there are some values in cell.
Instead of creating such an event (IBAction), you could do all of these in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
{
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
{
selectedCell.accessoryType = UITableViewCellAccessoryNone;
}
}
If you want a checkmark of your own style, you could set them up here and finish off things. Makes stuff easier !
I have integrated xmpp in my app and able to list all the users in a table view, but I only want to display the online users and then want to implement the feature to send and recieve messages to my online friends...
Please suggest me some helpful code...
Here is my code, executed after facebook login.
- (void)fbDidLogin
{
NSLog(#"logged in.....................");
[appDelegate.facebook requestWithGraphPath:#"me" andDelegate:self];
DDLogVerbose(#"%s accessToken: %# expirationDate: %#",__PRETTY_FUNCTION__,appDelegate.facebook.accessToken,appDelegate.facebook.expirationDate);
self.accessToken = appDelegate.facebook.accessToken;
if (xmppStreamFB) {
[xmppStreamFB release];
xmppStreamFB = nil;
}
xmppStreamFB = [[XMPPStreamFacebook alloc] init];
xmpReconnect = [[XMPPReconnect alloc] initWithStream:xmppStreamFB];
if (xmppRosterStorage) {
[xmppRosterStorage release];
xmppRosterStorage = nil;
}
xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
if (xmppRoster) {
[xmppRoster release];
xmppRoster = nil;
}
xmppRoster = [[XMPPRoster alloc] initWithStream:xmppStreamFB rosterStorage:xmppRosterStorage];
[xmppStreamFB addDelegate:self];
[xmppRoster addDelegate:self];
[xmppRoster setAutoRoster:YES];
xmppStreamFB.myJID = [XMPPJID jidWithString:[NSString stringWithFormat:#"%##chat.facebook.com", uid]];
// You may need to alter these settings depending on the server you're connecting to
allowSelfSignedCertificates = NO;
allowSSLHostNameMismatch = YES;
// Uncomment me when the proper information has been entered above.
NSError *error = nil;
if (![xmppStreamFB connect:&error])
NSLog(#"Error connecting: %#", error);
if(!tableView)
{
tableView = [[UITableView alloc]initWithFrame:CGRectMake(0,0, 480, 320) style:UITableViewStylePlain];
}
[tableView setFrame:CGRectMake(0,0, 480, 320)];
[tableView setTag:2];
[tableView setDelegate:self];
[tableView setDataSource:self];
[tableView setHidden:NO];
[tableView setBackgroundColor:[UIColor clearColor]];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[tableView setAlpha:1.0];
[self.view addSubview:tableView];
[self.tableView reloadData];
[self showTopBar];
}
I don't know the actual flow of the xmpp framework for showing users online and to implement chat feature...
i have the following delegate methods as well..
- (void)xmppStreamDidSecure:(XMPPStreamFacebook *)sender
{
NSLog(#"---------- xmppStreamDidSecure: ----------");
}
- (void)xmppStreamDidConnect:(XMPPStreamFacebook *)sender
{
NSLog(#"---------- xmppStreamDidConnect: ----------");
isOpen = YES;
NSError *error = nil;
if (![self.xmppStreamFB authenticateWithAppId:_APP_ID accessToken:self.accessToken error:&error])
{
NSLog(#"Error authenticating: %#", error);
}
else {
NSLog(#"NO Error authenticating:");
/*
ChatViewController *cvc = [[ChatViewController alloc] init];
[self.view addSubview:cvc.view];*/
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
NSLog(#"---------- xmppStreamDidAuthenticate: ----------");
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
NSLog(#"---------- xmppStream:didNotAuthenticate: ----------");
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
NSLog(#"---------- xmppStream:didReceiveIQ: ----------");
/*
ChatViewController *cvc = [[ChatViewController alloc] init];
[self.view addSubview:cvc.view];*/
return NO;
}
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
NSLog(#"---------- xmppStream:didReceiveMessage: ----------");
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
NSLog(#"---------- xmppStream:didReceivePresence: ----------");
}
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
{
NSLog(#"---------- xmppStream:didReceiveError: ----------");
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender
{
NSLog(#"---------- xmppStreamDidDisconnect: ----------");
if (!isOpen)
{
NSLog(#"Unable to connect to server. Check xmppStream.hostName");
}
}
And the two methods for online and offline user presence, but don't know how to modify them for my task:
- (void)goOnline
{
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[[self xmppStream] sendElement:presence];
}
- (void)goOffline
{
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[presence addAttributeWithName:#"type" stringValue:#"unavailable"];
[[self xmppStream] sendElement:presence];
}
finally after lots of efforts i found out how to show online/offline/away users.
i'm going to tell you step by step how i did it, so that i can be useful for the less experienced users too..
Step 1- on click of chat button i'm calling the following method-
-(void) chatFacebook
{
if (appDelegate.facebook == nil)
{
appDelegate.facebook = [[[Facebook alloc] initWithAppId:_APP_ID] autorelease];
}
if (!accessToken)
{
[appDelegate.facebook authorize:[XMPPStreamFacebook permissions] delegate:self appAuth:NO safariAuth:NO];
}
else
{
[self fbDidLogin];
}
}
step 2- Now its time for login dialog delegate methods to come in , if the login is successfull the fbDidLogin is called, here are the delegate methods you should include-
#pragma mark FBLoginDialogDelegate
/**
* Called when the user successfully logged in.
*/
- (void)fbDidLogin
{
NSLog(#"logged in.....................");
[appDelegate.facebook requestWithGraphPath:#"me" andDelegate:self];
DDLogVerbose(#"%s accessToken: %# expirationDate: %#",__PRETTY_FUNCTION__,appDelegate.facebook.accessToken,appDelegate.facebook.expirationDate);
self.accessToken = appDelegate.facebook.accessToken;
if (xmppStream) {
[xmppStream release];
xmppStream = nil;
}
xmppStream = [[XMPPStreamFacebook alloc] init];
xmpReconnect = [[XMPPReconnect alloc] initWithStream:xmppStream];
if (xmppRosterStorage) {
[xmppRosterStorage release];
xmppRosterStorage = nil;
}
xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
if (xmppRoster) {
[xmppRoster release];
xmppRoster = nil;
}
xmppRoster = [[XMPPRoster alloc] initWithStream:xmppStream rosterStorage:xmppRosterStorage];
[xmppStream addDelegate:self];
[xmppRoster addDelegate:self];
[xmppRoster setAutoRoster:YES];
xmppStream.myJID = [XMPPJID jidWithString:[NSString stringWithFormat:#"%##chat.facebook.com", uid]];
// You may need to alter these settings depending on the server you're connecting to
allowSelfSignedCertificates = NO;
allowSSLHostNameMismatch = YES;
// Uncomment me when the proper information has been entered above.
NSError *error = nil;
if (![xmppStream connect:&error])
NSLog(#"Error connecting: %#", error);
if(!tableView)
{
tableView = [[UITableView alloc]initWithFrame:CGRectMake(0,0, 480, 320) style:UITableViewStylePlain];
}
[tableView setFrame:CGRectMake(0,0, 480, 320)];
[tableView setTag:2];
[tableView setDelegate:self];
[tableView setDataSource:self];
[tableView setHidden:NO];
[tableView setBackgroundColor:[UIColor clearColor]];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[tableView setAlpha:1.0];
[self.view addSubview:tableView];
[self.tableView reloadData];
[self showTopBar];
}
/**
* Called when the user dismissed the dialog without logging in.
*/
- (void)fbDidNotLogin:(BOOL)cancelled
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Canceled" message:#"Login cancled" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
/**
* Called when the user logged out.
*/
- (void)fbDidLogout
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Logged out" message:#"Logged out" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
Step 3- The second line of the fbDidLogin method calls the FBRequestDelegate methods so you should include this protocol in your .h class, to get the uid of the user(which is logged in , means the current user) you need to implement the following methods-
pragma mark
pragma mark FBRequestDelegate
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error{
DDLogError(#"%s %#",__PRETTY_FUNCTION__,error);
//[appDelegate.facebook logout:self];
}
/**
* Called when a request returns and its response has been parsed into an object.
* The resulting object may be a dictionary, an array, a string, or a number, depending
* on thee format of the API response.
*/
- (void)request:(FBRequest*)request didLoad:(id)result {
DDLogVerbose(#"%s............DDLOG................... %#",__PRETTY_FUNCTION__,result);
NSLog(#" Result>>>>-------%#", result);
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:(NSMutableDictionary *)result];
uid = [dict objectForKey:#"id"];
NSLog(#"iddddddddddddd---%#", uid);
}
Step 4- Now comes the table view DataSource and Delegate methods, you need to implement these, here are the methods-
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView1
{
return [[[self fetchedResultsController] sections] count];
// need to implement NSFetchedResultsControllerDelegate
}
- (NSString *)tableView:(UITableView *)sender titleForHeaderInSection:(NSInteger)sectionIndex
{
NSArray *sections = [[self fetchedResultsController] sections];
if (sectionIndex < [sections count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:sectionIndex];
int section = [sectionInfo.name intValue];
switch (section)
{
case 0 : return #"Available";
case 1 : return #"Away";
default : return #"Offline";
}
}
}
return #"";
}
- (NSInteger)tableView:(UITableView *)tableView1 numberOfRowsInSection:(NSInteger)sectionIndex
{
NSArray *sections = [[self fetchedResultsController] sections];
if (sectionIndex < [sections count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:sectionIndex];
return sectionInfo.numberOfObjects;
NSLog(#"section ifnfo ===========%#", sectionInfo);
}
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
user = [[self fetchedResultsController] objectAtIndexPath:indexPath];
cell.textLabel.text = user.displayName;
cell.textLabel.textColor = [UIColor whiteColor];
cell1 = cell;
}
Step 5- Finally you also need to implement NSFetchedResultsController delegate methods , so that you can fill table with the chat users, here are the methods-
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController == nil)
{
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPUserCoreDataStorage"
inManagedObjectContext:[self managedObjectContext]];
NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:#"sectionNum" ascending:YES];
NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:#"displayName" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, sd2, nil];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:10];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[self managedObjectContext]
sectionNameKeyPath:#"sectionNum"
cacheName:nil];
[fetchedResultsController setDelegate:self];
[sd1 release];
[sd2 release];
[fetchRequest release];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
{
NSLog(#"Error performing fetch: %#", error);
}
}
return fetchedResultsController;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[[self tableView] reloadData];
}
Step 6 - Compile and run your code ,user list should appear in table view
if any problems appears, please share , i'm always here to help you .And please dont mind if there are some mistakes while posting this answer, cz i'm posting just for the third time
Thanks.