I want to connect to openfire server anonymously using xmpp framework in iOS. I can connect to open fire by providing the JID and PW. However when I tried to connect anonymously it says "The server doesn't support anonymous authentication".
I'm using a button in xib file. When its clicked below code executes:
- (IBAction)login:(id)sender {
[[self appDelegate]connect];
NSError *authenticationError = nil;
[self.xmppStream authenticateAnonymously:&authenticationError];
}
and below is the code for connect method:
- (BOOL)connect {
[self setupStream];
xmppStream.hostName = #"abc.xyz.com";
//xmppStream.hostName = #"Virtuals-MacBook-Pro.local ";
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userID"];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:#"userPassword"];
if (![xmppStream isDisconnected]) {
return YES;
}
if (jabberID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
//[alertView release];
return NO;
}
return YES;
}
Steps for anonymous authentication:
1- First of all connect the xmpp-stream, then authenticate anonymously.
[[self xmppStream] authenticateAnonymously:&error];
then you will be authenticated anonymously. but a very important thing. before authenticating, get the username and password of a registered user and connect to the xmpp-stream
The accepted answer is almost right but is mixing things (connection and authentication)
What you are facing is probably a server side configuration problem, if your server does not allow you to log in anonymously you cannot, period.
Anyway you can still try to connect anonymously and handle the fact that you are not allow, for that you need to:
1) Set your JabberID to anonymous#domain (were domain is your server domain)
[self.xmppStream setMyJID:[XMPPJID jidWithString:#"anonymous#domain"]];
2) With that in place you can connect to the server (you do not need a valid user as the accepted answer pointed out)
[self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]
3) Once you get response from the sever your XMPP delegate method didConnect will be called, in there you check if the server configuration supports anonymous authentication and if so try to authenticate anonymously
- (void)xmppStreamDidConnect:(XMPPStream*)sender
{
self.isXmppConnected = YES;
if ([self.xmppStream supportsAnonymousAuthentication]) {
NSError* error = nil;
//the server does support anonymous auth
[self.xmppStream authenticateAnonymously:&error];
}
else {
NSLog(#"The server does not support anonymous authentication");
}
}
4) You handle however you want the situations were the server does not support anonymous auth (maybe trie with a well know user or display a warning to the user) or you get an error authenticating (network issues)
Related
I created messaging application like whatsApp and hike. Its working on 3G,4G and Wifi network. when user switch to 2G network my app connection is interrupted but whatsApp and hike working perfectly. I posting code where i manage app connection ::
#pragma mark - connect to the server
- (BOOL)connect {
if (!self.xmppStream) {
[self setupStream];
}
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:kUserName];
if (![self.xmppStream isDisconnected]) {
return YES;
}
if (jabberID == nil || kXMPPPassword == nil) {
return NO;
}
[self.xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
[self.xmppStream setHostName:kXMPPHost];
NSError *error = nil;
if (![self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
// UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
// [alertView show];
NSLog(#"errorerrorerrorerrorerrorerror :- %#", error);
return NO;
}
return YES;}
- (void)connectThenSignIn {
if ([_xmppStream isConnecting]) { // Connection error, connection is being established
return ;
}
if ([_xmppStream isDisconnected]) { // If disconnected, a server connection is established
[self connect];
_goToRegisterAfterConnected = NO;
} else if ([_xmppStream isConnected]) {
[self doSignIn];
} }
Please suggest me best way to manage openfire connection on every network (2G, 3G, 4G and wifi).
Those applications are probably using push notifications to receive updates while on unreliable IP networks (like 2G). This allows them to appear online without maintaining a constant connection to a server.
This is difficult to accomplish with XMPP -- the protocol was written with the assumption that users only need to be reachable while they are connected to the server. Some XEP extensions have added partial workarounds, but the protocol as a whole is poorly suited to mobile clients. (This has been a well-known limitation since at least 2014.) You may want to consider alternatives.
I have trouble using [self isAuthorized] to get confirmation of the access token I've got earlier.
Every time I'm login in with Google Drive SDK for iOS with:
// Creates the auth controller for authorizing access to Google Drive.
-(GTMOAuth2ViewControllerTouch *)createAuthController {
GTMOAuth2ViewControllerTouch *authController;
authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scopes
clientID:kClientID
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
return authController;
}
After the authentification completed, there is no error so the access token should be saved correctly
// Handle completion of the authorization process, and updates the Drive service
// with the new credentials.
-(void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error {
if (error != nil)
{
//[self showAlert:#"Authentication Error" message:error.localizedDescription];
self.driveService.authorizer = nil;
}
else
{
self.driveService.authorizer = authResult;
}
}
I used an NSLog to make sure I received the access token and It did.
-(BOOL)isAuthorized {
NSString *oauthToken = [((GTMOAuth2Authentication *)self.driveService.authorizer) accessToken];
NSLog(#"oauthToken: %#", oauthToken);
return [((GTMOAuth2Authentication *)self.driveService.authorizer) canAuthorize];
}
But When I look if I'm authorized or not, there is no token saved (oauthToken is NULL) and I need to login again.
N.B: It was working in the past before iOS 9. I don't know if it is related.
Thanks
Vincent
You might want to try something like this to verify login:
// Check for authorization.
GTMOAuth2Authentication *auth =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientId
clientSecret:kClientSecret];
if ([auth canAuthorize]) {
[self isAuthorizedWithAuthentication:auth];
}
On the other hand, if you really want the access token, check out this SO post, however, it is not best practice to store the access token, since access token has an expiration time. Good luck & Hope this helps.
I am working on an iOS chat app where user login to app. I've downloaded XMPPFramework from GitHub XMPPFramework. I am trying to connect XMPP framework with Openfire server by following this tutorial. Here is my code to connect XMPP to openfire.
- (BOOL)connect {
[self setupStream];
[xmppStream setHostName:#"192.168.1.5"];
[xmppStream setHostPort:5222];
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userID"];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:#"userPassword"];
if (![xmppStream isDisconnected])
return YES;
if (jabberID == nil || myPassword == nil)
return NO;
[xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream isConnected])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
return NO;
}
return YES;
}
The problem is when I run the app, it shows the alert can't connect to server. I have checked many questions on StackOverflow and tried googling but couldn't find any relevant solution. How to connect it to the Openfire serve? If I am doing anything wrong in my code please suggest me with a snippet of code or a tutorial to make this happen.
A host of possibilities.
Try adding break points at xmppStreamDidConnect and xmppStreamDidAuthenticate.
If xmppStreamDidConnect isn't reached, the connection is not established; you've to rectify your hostName.
If xmppStreamDidAuthenticate isn't reached, the user is not authenticated; you've to rectify your credentials i.e. username and/or password.
One common mistake is omitting of #domainname at the back of username i.e. username#domainname e.g. keithoys#openfireserver where domain name is openfireserver.
Hope this still relevant, if not, hopefully it will help others.
There are some issues with your code:
I don't see the call to connect, you should add something like this:
NSError *error = nil;
if (![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error connecting"
message:#"Msg"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
Most of the XMPP API is asynchronous.
You have to set the stream delegate in order to receive events.
Check out XMPPStreamDelegate and XMPPStream#addDelegate
If you don't want to go through the code yourself XMPPStream.h
, you can implement all methods of XMPPStreamDelegate and log the events. This will help you understand how the framework works.
Hope this helps, Yaron
I am using quickblox in my app. I did my user signup, user login and chat. Everything works fine when i log in for the first time. if I press home and enter the app again, I come to my viewController page. The user is logged out automatically. And when I try to log in it says, token is required.
I have put the session authentication in appdelegate
[QBAuth createSessionWithDelegate:self]
-(void)viewDidAppear:(BOOL)animated
{
if([LocalStorageService shared].currentUser == nil)// check if user is logged in
{
NSCharacterSet *nonalphanumericSet = [[ NSCharacterSet alphanumericCharacterSet] invertedSet];
[QBUsers logInWithUserLogin:[[[PFUser currentUser].username componentsSeparatedByCharactersInSet:nonalphanumericSet ] componentsJoinedByString:#"1"] password:#"password" delegate:self];
}
}
- (void)completedWithResult:(Result *)result
{
if(result.success && [result isKindOfClass:QBUUserLogInResult.class])
{
// Success, do something
QBUUserLogInResult *userResult = (QBUUserLogInResult *)result;
NSLog(#"Logged In user=%#", userResult.user);
userResult.user.password =#"password";
// Save current user
//
[[LocalStorageService shared] setCurrentUser: userResult.user];
// Login to QuickBlox Chat
//
[[ChatService instance] loginWithUser:[LocalStorageService shared].currentUser completionBlock:^{
NSLog(#"chat logged successfully");
}];
// Errors
}
else
{
NSString *errorMessage = [[result.errors description] stringByReplacingOccurrencesOfString:#"(" withString:#""];
errorMessage = [errorMessage stringByReplacingOccurrencesOfString:#")" withString:#""];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Errors"
message:errorMessage
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
}
token is required means that you are trying to perform request, but you didn't create a session still
You can reproduce this issue just perform 2 requests one by one:
[QBAuth createSessionWithDelegate:self];
[QBUsers logInWithUserLogin:... delegate:self];
After this sequence you will got 'token is required'
To get rid of this you should wait when create session requests will be finished and perform next request:
[QBAuth createSessionWithDelegate:self];
...
- (void)completedWithResult:(Result *)result{
if(result.success && [result isKindOfClass:QBAAuthSessionCreationResult.class]){
// you got token here - perform any other requests after this
[QBUsers logInWithUserLogin:... delegate:self];
}
}
It's not a solution for your issue, but it's an explanation hy it happenes and how to resolve it
It seems socket get closed. Try to log out from QBChat instance when app goes to background, and log in to QBChat when app will enter foreground. And if you don't send presence messages to QBChat, socket will be closed in 90 seconds
I have a Problem with the XMPP-Framework for iOS. Every Time I fire registerWithPassword Method i get an Error:
"Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the
stream is connected." UserInfo=0xad7c300
{NSLocalizedDescription=Please wait until the stream is connected.} "
I do the following steps in my Code:
-(void)createUserWithUsername:(NSString*)name andPW:(NSString*)pw{
[self setupStream];
NSLog(#"name: %# ",name);
NSString *nameFor = name;
[self disconnect];
NSString *jidBenutzer = [NSString stringWithFormat:#"%##my-Server.com",nameFor];
NSError *error = nil;
NSError * err = nil;
NSLog(#"jabberid : %#",jidBenutzer);
XMPPJID *jid = [XMPPJID jidWithString:jidBenutzer];
self.xmppStream.myJID = jid;
[[self xmppStream] registerWithPassword:pw error:&err];
NSLog(#"Connection: %#",error);
NSLog(#"Register: %#",err);
}
I hope you can help me !
From your example code, I do not see any call to:
[xmppStream connect:&error]
From the error message, you are actually not connected.
Make sure you correctly call the connect method and that you are processing the error accordingly.
/**
* This method attempts to register a new user on the server using the given username and password.
* The result of this action will be returned via the delegate methods.
*
* If the XMPPStream is not connected, or the server doesn't support in-band registration, this method does nothing.
**/
This is the below.
- (BOOL)registerWithPassword:(NSString *)password error:(NSError **)errPtr
The method's instructions . You will find that before you use this method , you have to connecting the server.
I can' not find below.
[xmppStream connect:&error]
I use the this.
NSError *error;
NSString *tjid = [[NSString alloc] initWithFormat:#"anonymous#%#", serverName];
isRegister = YES;
[xmppStream setMyJID:[XMPPJID jidWithString:tjid]];
[xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]
Please make sure your openfire server is turned on from your system preferences.
It is a late answer but still for any new developer like me: You have to login anonymously before registration: For example you are login with yourname#yourserver and your password try to login with unknown#yourserver and for password put nothing. So it will connect the stream but will not authenticate this is required for registration.
The stream should be connected but not be authenticated.