2015-04-09 7 views
11

Sto usando NSURLCredentials in questo metodo:Objective-C chiaro 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]; 
} 

E ora sto cercando di cancellare i NSURLCredentials in un metodo di logout in questo modo:

-(void)logout 
{ 
    //Clear NSURLCredentialPersistenceForSession 
} 

Come avrei Vado a fare questo? Devo resettare NSURLCredentials o è lì per eliminarli?

UPDATE

ho trovato questa soluzione:

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

     } 

    } 

Da qui: Using NSURLCredentialPersistenceForSession while request and then clearing the credentials on logout still persist the cerdentials

E 'questo il modo migliore? Ho solo 1 credenziale memorizzata. Anche questo codice mi dà un avvertimento su questa linea:

NSURLCredential *credential = [spaceDictionary objectForKey:userName]; 

e qui è l'avvertimento ... come faccio a rimuovere questo avviso?

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

UPDATE

Va bene, così ho 3 metodi: UserLogin, di accesso e LogoutButtonPressed

UserLogin: Sto usando AFNetworking per connettersi a un autenticato URL Windows utilizzando NSURLCredential come indicato sopra:

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

} 

Questo metodo viene chiamato dal metodo login:

- (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; 

     } 
    }]; 

} 

E io sto cercando di chiarire la mia sessione con il 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]; 
      } 
     } 
    } 
} 

ho ottenuto questo codice da questo esempio: http://www.springenwerk.com/2008/11/i-am-currently-building-iphone.html

Ora il mio problema che sto avendo è che quando ho innescare la pulsante di logout e quindi goto innescare il metodo di accesso SENZA CREDENZIALI Posso ancora accedere, Se esco, attendi 2 - 3 minuti e accedi con NO CREDENZIALI Non riesco ad accedere. Perché si sta comportando in questo modo, è quasi come se i crediti venissero salvati. Per favore aiuto.

UPDATE

ho cercato di cancellare la cache, cookie e creds dentro il mio 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]; 
     } 
    } 
} 

e ancora non ha funzionato.

risposta

5

Questo problema può essere risolto facilmente con l'aggiunta di un numero casuale alla fine dell'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]; 

} 

e assicurarsi di avere un numero casuale alla fine di tutti gli URL che si sta chiamando.

+0

Cosa farà un numero casuale. Sono solo curioso di sapere. –

1

LogoutButtonPressed sta rimuovendo le credenziali da NSURLCredentialStorage durante l'iterazione sulle stesse credenziali. NSEnumerator non lo supporta. Stai vedendo il messaggio "cred essere rimosso" nel log?

Si potrebbe provare invece il metodo _resetCredentials da https://developer.apple.com/library/ios/samplecode/AdvancedURLConnections/Listings/CredentialsController_m.html.

Indipendentemente dal fatto che ciò faccia la differenza, sarebbe interessante esaminare l'output, sia prima che dopo la chiamata resetCredentials, di _dumpCredentials - o meglio ancora fare il dump nel metodo di accesso, e vedere se c'è un cambiamento subito dopo il reset e 2-3 minuti dopo.

È stato eliminato il campo self.passwordTextField.text? Nel caso in cui non ci siano credenziali in cui si effettua l'accesso, il numero NSURLCredential credentialWithUser: ti dà zero?

+0

Vedo il messaggio "NSLog (@" da rimuovere:% @ ", cred);' messaggio, ho provato a scaricare i crediti nel mio metodo di accesso e sia login, UserLogin e logoutbuttonpressed – user979331

+1

Cool. Vuoi dirci cosa rivela la discarica? –

+0

stessi risultati ... quando mi disconnetto e tento di accedere subito con crediti errati, sono in grado di accedere, se aspetto 2-3 minuti non riesco ad accedere. – user979331