I am creating a chat app using ejabberd in iOS & android. The application also have offline push notification. To do this I need to connect to same resource every time I login. In android , I can do this as follows
XMPPTCPConnectionConfiguration.Builder confBuilder = XMPPTCPConnectionConfiguration.builder()
.setServiceName(serviceName)
.setUsernameAndPassword(jidParts[0], password)
.setConnectTimeout(3000)
// .setDebuggerEnabled(true)
.setResource("xxxxx")
.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
But in IOS , I can't setResource because I don't know how to set this on iOS.
the login code is as follows
- (BOOL)connect:(NSString *)myJID withPassword:(NSString *)myPassword auth:(AuthMethod)auth hostname:(NSString *)hostname port:(int)port
{
if (![xmppStream isDisconnected]) {
[self disconnect];
}
if (myJID == nil || myPassword == nil) {
return NO;
}
NSLog(#"Connect using JID %#", myJID);
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
username = myJID;
password = myPassword;
authMethod = auth;
xmppStream.hostName = (hostname ? hostname : [username componentsSeparatedByString:#"#"][1]);
if(port){
xmppStream.hostPort = port;
}
NSError *error = nil;
if (port == 5223) {
self.xmppReconnect.usesOldSchoolSecureConnect = YES;
if (![xmppStream oldSchoolSecureConnectWithTimeout:30 error:&error])
{
DDLogError(#"Error connecting: %#", error);
if (self.delegate){
[self.delegate onLoginError:error];
}
return NO;
}
} else {
if (![xmppStream connectWithTimeout:30 error:&error])
{
DDLogError(#"Error connecting: %#", error);
if (self.delegate){
[self.delegate onLoginError:error];
}
return NO;
}
}
return YES;
}
How can I ad resource in above code?
You can set a resource by changing the init method of XMPPJID to
[xmppStream setMyJID:[XMPPJID jidWithString:myJID resource:resourceId]];
This is an overloaded method in XMPPJID
Related
Hi I am working with the xmpp framework working fine till yesterday But I don't know what happen suddenly xmpp didDisConnect method calling
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
where I am missing.I know if username password wrong then it will be disconnected.But I checked my username it is fine and it is showing below error
Error Domain=GCDAsyncSocketErrorDomain Code=4 "Read operation timed out" UserInfo={NSLocalizedDescription=Read operation timed out
below is the connect method
- (BOOL)connect
{
if (![xmppStream isDisconnected]) {
return YES;
}
myJID =[NSString stringWithFormat:#"%##servername",[[NSUserDefaults standardUserDefaults] stringForKey:#"FinalUserNameJID"]];
NSString *password1=[[NSUserDefaults standardUserDefaults] stringForKey:#"smsVerificationNumber"];
// If you don't want to use the Settings view to set the JID,
// uncomment the section below to hard code a JID and password.
//
// myJID = #"user#gmail.com/xmppframework";
// myPassword = #"";
if (myJID == nil || password1 == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = password1;
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:NSLocalizedString( #"O_K", #"OK")
otherButtonTitles:nil];
[alertView show];
DDLogError(#"Error connecting: %#", error);
return NO;
}
return YES;
}
Please help me if any body face this issue.Thankyou
I am trying to access the gmail messages in offline access mode. gmail access token I get from the server end.
I followed this link to here
I created my own authenticator class and subclass from GTMOAuth2Authentication and implemented the protocol as mentioned in the above link.
The canAutherize always fail and even though I make gmail query, It crashes in authorize function. Any help would be appreciated.
- (void)viewDidLoad {
[super viewDidLoad];
if ([self.subjectInfo length] > 0) {
[self.subjectLabel setText:self.subjectInfo];
}else {
[self.subjectLabel setText:#""];
}
self.service = [[GTLServiceGmail alloc] init];
[self fetchAccessToken];
// Initialize the Gmail API service & load existing credentials from the keychain if available.
}
// When the view appears, ensure that the Gmail API service is authorized, and perform API calls.
- (void)viewDidAppear:(BOOL)animated {
if (!self.service.authorizer.canAuthorize) {
// Not yet authorized, request authorization by pushing the login UI onto the UI stack.
// [self presentViewController:[self createAuthController] animated:YES completion:nil];
[self fetchAccessToken];
} else {
[self fetchMail:[self gmailMsgId]];
}
}
-(void) fetchAccessToken
{
[[APIManager sharedManager] fetchGmailToken:^(NSDictionary *resultDict) {
if (resultDict != nil) {
self.accessToken = [resultDict objectForKey:#"access_token"];
_authInst = [[GmailAuthenticator alloc] initWithAccessToken:self.accessToken];
self.service.authorizer = _authInst;
}
} failure:^(NSError *error) {
NSLog(#"fail to fetch access token");
}];
}
- (void)fetchMail:(NSString*)messageId {
GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesGet];
query.messageId = messageId;
[self.service executeQuery:query
delegate:self
didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
- (void)displayResultWithTicket:(GTLServiceTicket *)ticket
finishedWithObject:(GTLGmailMessage *)messageResponse
error:(NSError *)error {
if (error == nil) {
NSLog(#"description is %#", [messageResponse description]);
} else {
NSLog(#"error : %#", [error description]);
}
}
I am trying to find the email of the logged in account from the google login API in iOS using Swift.
The code i used is the same as given in the google Developers instruction page.
This is my code
description = [NSString stringWithFormat: #"%# %# %# %# %# %#",
person.displayName,person.gender,person.ageRange.min,person.ageRange.max,person.emails,person.birthday];
The output when i print this "description" id is this:
Karanvir Singh male 18 20 (
"GTLPlusPersonEmailsItem 0x7fbe4a67aee0: {value:\"karanvir95#gmail.com\" type:\"account\"}"
) (null)
I want to know how i can remove the excess of output when i just want to know the email ID
i want the output as such:
Karanvir Singh male 18 20 karanvir95#gmail.com 17/02/1995
Code as requested:
import "ViewController.h"
import "GoogleOpenSource/GoogleOpenSource.h"
import "GooglePlus/GooglePlus.h"
import "AppDelegate.h"
#interface ViewController ()
#end
#implementation ViewController #synthesize signInButton; #synthesize
signOutHandle; #synthesize signInHandle; #synthesize infoLabel;
#synthesize description;
- (void)viewDidLoad {
[super viewDidLoad];
signOutHandle.hidden=true; }
(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
-(void)refreshInterfaceBasedOnSignIn {
if ([[GPPSignIn sharedInstance] authentication]) {
signOutHandle.hidden=false;
signInHandle.hidden=true;
infoLabel.text=description;
} else {
} }
(void)finishedWithAuth: (GTMOAuth2Authentication *)auth error: (NSError *) error {
NSLog(#"Received error %# and auth object %#",error, auth);
if (error) {
// Do some error handling here.
} else {
GTLServicePlus* plusService = [[GTLServicePlus alloc] init];
plusService.retryEnabled = YES;
[plusService setAuthorizer:[GPPSignIn sharedInstance].authentication];
GTLQueryPlus *query = [GTLQueryPlus queryForPeopleGetWithUserId:#"me"];
query.collection=kGTLPlusCollectionVisible;
[plusService executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLPlusPerson *person,
NSError *error){
if (error) {
GTMLoggerError(#"Error: %#", error);
} else {
// [person retain];
NSString *age = [NSString string];
description = [NSString stringWithFormat: #"%# %# %# %# %# %# %#", person.displayName,person.gender,person.ageRange.min,person.ageRange.max,person.emails,person.birthday,email];
NSLog(description);
}
GTLQueryPlus *query2 =
[GTLQueryPlus queryForPeopleListWithUserId:#"me"
collection:kGTLPlusCollectionVisible];
[plusService executeQuery:query2 completionHandler:^(GTLServiceTicket *ticket, GTLPlusPeopleFeed *peopleFeed, NSError *error) {
if (error) {
GTMLoggerError(#"Error: %#", error);
} else {
// Get an array of people from GTLPlusPeopleFeed
NSArray* peopleList = peopleFeed.items;
}
}];
[self refreshInterfaceBasedOnSignIn];
}];
} }
- (IBAction)signOutButton:(id)sender {
[[GPPSignIn sharedInstance] signOut];
[[GPPSignIn sharedInstance] disconnect];
signOutHandle.hidden=true;
signInHandle.hidden=false;
infoLabel.text=#""; }
(void)signOut {
[[GPPSignIn sharedInstance] signOut]; }
(void)disconnect {
[[GPPSignIn sharedInstance] disconnect]; }
(IBAction)signedIn:(id)sender {
GPPSignIn *signIn = [GPPSignIn sharedInstance];
signIn.shouldFetchGooglePlusUser = YES;
signIn.shouldFetchGoogleUserEmail = YES;
signIn.clientID = kClientId;
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
signIn.shouldFetchGoogleUserEmail = YES;
signIn.delegate = self;
signIn.scopes = #[ kGTLAuthScopePlusUserinfoProfile, kGTLAuthScopePlusLogin,kGTLAuthScopePlusMe,kGTLAuthScopePlusUserinfoEmail
];
signIn.delegate = self;
[signIn authenticate];
email=(#"%#",signIn.userEmail);
NSLog(#" email:%#",email); }
(void)didDisconnectWithError:(NSError *)error {
if (error) {
NSLog(#"Received error %#", error);
} else {
NSLog(#"The user is signed out and disconnected.");
// The user is signed out and disconnected.
// Clean up user data as specified by the Google+ terms.
} }
#end
description = [NSString stringWithFormat: #"%# %# %# %# %# %# %#", person.displayName, person.gender,person.ageRange.min,person.ageRange.max,person.emails.value,person.birthday];
And I want to note that your person has nil bithday
When a session is created, a shell is started and commands are written: no responses are recieved and the callback methods for the buffer is never called, what did i miss?:
(Executing a single command using channel:execute works)
-(void) createSessionWithAdress:(NSString*)address username:(NSString*)user password:(NSString*)pass{
session = [NMSSHSession connectToHost:address withUsername:user];
if (session.isConnected) {
[session authenticateByPassword:pass];
if (session.isAuthorized) {
NSError *err = nil;
session.channel.delegate = self;
//self.receiveView.text = [session.channel execute:#"ls" error:&err]; // works
[session.channel startShell:&err];
NSLog(#"Authentication succeeded");
}
}
}
- (void)channel:(NMSSHChannel *)channel didReadData:(NSString *)message{
NSLog(#"Read data!");
receiveView.text = [NSString stringWithFormat:#"%# \n%#",receiveView.text,message];
}
- (void)channel:(NMSSHChannel *)channel didReadError:(NSString *)error{
receiveView.text = [NSString stringWithFormat:#"%# \n%#",receiveView.text,error];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"RETURN PRESSED");
NSError* err = nil;
bool commandSucess = [session.channel write:sendView.text error:&err];
[session.channel write:#"/n" error:&err];
if (commandSucess) {
NSLog(#"Command written successfully");
}else{
NSLog(#"Command not written successfully");
}
return YES;
}
PTY mode needs to be enabled, and there were som issues in the library (should be fixed now)
I am trying to make a jabber chat application using the xmppframework.
I have implemented the xmppStream methods in the applicationAppDelegate, but none of these method has been invoked.
Here is the code of the applicationAppDelegate:
- (void)setupStream {
xmppStream = [[XMPPStream alloc] init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
//[self connect];
}
- (void)goOnline {
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
}
- (void)goOffline {
XMPPPresence *presence = [XMPPPresence presenceWithType:#"unavailable"];
[[self xmppStream] sendElement:presence];
}
- (BOOL)connect {
[self setupStream];
NSString *emailUserDefault = [[NSUserDefaults standardUserDefaults] stringForKey:#"email"];
NSString *jabberID = [emailUserDefault stringByAppendingString:#"#server.local"];
NSLog(#"%#",jabberID);
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:#"password"];
NSLog(#"%#",myPassword);
if (![xmppStream isDisconnected]) {
NSLog(#"You are connected");
return YES;
}
if (jabberID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
//xmppStream.myJID = [XMPPJID jidWithString:jabberID];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:20 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];
return NO;
}
return YES;
}
- (void)disconnect {
[self goOffline];
[xmppStream disconnect];
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
isOpen = YES;
NSError *error = nil;
[[self xmppStream] authenticateWithPassword:password error:&error];
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
NSString *presenceType = [presence type]; // online/offline
NSString *myUsername = [[sender myJID] user];
NSString *presenceFromUser = [[presence from] user];
if (![presenceFromUser isEqualToString:myUsername]) {
if ([presenceType isEqualToString:#"available"]) {
[__chatDelegate newBuddyOnline:[NSString stringWithFormat:#"%##%#", presenceFromUser, #"server.local"]];
} else if ([presenceType isEqualToString:#"unavailable"]) {
[__chatDelegate buddyWentOffline:[NSString stringWithFormat:#"%##%#", presenceFromUser, #"server.local"]];
}
}
}
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
NSString *msg = [[message elementForName:#"body"] stringValue];
NSString *from = [[message attributeForName:#"from"] stringValue];
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject:msg forKey:#"msg"];
[m setObject:from forKey:#"sender"];
[__messageDelegate newMessageReceived:m];
}
Here my code for the chatViewController classe:
- (myApplicationAppDelegate *)appDelegate {
return (myApplicationAppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (XMPPStream *)xmppStream {
return [[self appDelegate] xmppStream];
}
- (void)viewDidLoad
{
[super viewDidLoad];
onlineBuddies = [[NSMutableArray alloc ] init];
myApplicationAppDelegate *del = [self appDelegate];
[self xmppStream];
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:#"email"];
del._chatDelegate = self;
if (login) {
if ([[self appDelegate] connect]) {
NSLog(#"show buddy list");
}
} else {
NSLog(#"Login Error");
}
}
I cannot figure out why the xmpp delegate methods are not being invoked. If someone can give me a hand, please don't hesitate.
Thanks in advance.
I think you misunderstood the purpose of AppDelegate. First of all for every iOS app that you are creating in Xcode there is a class created that contains the name AppDelegate but this class should only be used to get information of your application state, such as if the app goes to background, if it's launched with success or if it's coming up from background. Also the app delegate is used to specify the root (or entry point) view controller of your application.
So I think you should first check the basic rules (or a basic tutorial) on how to create a very simple application (a "Hello World Application"), after that you can go forward and create a basic structure of your application and decide what view controller or what model classes will handle your connection handling and response/request parsing.
I strongly suggest that you have a look over view controllers and I'm pretty sure that after you do the above suggested "tasks" you will answer yourself the posted question.
P.S Last point, have a look on "iOS naming & other conventions"enter link description herelife cycle methods