IOS- XMPP - 登录按钮
身份验证和alertview目前我正在为聊天应用程序在ios上的XMPP
协议。我想在登录按钮上放置警报视图和身份验证。如果认证成功,那么用户可以看到主屏幕屏幕,否则将出现警报视图请检查用户名和密码我显示聊天安全开源项目,但我无法理解。IOS- XMPP - 登录按钮
//appdelegate.m file .//
- (BOOL)connect
{
if (![xmppStream isDisconnected]) {
return YES;
// isauthenticate=YES;
}
NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];
//
// 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 = @"[email protected]/xmppframework";
// myPassword = @"";
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;
}
return YES;
}
- (void)disconnect
{
[self goOffline];
[xmppStream disconnect];
}
#pragma mark UIApplicationDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
#if TARGET_IPHONE_SIMULATOR
DDLogError(@"The iPhone simulator does not process background network traffic. "
@"Inbound traffic is queued until the keepAliveTimeout:handler: fires.");
#endif
if ([application respondsToSelector:@selector(setKeepAliveTimeout:handler:)])
{
[application setKeepAliveTimeout:600 handler:^{
DDLogVerbose(@"KeepAliveHandler");
// Do other keep alive stuff here.
}];
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)applicationWillTerminate:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self teardownStream];
}
#pragma mark XMPPStream Delegate
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSString *expectedCertName = [xmppStream.myJID domain];
if (expectedCertName)
{
settings[(NSString *) kCFStreamSSLPeerName] = expectedCertName;
}
if (customCertEvaluation)
{
settings[GCDAsyncSocketManuallyEvaluateTrust] = @(YES);
}
}
- (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
// The delegate method should likely have code similar to this,
// but will presumably perform some extra security code stuff.
// For example, allowing a specific self-signed certificate that is known to the app.
dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgQueue, ^{
SecTrustResultType result = kSecTrustResultDeny;
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) {
completionHandler(YES);
}
else {
completionHandler(NO);
}
});
}
- (void)xmppStreamDidSecure:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
isXmppConnected = YES;
NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(@"Error authenticating: %@", error);
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
isauthenticate=YES;
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
我曾尝试与方法设置BOOL(isauthenticate)
但没有成功。我可以重定向到主页,但如果我写错了详细信息,它仍然会重定向到主页。我想设置它,如果用户名或密码错误,并没有通过服务器进行身份验证。
//view controller.m file //
#import "ViewController.h"
#import "AppDelegate.h"
@interface ViewController()<MBProgressHUDDelegate>
{
MBProgressHUD *HUD;
IBOutlet UITextField *mViewEmail;
IBOutlet UITextField *mViewPassword;
}
@end
NSString *const kXMPPmyJID = @"kXMPPmyJID";
NSString *const kXMPPmyPassword = @"kXMPPmyPassword";
@implementation ViewController
- (IBAction)checkLogin:(id)sender {
NSLog(@"Email: %@ Password: %@",mViewEmail.text,mViewPassword.text);
[self setField:mViewEmail forKey:kXMPPmyJID];
[self setField:mViewPassword forKey:kXMPPmyPassword];
// if (appdelegate.connect==YES) {
if([ [self appDelegate] connect]) {
// if (appdelegate.isauthenticate==YES) {
HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES] ;
HUD.delegate = self;
HUD.color = [UIColor blackColor];
HUD.labelText = @"Please Wait";
HUD.dimBackground = YES;
// HUD.detailsLabelText = @"Close chat";
[self showHome];
//}
}
//}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry"
message:@"Please Check Username or Password"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
}
- (void)showHome{
[self performSegueWithIdentifier:@"signIn" sender:self];
}
好的。所以最终我的问题解决了。我发布我的答案。首先我的错误是我忘了写
appdelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
appdelegate.viewController = self; // very imp when you call method in app delegate.h
在我的视图控制器。所以当我调用viewcontroller的方法在appdelegate它的调用,但不执行由于上述方法丢失(第二行)。然后我在- (void)xmppStreamDidAuthenticate:(XMPPStream *)发送方方法中调用了视图控制器的segue方法。然后完美地工作。所以我的最终解决方案是
//app delegate.m file//
- (BOOL)connect
{
// Setup HUD(Activity Indicator) when Connect method call //
HUD = [[MBProgressHUD alloc] initWithWindow:[UIApplication sharedApplication].keyWindow]; [self.window.rootViewController.view addSubview:HUD];
[HUD setDetailsLabelText:@"Please wait..."];
[HUD setDimBackground:YES];
[HUD setOpacity:0.5f];
[HUD show:YES];
if (![xmppStream isDisconnected]) {
return YES;
}
NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];
if (myJID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
HUD.hidden=YES;
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;
}
return YES;
}
- (void)disconnect
{
[self goOffline];
[xmppStream disconnect];
}
#pragma mark UIApplicationDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
#if TARGET_IPHONE_SIMULATOR
DDLogError(@"The iPhone simulator does not process background network traffic. "
@"Inbound traffic is queued until the keepAliveTimeout:handler: fires.");
#endif
if ([application respondsToSelector:@selector(setKeepAliveTimeout:handler:)])
{
[application setKeepAliveTimeout:600 handler:^{
DDLogVerbose(@"KeepAliveHandler");
// Do other keep alive stuff here.
}];
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)applicationWillTerminate:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self teardownStream];
}
#pragma mark XMPPStream Delegate
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSString *expectedCertName = [xmppStream.myJID domain];
if (expectedCertName)
{
settings[(NSString *) kCFStreamSSLPeerName] = expectedCertName;
}
if (customCertEvaluation)
{
settings[GCDAsyncSocketManuallyEvaluateTrust] = @(YES);
}
}
- (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgQueue, ^{
SecTrustResultType result = kSecTrustResultDeny;
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) {
completionHandler(YES);
}
else {
completionHandler(NO);
}
});
}
- (void)xmppStreamDidSecure:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
isXmppConnected = YES;
NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(@"Error authenticating: %@", error);
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
HUD.hidden=YES; //Hud Will be hide when User Authenticated
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self.viewController showHome]; // view controllers method to go to next view controller //
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
// HUD will be hidden and alertview will be shown //
HUD.hidden=YES;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry"
message:@"Please Check Username or Password"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
isauthenticate=NO;
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
{
NSLog(@"error = %@", error);
}
}
而在viewcontroller.m中我们已经显示viewcontroller也是appdelegate控制器。所以我们必须在- (void)viewDidLoad方法中声明它。
// viewcontroller.m file//
- (void)viewDidLoad
{
[super viewDidLoad];
appdelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
appdelegate.viewController = self;
}
- (AppDelegate *)appDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (IBAction)checkLogin:(id)sender {
[self dismissKeyboard];
NSLog(@"Email: %@ Password: %@",mViewEmail.text,mViewPassword.text);
[self setField:mViewEmail forKey:kXMPPmyJID];
[self setField:mViewPassword forKey:kXMPPmyPassword];
[[self appDelegate ]connect];//call when loginbutton pressed
}
//call in appdelegate.h // segue(push) to next view
- (void)showHome
{
[self performSegueWithIdentifier:@"signIn" sender:self];
}
注:我试图解释为尽我所能。
其实你正在检查XMPP
连接,是不是意味着Authenticate User
。如果您的用户名和密码是正确的,那么您收到的响应方式为。您可以在用户验证后编写代码推送到HomeViewController。
以下两种方法可用于在用户变更后显示警报或推送到另一个视图。
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
NSLog(@"Error");
}
这是XMPP
委托方法
希望这有助于你。
我试过这个,但没有成功。我们必须在登录按钮上调用connect方法,然后在xmppstreamdidauthenticate中调用方法。并在didnotauthenticate上设置alertview。但不成功。 –
您需要设置XMPP委托。那么XMPP将自动调用它的委托方法。只需要传递用户名和密码以进行变更。 –
感谢您的重播。 –
如果用户名和密码正确,则xmppStreamDidAuthenticate方法调用,如果其中一个不正确,则执行didNotAuthenticate方法调用。
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
NSLog(@"error = %@", error);
}
这里打印错误并按照您的要求在UIALertview中显示此错误。
此方法不起作用,因为xmpp流花费时间来验证用户身份。在调用连接方法后,所以可能是我必须设置HUD与计时器“活动指标”,但我不知道如何设置这整个事情。需要建议或方法。谢谢。 –
有一个方法名称goonline。所以在成功验证了这个方法后,就可以打电话了。因此,如果您必须执行任何操作,您可以开始旋转(指示符/ SVProgress)并使用goonline方法解除svprogress。并且您可以根据需要导航到主页视图。 – Parthpatel1105
非常感谢。我能理解你的答案。所以现在在登录方法中如何设置等待上网方法执行的指标。 –
您尚未设置任何XMPP委托,请设置Delegate,然后它将调用委托方法,否则不调用委托方法。 –