2011-03-14 8 views
7

He integrado xmpp en mi aplicación y puedo mostrar todos los usuarios en una vista de tabla, pero solo quiero mostrar los usuarios en línea y luego quiero implementar la función para enviar y reciba mensajes a mis amigos en línea ...Cómo enumerar solo usuarios en línea en Facebook con xmpp framework

por favor, me sugieren algún código útil ...

Aquí está mi código, ejecutado después de 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]; 

} 

No sé el flujo real del marco XMPP para mostrar a los usuarios en línea y poner en práctica la función de chat ...

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"); 
    } 
} 

Y los dos métodos para la presencia del usuario en línea y fuera de línea, pero no saben cómo modificarlos para mi tarea:

- (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]; 
} 
+0

Muy útil: http://msmvps.com/blogs/jon_skeet/archive/2010/08/29/writing-the-perfect-question.aspx –

+0

Hola Rakesh, esa es una gran sugerencia, pero ¿qué es 'managedObjectContext'. ¿Puede darnos un código de muestra para que podamos entenderlo? Gracias por adelantado. – Apekshit

+0

Hola Rakesh, ¿podrías sugerirme algún enlace de tutorial o cualquier demo para Xmppframework o cualquier ayuda? En el método authenticateWithPassword estoy obteniendo este error messase- "error de análisis sintáctico de cadenas"? Gracias – Yogendra

Respuesta

7

finalmente después de muchos esfuerzos que descubrí cómo mostrar en línea/fuera de línea/lejos usuarios.

voy a decir paso a paso cómo lo hice, de modo que pueda ser útil para los usuarios menos experimentados también ..

Paso 1- el clic del botón de chat Voy a llamar al tras método-

-(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]; 
} 

}

paso 2- Ahora es el momento para los métodos de delegado de diálogo de inicio de sesión para entrar, si el inicio de sesión es exitoso el fbDidLogin se llama, aquí están los métodos de delegado debe incluir:

#pragma mark FBLoginDialogDelegate 

/** * llama cuando el usuario ha iniciado sesión con éxito en. */

- (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]; 

}

/** * Se llama cuando el usuario desestimó el diálogo sin iniciar sesión. */

- (void)fbDidNotLogin:(BOOL)cancelled 
    { 
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Canceled" message:@"Login cancled" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
[alert show]; 
[alert release]; 
} 

/** * Llamado cuando planees n el usuario ha cerrado sesión. */

- (void)fbDidLogout 
{ 
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Logged out" message:@"Logged out" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
[alert show]; 
[alert release]; 
    } 

Paso 3 La segunda línea del método fbDidLogin llama a los métodos FBRequestDelegate por lo que debe incluir este protocolo en su clase .h, para obtener el identificador de usuario del usuario (que está conectado, medios el usuario actual) que necesita para poner en práctica los siguientes métodos-

marca Pragma

marca Pragma FBRequestDelegate

- (void)request:(FBRequest*)request didFailWithError:(NSError*)error{ 
    DDLogError(@"%s %@",__PRETTY_FUNCTION__,error); 
    //[appDelegate.facebook logout:self]; 
} 

/** * Se invoca cuando una solicitud regresa y su respuesta ha sido analizada en un objeto. * El objeto resultante puede ser un diccionario, una matriz, una cadena o un número, según * en el formato de la respuesta de la API. */

- (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); 

} 

Paso 4 Ahora viene la vista de la tabla origen de datos y los métodos de delegado, lo que necesita para poner en práctica estos, aquí son los métodos-

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView1 
{ 
    return [[[self fetchedResultsController] sections] count]; 

// necesitan para implementar NSFetchedResultsControllerDelegate }

- (NSString *)tableView:(UITableView *)sender titleForHeaderInSection:(NSInteger)sectionIndex 

{ NSArray * sections = [[self-fetchedResultsController] secciones];

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; 

}

Paso 5- Por último también es necesario para poner en práctica los métodos de delegado NSFetchedResultsController, de modo que usted puede llenar la mesa con los usuarios de chat, aquí están los métodos-

- (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]; 
} 

Paso 6 - Compilar y ejecutar su código, la lista de usuarios debe aparecer en la vista de tabla

si aparece algún problema, por favor comparta, siempre estoy aquí para ayudarlo. Y por favor no importa si t aquí hay algunos errores al publicar esta respuesta, cz estoy publicando solo por tercera vez

Gracias.

+0

gracias pugal para editar .... – Rakesh

+0

uid = [dict objectForKey: @ "id"]; debe reemplazarse con uid = [dict objectForKey: @ "uid"]; – manutd

+0

@Rakesh Estoy familiarizado con la API de Facebook pero soy muy nuevo en XMPP estándar, y recientemente publiqué esta pregunta (http://stackoverflow.com/questions/27222641/fetch-online-presence-for-thousands-of-facebook- usuarios de la aplicación). ¿El método anterior ofrecería una forma de devolver el estado en línea de manera eficiente para los usuarios de aplicaciones de Facebook que no son amigos entre sí? Me encantaría su orientación de cualquier manera, y gracias. – user1544138

Cuestiones relacionadas