2015-05-29 81 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

非常感謝。我能理解你的答案。所以現在在登錄方法中如何設置等待上網方法執行的指標。 –