2015-04-09 17 views
11

Używam NSURLCredentials w tej metodzie:objective-c jasne NSURLCredential - NSURLCredentialPersistenceForSession

-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler 
{ 


    NSURL *url = [NSURL URLWithString:kIP]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] 
             initWithRequest:request]; 


    NSURLCredential *credential = [NSURLCredential 
            credentialWithUser:user 
            password:password 
            persistence:NSURLCredentialPersistenceForSession]; 

    [operation setCredential:credential]; 

    [[NSOperationQueue mainQueue] addOperation:operation]; 

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

     if (completionHandler) { 
      completionHandler(responseObject, nil); 
     } 

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

     if (completionHandler) { 
      completionHandler(nil, error); 
     } 

    }]; 

    [operation start]; 
} 

A teraz szukam wyczyścić NSURLCredentials w metodzie wylogowania tak:

-(void)logout 
{ 
    //Clear NSURLCredentialPersistenceForSession 
} 

Jak Robię to? Czy powinienem zresetować NSURLCredentials lub czy mogę je usunąć?

UPDATE

Znalazłem rozwiązanie:

NSURLCredentialStorage *credentialStorage = [NSURLCredentialStorage sharedCredentialStorage]; 
    NSDictionary *credentialsDicationary = [credentialStorage allCredentials]; 


    for (NSURLProtectionSpace *space in [credentialsDicationary allKeys]) { 

     NSDictionary *spaceDictionary = [credentialsDicationary objectForKey:space]; 

     for (id userName in [spaceDictionary allKeys]) { 

      NSURLCredential *credential = [spaceDictionary objectForKey:userName]; 

      [credentialStorage removeCredential:credential forProtectionSpace:space]; 

     } 

    } 

stąd: Using NSURLCredentialPersistenceForSession while request and then clearing the credentials on logout still persist the cerdentials

Jest to najlepszy sposób? Mam zapisane tylko 1 referencje. Również ten kod daje mi ostrzeżenie na tej linii:

NSURLCredential *credential = [spaceDictionary objectForKey:userName]; 

i tutaj jest ostrzeżenie ... jak usunąć to ostrzeżenie?

/Users/jsuske/Documents/SSiPad(Device Only)ios7/SchedulingiPadApplication/ViewControllers/LHLoginController.m:496:73: Local declaration of 'userName' hides instance variable 

UPDATE

Ok, więc mam 3 sposoby: UserLogin, login i LogoutButtonPressed

UserLogin: Używam AFNetworking połączyć się z systemu Windows uwierzytelniony URL przy użyciu NSURLCredential jak pokazano powyżej:

-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler 
{ 

    NSURL *url = [NSURL URLWithString:kIP]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] 
             initWithRequest:request]; 

    NSURLCredential *credential = [NSURLCredential 
            credentialWithUser:user 
            password:password 
            persistence:NSURLCredentialPersistenceForSession]; 

    [operation setCredential:credential]; 


    [[NSOperationQueue mainQueue] addOperation:operation]; 

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

     if (completionHandler) { 
      completionHandler(responseObject, nil); 
     } 

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

     if (completionHandler) { 
      completionHandler(nil, error); 
     } 

    }]; 

    [operation start]; 

} 

Ta metoda jest wywoływana za pomocą metody logowania:

- (void)Login 
{ 
    NSString *rawString = [self.idTextField text]; 
    NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 
    [self.idTextField setText:[rawString stringByTrimmingCharactersInSet:whitespace]]; 


    [userName UserLogin:self.idTextField.text andPassWordExists:self.passwordTextField.text completionHandler:^(id responseObject, NSError *error) { 
     if (responseObject) { 

       [self.idTextField removeFromSuperview]; 
       [self.passwordTextField removeFromSuperview]; 
       [self.loginButton removeFromSuperview]; 
       self.idTextField = nil; 
       self.passwordTextField = nil; 
       //self.loginButton = nil; 


       [self CreateMenu]; 



       [indicatorView stopAnimating]; 
       [indicatorView removeFromSuperview]; 
       indicatorView = nil; 
       [loadingView removeFromSuperview]; 
       loadingView = nil; 
     }else{ 


      [self CustomAlert:@"Sorry Login Failed, User and/or Passsword Incorrect"]; 

      [indicatorView stopAnimating]; 
      [indicatorView removeFromSuperview]; 
      indicatorView = nil; 
      [loadingView removeFromSuperview]; 
      loadingView = nil; 

     } 
    }]; 

} 

I staram się oczyścić sesję z LogoutButtonPressed:

