2015-05-29 82 views
0

身份验证和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]; 
} 
+0

您尚未设置任何XMPP委托,请设置Delegate,然后它将调用委托方法,否则不调用委托方法。 –

回答

3

好的。所以最终我的问题解决了。我发布我的答案。首先我的错误是我忘了写

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

注:我试图解释为尽我所能。

0

其实你正在检查XMPP连接,是不是意味着Authenticate User。如果您的用户名和密码是正确的,那么您收到的响应方式为​​。您可以在用户验证后编写代码推送到HomeViewController。

以下两种方法可用于在用户变更后显示警报或推送到另一个视图。

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender 

{ 

} 

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error 
{ 
NSLog(@"Error"); 
} 

这是XMPP委托方法

希望这有助于你。

+0

我试过这个,但没有成功。我们必须在登录按钮上调用connect方法,然后在xmppstreamdidauthenticate中调用方法。并在didnotauthenticate上设置alertview。但不成功。 –

+0

您需要设置XMPP委托。那么XMPP将自动调用它的委托方法。只需要传递用户名和密码以进行变更。 –

+0

感谢您的重播。 –

1

如果用户名和密码正确,则xmppStreamDidAuthenticate方法调用,如果其中一个不正确,则执行didNotAuthenticate方法调用。

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender 
{ 
} 

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error 
{ 
NSLog(@"error = %@", error); 
} 

这里打印错误并按照您的要求在UIALertview中显示此错误。

+0

此方法不起作用,因为xmpp流花费时间来验证用户身份。在调用连接方法后,所以可能是我必须设置HUD与计时器“活动指标”,但我不知道如何设置这整个事情。需要建议或方法。谢谢。 –

+0

有一个方法名称goonline。所以在成功验证了这个方法后,就可以打电话了。因此,如果您必须执行任何操作,您可以开始旋转(指示符/ SVProgress)并使用goonline方法解除svprogress。并且您可以根据需要导航到主页视图。 – Parthpatel1105

+0

非常感谢。我能理解你的答案。所以现在在登录方法中如何设置等待上网方法执行的指标。 –