I am developing a chat system in both iOS. The chat server which I am using is ejabbered server. I am using Robbiehanson xmppframework for iOS chat client.
The issue which I am facing is that I am not able to establish a proper xmppstream between the chat client and the server. The xmppstream state is in STATE_XMPP_REGISTERING. This holds a value of 8. Due to this,when I try to authenticate the just created registered user, I am encountering an exception
"Error authenticating: Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo=0x166c1e30 {NSLocalizedDescription=Please wait until the stream is connected.}
But surprisingly, I am able to register a user using a password. When I try to authenticate the user, I am encountering this exception due to which the registered user is not able to appear ONLINE.
I am using ConnectWithTimeOut to connect the xmppstream to the server
NSString *myPassword = #"password";
if (myJID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error connecting"
message:#"See console for error details."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
DDLogError(#"Error connecting: %#", error);
return NO;
}
Using this above code, I am able to establish a connection to the server.
Once the connectton is established, xmppStreamDidConnect is invoked.
when I checked the status of the XMPPStream, I am seeing the stream is connected.
Below is the code.
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
if ([xmppStream isDisconnected]){
NSLog(#"Is DisConnected");
[self connect];
}
if ([xmppStream isConnecting]){
NSLog(#"Is Connecting");
}
if ([xmppStream isConnecting]){
NSLog(#"Is Connecting");
}
if ([xmppStream isConnected]){
NSLog(#"Is Connected");
}
NSError *error = nil;
if (![[self xmppStream] registerWithPassword:#"password" error:&error]) {
NSLog(#"Registration error: %#", error);
}
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(#"Error authenticating: %#", error);
}else{
[self goOnline];
XMPPPresence *presence = [XMPPPresence presenceWithType:#"available"];
[sender sendElement:presence];
}
As per the above code, a user is registered and here comes the issue. When I try to authenticate the user, using authenticateWithPassword:password
XMPPLogTrace();
// The given password parameter could be mutable
NSString *password = [inPassword copy];
__block BOOL result = YES;
__block NSError *err = nil;
dispatch_block_t block = ^{ #autoreleasepool {
if (state != STATE_XMPP_CONNECTED)
{
NSString *errMsg = #"Please wait until the stream is connected.";
NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
err = [NSError errorWithDomain:XMPPStreamErrorDomain code:XMPPStreamInvalidState userInfo:info];
result = NO;
return_from_block;
}
if (myJID_setByClient == nil)
{
NSString *errMsg = #"You must set myJID before calling authenticate:error:.";
NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
err = [NSError errorWithDomain:XMPPStreamErrorDomain code:XMPPStreamInvalidProperty userInfo:info];
result = NO;
return_from_block;
}
the code below gets executed. But when I check the status of the xmppstream when I enter this delegate, I am seeing it in status 8 (which is STATE_XMPP_REGISTERING) though the user is successfully registered. This status makes to return a NO and hence the registered user is not appearing online.
Could anyone please help me in resolving this issue. I tried a lot of ways. But not able to progress.
Why I am not able to move to the next status and ultimately to status 12 before the authenticatewithpassword is invoked. Am I missing any intermediate steps after establishing a connection and successful registration. In nutshell, why the stream state stops at 8. and not going forward to
STATE_XMPP_AUTH,STATE_XMPP_BINDING,STATE_XMPP_START_SESSION, STATE_XMPP_CONNECTED, before getting into authenticatewithpassword
Logs for more info.
2014-05-30 07:40:20:995 konnectlinks[3249:8403] SEND: <?xml version='1.0'?>
2014-05-30 07:40:20:996 konnectlinks[3249:8403] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='localhost'>
2014-05-30 07:40:21.246 konnectlinks[3249:60b] dhaval is here
2014-05-30 07:40:21:608 konnectlinks[3249:4717] RECV: <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" id="114321716" from="localhost" version="1.0" stream1:lang="en"/>
2014-05-30 07:40:21:609 konnectlinks[3249:8403] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.process-one.net/en/ejabberd/" ver="9DVbXp9C/vTyB5mLfy7wktk5Pfs="/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
2014-05-30 07:40:21.610 konnectlinks[3249:8403] -[XMPPReconnect xmppStreamDidConnect:]
2014-05-30 07:41:01.558 konnectlinks[3249:60b] Is Connected
2014-05-30 07:41:01.561 konnectlinks[3249:8403] -[XMPPReconnect setMultipleReachabilityChanges:]
2014-05-30 07:41:14.073 konnectlinks[3249:8403] -[XMPPReconnect setManuallyStarted:]
2014-05-30 07:41:14.076 konnectlinks[3249:8403] -[XMPPReconnect teardownReconnectTimer]
2014-05-30 07:41:14:076 konnectlinks[3249:60b] SEND: <iq type="set"><query xmlns="jabber:iq:register"><username>timop</username><password>password</password></query></iq>
2014-05-30 07:41:14.077 konnectlinks[3249:8403] -[XMPPReconnect teardownNetworkMonitoring]
2014-05-30 07:42:07:428 konnectlinks[3249:860b] RECV: <iq xmlns="jabber:client" from="localhost" type="result"><query xmlns="jabber:iq:register"><username>timop</username><password>password</password></query></iq>
2014-05-30 07:42:10:312 konnectlinks[3249:60b] Error authenticating: Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo=0x166c1e30 {NSLocalizedDescription=Please wait until the stream is connected.}
I am sure someone would have encountered the issue.
Please help me in resolving this issue. Advance thanks for your time and help
I reviewed the code seems its right , Make sure the username and password you send it must be correct.
If nothing goes right then contact with your server/web team regarding this or try to connect with creating new user
Related
When I'm trying to perform request for inserting of a broadcast I receive error:
Error Domain=com.google.GTLRErrorObjectDomain Code=403 "The user is blocked from live streaming."
UserInfo={GTLRStructuredError=GTLRErrorObject 0x28027ad30: {code:403
errors:[1] message:"The user is blocked from live streaming."},
NSLocalizedDescription=The user is blocked from live streaming.}
I have started receiving this error today. Before, everything has been working fine. I have tested on several accounts and had not any luck.
Code:
GTLRYouTube_LiveBroadcastSnippet *broadcastSnippet= [[GTLRYouTube_LiveBroadcastSnippet alloc] init];
[broadcastSnippet setTitle:title];
[broadcastSnippet setScheduledStartTime:[GTLRDateTime dateTimeWithDate:self.beginOfStream]]; // current date + 1 minute.
[broadcastSnippet setScheduledEndTime:[GTLRDateTime dateTimeWithDate:[NSDate dateWithTimeIntervalSinceNow:80000]]];
GTLRYouTube_LiveBroadcastStatus *status = [[GTLRYouTube_LiveBroadcastStatus alloc] init];
[status setPrivacyStatus:[StreamSettings youtubeStringForPrivacyStatus:[privacyStatus intValue]]];
GTLRYouTube_LiveBroadcastContentDetails *details = [self streamDetailsWith:latency];
GTLRYouTube_LiveBroadcast *broadcast = [[GTLRYouTube_LiveBroadcast alloc] init];
[broadcast setKind:#"youtube#liveBroadcast"];
[broadcast setSnippet:broadcastSnippet];
[broadcast setStatus:status];
GTLRYouTubeQuery_LiveBroadcastsInsert *query = [GTLRYouTubeQuery_LiveBroadcastsInsert queryWithObject:broadcast
part:#"id, snippet, contentDetails,status"];
GTLRYouTubeService *service = self.youTubeService;
__strong id <YouTubeHelperDelegate> strongDelegate = self.delegate;
[service executeQuery:query completionHandler:^(GTLRServiceTicket *ticket,
GTLRYouTube_LiveBroadcast *returnedBrocast,
NSError *error) {
if (error) {
NSLog(#"%#", error); //Here is place I got an error
}
}];
If the logged in user does not have more than 1000 subscribers he can't go live using a mobile app, as mentioned in link:
https://support.google.com/youtube/answer/2853834?hl=en
I'm trying to use Google's OAuth2 and YouTube APIs. The OAuth returns GTMOAuth2Authentication object that you then use to make requests to services like YouTube. My login works fine, and when I manually pass the authentication object, I can make requests.
However, I should also be able to access the authentication object via keychain, and I receive a valid object, but if I try to use it to make requests, I cannot. I keep getting the following error: "The operation couldn’t be completed. (com.google.GTMHTTPFetcher error -1.)" I'd appreciate it if someone could point out my mistake. I'm testing on a real iPhone 5s.
Authentication Code:
GTMOAuth2ViewControllerTouch * viewController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:scope
clientID:kGoogleClientID
clientSecret:kGoogleClientSecret
keychainItemName:kGoogleKeychainItemName
delegate:self
finishedSelector:#selector(viewController:
finishedWithAuth:
error:)];
[self.navigationController pushViewController:viewController animated:YES];
Authentication Completion Handler:
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
NSLog(#"%s", __PRETTY_FUNCTION__);
if (error != nil) {
NSLog(#"%s %#", __PRETTY_FUNCTION__, error.localizedDescription);
return;
}
MediaGETWrapper *getWrapper = [MediaGETWrapper sharedWrapper];
getWrapper.googleAuth = auth; // passing auth directly without keychain
[getWrapper youTubeSubscriptionsWithSuccess:nil failure:nil];
YouTube Client Initialization:
self.youTube = [GTLServiceYouTube new];
GTMOAuth2Authentication *auth = [GTMOAuth2Authentication new];
[GTMOAuth2ViewControllerTouch
authorizeFromKeychainForName:kGoogleKeychainItemName
authentication:auth
error:nil];
self.youTube.authorizer = auth;
Request:
- (void)youTubeSubscriptionsWithSuccess:(void(^)(NSArray *subscriptions))success
failure:(void(^)(NSError *error))error {
NSLog(#"%s", __PRETTY_FUNCTION__);
// self.youTube.authorizer = self.googleAuth; // If uncommented, works!
GTLQueryYouTube *query = [GTLQueryYouTube queryForSubscriptionsListWithPart:#"snippet"];
query.mine = YES;
[self.youTube
executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLYouTubeChannelListResponse *channelList,
NSError *error) {
if (error != nil) {
NSLog(#"%s %#", __PRETTY_FUNCTION__, error.localizedDescription); // fails here
return;
}
for (GTLYouTubeSubscription *channel in channelList) {
NSLog(#"%#", channel.snippet.title);
}
}];
}
I couldn't find a direct fix, but you can do this:
Get the access token from a GTMOAuth2Authentication object via:
auth.accessToken
Then set the access token wherever you want to make requests.
To refresh the token, use this method:
[auth
authorizeRequest:nil // just to refresh
completionHandler:^(NSError *error) {
// your code here
}];
iPhone Chat app using xmpp/jabber.
This method i am not able register on server. it gives me "403" error.
Can anyone help me, how can i create a new account on server using xmpp/jabber in ios?
here my code :
NSString *username = loginField.text;
NSString *password = passwordField.text;
AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
del.xmppStream.myJID = [XMPPJID jidWithString:username];
NSLog(#"Does supports registration %hhd ",del.xmppStream.supportsInBandRegistration );
NSLog(#"Attempting registration for username %#",del.xmppStream.myJID.bare);
if (del.xmppStream.supportsInBandRegistration)
{
NSError *error = nil;
if (![del.xmppStream registerWithPassword:password error:&error])
{
NSLog(#"Oops, I forgot something: %#", error);
}
else
{
NSLog(#"No Error");
}
}
and i got error
ERROR :-
<iq xmlns="jabber:client" from="username#Testlocalhost" to="username#Testlocalhost/40751035661420464079722458" type="error">
<query xmlns="jabber:iq:register">
<username>newusername</username>
<password>userpassword</password>
</query>
<error code="403" type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
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)
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.