- (void)LogoutButtonPressed 
{ 

    //@TODO: Fix Logout 

    NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials]; 

    if ([credentialsDict count] > 0) { 
     NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator]; 
     id urlProtectionSpace; 

     while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) { 
      NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator]; 
      id userNameCred; 

      while (userNameCred = [userNameEnumerator nextObject]) { 
       NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userNameCred]; 
       NSLog(@"cred to be removed: %@", cred); 
       [[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace]; 
      } 
     } 
    } 
} 

Mam ten kod z tym przykładzie: http://www.springenwerk.com/2008/11/i-am-currently-building-iphone.html

Teraz mój problem mam jest to, że kiedy wyzwolić przycisk wylogowania, a następnie goto wywołaj metodę logowania BEZ ŻADNYCH POŚREDNIKÓW Mogę się jeszcze zalogować, Jeśli się wyloguję, poczekaj 2 - 3 minuty i zaloguj się bez ŻADNYCH POŚREDNIKÓW Nie mogę się zalogować. Dlaczego zachowuje się w ten sposób, prawie tak, jak kredyty wciąż są zapisywane. Proszę pomóż.

UPDATE

Próbowałem wyczyścić cache, cookies i creds wewnątrz mojego LogoutButtonPressed:

NSURLCache *sharedCache = [NSURLCache sharedURLCache]; 
[sharedCache removeAllCachedResponses]; 

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 
NSArray *cookies = [cookieStorage cookies]; 
id cookie; 
for (cookie in cookies) { 
    [cookieStorage deleteCookie:cookie]; 
} 

NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials]; 
if ([credentialsDict count] > 0) { 
    NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator]; 
    id urlProtectionSpace; 
    while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) { 
     NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator]; 
     id userNameCreds; 
     while (userNameCreds = [userNameEnumerator nextObject]) { 
      NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userNameCreds]; 
      [[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace]; 
     } 
    } 
} 

i nadal nie działa.

Odpowiedz

5

Ten problem może być łatwo ustalony przez dodanie liczby losowej na końcu adresu URL:

-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler 
{ 
    NSInteger randomNumber = arc4random() % 999; 

    NSString *requestURL = [NSString stringWithFormat:@"%@?cache=%ld",kIP,(long)randomNumber]; 

    NSURL *url = [NSURL URLWithString:requestURL]; 

    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] 
             initWithRequest:request]; 

    NSURLCredential *credential = [NSURLCredential 
            credentialWithUser:user 
            password:password 
            persistence:NSURLCredentialPersistenceForSession]; 


    [operation setCredential:credential]; 
    operation.responseSerializer = [AFJSONResponseSerializer serializer]; 
    [[NSOperationQueue mainQueue] addOperation:operation]; 


    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

     if (completionHandler) { 
      completionHandler(responseObject, nil); 
     } 

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

     if (completionHandler) { 
      completionHandler(nil, error); 
     } 

    }]; 

    [operation start]; 

} 

I upewnij się, że masz liczby losowej na końcu wszystkich adresów URL dzwonisz.

+0

Co będzie liczbą losową do zrobienia. Po prostu ciekawy. –

1

LogoutButtonPressed usuwa poświadczenia z NSURLCredentialStorage podczas iteracji na tych samych poświadczeniach - NSEnumerator nie obsługuje tego. Czy widzisz komunikat "cred do usunięcia" w dzienniku?

Zamiast tego można wypróbować metodę _resetCredentials z https://developer.apple.com/library/ios/samplecode/AdvancedURLConnections/Listings/CredentialsController_m.html.

Niezależnie od tego, czy robi to różnicę, interesujące byłoby zbadanie danych wyjściowych, zarówno przed wywołaniem resetCredentials, jak i po nim, z _dumpCredentials - lub jeszcze lepiej zrzutu w metodzie logowania i sprawdzenia, czy nastąpiła zmiana natychmiast po resecie, a następnie 2-3 minuty później.

Czy self.passwordTextField.text jest usuwany? W przypadku braku poświadczeń, w którym się loguje, czy daje zero?

+0

Widzę komunikat 'NSLog (@" do usunięcia:% @ ", cred);' próbowałem zrzucić zeznania w mojej metodzie logowania i zarówno login, UserLogin jak i logoutbuttonpressed – user979331

+1

Cool. Chcesz nam powiedzieć, co ujawnia dump? –

+0

same wyniki ... kiedy się wylogowuję i próbuję zalogować się od razu z błędnymi kredytami, jestem w stanie się zalogować, jeśli poczekam 2-3 mintues, nie jestem w stanie się zalogować. – user979331

Powiązane problemy