I am currently trying to access a webpage where the user can login using their credentials, after entering their user and password - if correct it will redirect to a new url. This new url loads a webpage with a single string which I intend to use.
However, how am I able to check the contents of the redirected url? At the moment I am only able to check the Response/Data/Contents of the initial page loaded by the following method;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
casSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSString *urlAddress = #"https://originalurl.com";
NSURL *httpUrl = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:httpUrl];
[loginPage loadRequest:requestObj];
NSURLSessionDataTask *redirect = [casSession dataTaskWithURL:httpUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *newURL = [NSString stringWithFormat: #"%#", response.URL];
if ([newURL containsString:#"ticket=ST"]) {
NSString * registrationID = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"REGISTRATION: %#", registrationID);
if (registrationID != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
loginPage.hidden = YES;
});
}
} else {
NSLog(#"No ticket recieved");
}
}];
[redirect resume];
I'm not sure which delegate to use, in order to actively check every time a redirection happens and then obtain the contents of the new url?
Thanks.
You’re looking at this the wrong way. You should query the user for the login info directly and insert that into a single NSURLDataTask. Then the data task should query the server with the login info, and return some data.
This all happens with APIs (in a broad manner of speaking) where you will not present HTML contents to the user, but instead some sort of encoded data that is returned.
So for example, once you have a task defined from a URL or URLRequest, and you begin the task, you then use the completion handler to verify the returned data and/or error. If here, you may decode the returned data as a NSString, and then convert the JSON to objects, such as a user’s profile’s data (name, age, email, ...)
I did not go into detail in this answer because it is a very very broad topic, with many use cases. Look up some tutorials on NSURLDataTasks or consuming APIs from Swift and/or Objective-C.
Related
Using URL session FTP download is not working. I tried using below code.
Approach 1
NSURL *url_upload = [NSURL URLWithString:#"ftp://user:pwd#121.122.0.200:/usr/path/file.json"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url_upload];
[request setHTTPMethod:#"PUT"];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSURL *docsDirURL = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:#"prova.zip"]];
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = 30.0;
sessionConfig.timeoutIntervalForResource = 60.0;
sessionConfig.allowsCellularAccess = YES;
sessionConfig.HTTPMaximumConnectionsPerHost = 1;
NSURLSession *upLoadSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLSessionUploadTask *uploadTask = [upLoadSession uploadTaskWithRequest:request fromFile:docsDirURL];
[uploadTask resume];
Approach 2
NSURL *url = [NSURL URLWithString:#"ftp://121.122.0.200:/usr/path/file.json"];
NSString * utente = #"xxxx";
NSString * codice = #"xxxx";
NSURLProtectionSpace * protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:url.host port:[url.port integerValue] protocol:url.scheme realm:nil authenticationMethod:nil];
NSURLCredential *cred = [NSURLCredential
credentialWithUser:utente
password:codice
persistence:NSURLCredentialPersistenceForSession];
NSURLCredentialStorage * cred_storage ;
[cred_storage setCredential:cred forProtectionSpace:protectionSpace];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.URLCredentialStorage = cred_storage;
sessionConfiguration.allowsCellularAccess = YES;
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url];
[downloadTask resume];
The error I get is as follows:
the requested url is not found on this server
But the same url is working in terminal with SCP command and file is downloading successfully
First of all, you should consider switching from ftp to sftp or https protocol, since they are much more secure and address some other problems.
Having that said, ftp protocol is not strictly prohibited in iOS (unlike, say, http), and you still can use it freely. However NSURLSession is not designed to work with ftp-upload tasks out of the box. So you either have to implement a custom NSURLProtocol which adopts such a request or just use other means without NSURLSession.
Either way you will have to rely on the deprecated Core Foundation API for FTP streams. First create a CFWriteStream which points to the destination url on your ftp-server like this:
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFTPURL(kCFAllocatorDefault, (__bridge CFURLRef)uploadURL);
NSOutputStream *_outputStream = (__bridge_transfer NSOutputStream *)writeStream;
And specify the user's login and password in the newly created object:
[_outputStream setProperty:login forKey:(__bridge NSString *)kCFStreamPropertyFTPUserName];
[_outputStream setProperty:password forKey:(__bridge NSString *)kCFStreamPropertyFTPPassword];
Next, create an NSInputStream with the URL to the source file you want to upload to (it's not neccesarily, to bound the input part to the streams API, but I find it consistent, since you anyway have to deal with streams):
NSInputStream *_inputStream = [NSInputStream inputStreamWithURL:fileURL];
Now the complicated part. When it comes to streams with remote destination, you have to work with them asynchronously, but this part of API is dead-old, so it never adopted any blocks and other convenient features of modern Foundation framework. Instead you have to schedule the stream in a NSRunLoop and wait until it reports desired status to the delegate object of the stream:
_outputStream.delegate = self;
NSRunLoop *loop = NSRunLoop.currentRunLoop;
[_outputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[_outputStream open];
Now the delegate object will be notified about any updates in the status of the stream via the stream:handleEvent: method. You should track the following statuses:
NSStreamEventOpenCompleted - the output stream has just established connection with the destination point. Here you can open the input stream or do some other preparations which became relevant shortly before writing the data to the ftp server;
NSStreamEventHasSpaceAvailable - the output stream is ready to receive the data. Here is where you actually write the data to the destination;
NSStreamEventErrorOccurred - any kind of error what may occur during the data transition / connection. Here you should halt processing the data.
Be advised that you don't want to upload a whole file in one go, first because you may easily end up with memory overflow in a mobile device, and second because remote file may not consume every byte sent immediately. In my implementation i'm sending the data with chunks of 32 KB:
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventOpenCompleted:
[_inputStream open];
return;
case NSStreamEventHasSpaceAvailable:
if (_dataBufferOffset == _dataBufferLimit) {
NSInteger bytesRead = [_inputStream read:_dataBuffer maxLength:kDataBufferSize];
switch (bytesRead) {
case -1:
[self p_cancelWithError:_inputStream.streamError];
return;
case 0:
[aStream removeFromRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
// The work is done
return;
default:
_dataBufferOffset = 0;
_dataBufferLimit = bytesRead;
}
}
if (_dataBufferOffset != _dataBufferLimit) {
NSInteger bytesWritten = [_outputStream write:&_dataBuffer[_dataBufferOffset]
maxLength:_dataBufferLimit - _dataBufferOffset];
if (bytesWritten == -1) {
[self p_cancelWithError:_outputStream.streamError];
return;
} else {
self.dataBufferOffset += bytesWritten;
}
}
return;
case NSStreamEventErrorOccurred:
[self p_cancelWithError:_outputStream.streamError];
return;
default:
break;
}
}
At the line with // The work is done comment, the file is considered uploaded completely.
Provided how complex this approach is, and that it's not really feasible to fit all parts of it in a single SO answer, I made a helper class available in the gist here.
You can use it in the client code as simple as that:
NSURL *filePathURL = [NSBundle.mainBundle URLForResource:#"895971" withExtension:#"png"];
NSURL *uploadURL = [[NSURL URLWithString:#"ftp://ftp.dlptest.com"] URLByAppendingPathComponent:filePathURL.lastPathComponent];
TDWFTPUploader *uploader = [[TDWFTPUploader alloc] initWithFileURL:filePathURL
uploadURL:uploadURL
userLogin:#"dlpuser"
userPassword:#"rNrKYTX9g7z3RgJRmxWuGHbeu"];
[uploader resumeWithCallback:^(NSError *_Nullable error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"File uploaded successfully");
}
}];
It doesn't even need to be retained, because the class spawns a thread, which retain the instance until the work is done. I didn't pay too much attention to any corner cases, thus feel free to let me know if it has some errors or doesn't meet the required behaviour.
EDIT
For GET requests the only difference from any other protocol is that you pass login and password as part of URL and cannot use any secure means to do the same. Apart from that, it works straightforward:
NSURLComponents *components = [NSURLComponents componentsWithString:#"ftp://121.122.0.200"];
components.path = #"/usr/path/file.json";
components.user = #"user";
components.password = #"pwd";
[[NSURLSession.sharedSession dataTaskWithURL:[components URL] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable
response, NSError * _Nullable error) {
NSLog(#"%#", response);
}] resume];
I have downloaded a json file (data.json) using NSURLSession. I am trying to access this file from a local html file (main project folder) myfile.html which is displayed via UIWebView. From NSLog I have identified the temp file location is here:
file:///Users/administrator/Library/Developer/CoreSimulator/Devices/166B438D-4F67-448C-B0E5-B32438DA3BF9/data/Containers/Data/Application/FCA61482-BC5D-4804-91F8-891EAB4DB145/tmp/CFNetworkDownload_g6961Q.tmp
My question is how should I access this temp file from the local 'top level' html file, using a relative path?
More generally therefore - how does one access the iOS application file structure from such a top level (relative to the project) html file?
Some background info:
When I manually copy data.json to XCode and access it from myfile.html using the relative path 'data.json' it works.
The download code is:
NSURL *URL = [NSURL URLWithString:#"http://myurl.com/data.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:
^(NSURL *location, NSURLResponse *response, NSError *error) {
}
The reason I am doing this with NSURLSession is that I can't do it with Javascript in the html file since it is a cross domain request.
EDIT: Thanks for the helpful answers about adding HTML as a string into the UIWebView. I can see that trying to reference a temp file from the local HTML file is a bit unwieldly and may run counter to Apple's preference of not exposing filepaths - but I am still interested in a definitive answer on whether it can be done.
Perhaps you could inject the JSONData into the web page once it has finished loading within the web view. Something like this (I have not tested it):
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSError *error = nil;
NSURL *URL = [NSURL URLWithString:#"http://myurl.com/data.json"];
NSString *result = [NSString stringWithContentsOfURL:URL
encoding:NSUTF8StringEncoding error:&error];
if (!error && result.length > 0)
{
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"var jsonData = \"%#\"", result]];
}
else
{
NSLog(#"Oops: %#", error);
}
}
I don't think you can either. Instead of loading your resource HTML as-is, use it as a "template" and put a "placeholder" string where you need the link to your temp file.
Then, load your HTML into a (mutable) string, replace the placeholder for the actual path to the file and pass this modified HTML string to your web view.
We have crated session with below configuration code. I call this method for each task I crate.
+(NSURLSession ) getNewSessionWithID:(NSString )sessionID delegateObject:(id)sender
{
NSURLSession *session;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
queue.maxConcurrentOperationCount=10;
queue.name=sessionID;
session = [NSURLSession sessionWithConfiguration:configuration delegate:sender delegateQueue:queue];
NSLog(#"Session ID :%#",session);
NSLog(#"QUEUE : %#",queue);
return session;
}
Even multiple sessions are created for multiple tasks only one session is active and only one task is executing and for that task only three part are downloading for that one session.
This method is called to create and start download task.
-(void)DLRequestAllRenge:(NSMutableArray*)arrayrange andFileinfo:(FileInfo *)fileInfoObj
{
NSMutableArray *arrayAllParts=[[NSMutableArray alloc]init];
fileInfoObj.tempPath=[fileInfoObj UniqueFileName:[NSTemporaryDirectory() stringByAppendingString:[fileInfoObj.Name stringByDeletingPathExtension]]];
[self createTempDirectory:fileInfoObj.tempPath];
NSLog(#"REQ Session:%#",fileInfoObj.session);
for (int i=0; i<arrayrange.count; i++)
{
NSString *rangString = [arrayrange objectAtIndex:i];
NSMutableURLRequest *request=[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:fileInfoObj.URL]];
[request setValue:rangString forHTTPHeaderField:#"Range"];
NSString *fileName=[NSString stringWithFormat:#"%#(%d).data",[fileInfoObj.Name stringByDeletingPathExtension],i];
NSString *filePath=[fileInfoObj.tempPath stringByAppendingPathComponent:fileName];
FileInfo *subFileInfo=[[FileInfo alloc]init];
subFileInfo.URL=fileInfoObj.URL;
subFileInfo.Name=fileName;
subFileInfo.Path=filePath;
subFileInfo.Folder=[fileInfoObj getCurrentFolderName:filePath];
subFileInfo.Range=rangString;
subFileInfo.isDownloaded=NO;
subFileInfo.NSUrlSessionID=fileInfoObj.NSUrlSessionID;
subFileInfo.Progress=#"0";
subFileInfo.Priority=[NSString stringWithFormat:#"%d",i];
subFileInfo.fileDetail=#"Connecting...";
subFileInfo.fileStatus=RequestStatusDownloading;
subFileInfo.request=request;
subFileInfo.startTime=[NSDate date];
NSURLSessionDownloadTask *downloadTask = [fileInfoObj.session downloadTaskWithRequest:request];
downloadTask.taskDescription=filePath;
[downloadTask resume];
subFileInfo.DownloadTask=downloadTask;
[arrayAllParts addObject:subFileInfo];
}
fileInfoObj.parts=arrayAllParts;
[downloadingArray addObject:fileInfoObj];
[bgDownloadTableView reloadData];
}
Issue 1
Why all sessions are not active?
Issue 2
Why only three part for one task and one session is downloading?
Is there any way we can activate more session for download more part concurrently?
Please help me with this. Any help is appreciated.
Update
We are able to download data using the above code but the issue is I am not able to get any downloaded data when any downloading task is stopped using -suspend or -cancel.
Is there any way I am able to retrieve raw data not the resumeData but the original downloaded data?
I am writing a sample app to test how AFNetworking can be used as a replacement for ASIHTTPLib.. The old library made it simple to upload a file to an Apache server (provided the user has write access to a URL/directory). No other server side support is used..
This code has some problem, but I have not pinpointed it: executing the method reports an upload success, but the plist file on the cloud side does not change…
-(void)uploadReminders:(NSArray*)reminders
{
NSLog(#"AppDelegate Synch Reminders to cloud");
//NSLog(#"Data: %#", reminders);
[self persistReminders:reminders atCustomPath:nil];
NSString *cacheDirectoryPath = [self cachesDirectoryPath];
NSString *urlString = [NSString stringWithFormat:#"%#/%#",kStandardCloudAreaAccessURL,kStandardLocalCachePlistFile];
//NSLog(#"URL: %#", urlString);
NSString *remindersPlistFile = [NSString stringWithFormat:#"%#/%#",cacheDirectoryPath,kStandardLocalCachePlistFile];
//NSLog(#"Filepath: %#",remindersPlistFile);
NSURLCredential *defaultCredential = [NSURLCredential credentialWithUser:kStandardCloudAreaAccessUsername password:kStandardCloudAreaAccessUserPW persistence:NSURLCredentialPersistenceNone];
/**/
NSURL *url = [NSURL URLWithString:urlString];
NSString *host = [url host];
NSInteger port = [[url port] integerValue];
NSString *protocol = [url scheme];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:nil authenticationMethod:NSURLAuthenticationMethodHTTPBasic];
NSURLCredentialStorage *credentials = [NSURLCredentialStorage sharedCredentialStorage];
[credentials setDefaultCredential:defaultCredential forProtectionSpace:protectionSpace];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
[configuration setURLCredentialStorage:credentials];
[configuration setHTTPAdditionalHeaders: #{#"Accept": #"text/plain"}];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
[manager.securityPolicy setAllowInvalidCertificates:YES];
manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
NSURL *URL = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:remindersPlistFile];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Upload Error: %#", error);
} else {
//NSLog(#"Upload Success");
NSLog(#"Upload Success: %# %#", response, responseObject);
}
}];
[uploadTask resume];
}
The console shows this:
Upload Success: <NSHTTPURLResponse: 0x8d4ec50> { URL: https://[.....]/CodeTests/Reminders/Reminders.plist } { status code: 200, headers {
"Accept-Ranges" = bytes;
Connection = "Keep-Alive";
"Content-Length" = 1324;
"Content-Type" = "text/plain";
Date = "Mon, 10 Mar 2014 14:48:13 GMT";
Etag = "\"3f06e5-52c-4f430180dae80\"";
"Keep-Alive" = "timeout=5, max=100";
"Last-Modified" = "Sun, 09 Mar 2014 17:48:26 GMT";
Server = "Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.7l DAV/2";
} } {
reminders = (
{
completed = 1;
created = "2014-03-09 17:47:41 +0000";
description = "";
title = Reminder;
updated = "2014-03-09 17:47:41 +0000";
},
{
completed = 1;
created = "2014-03-08 09:47:58 +0000";
description = "Orza!!! Ma orza in fretta... Ah: funziona? Ebbene, s\U00ec! O no?\n";
title = "Reminder Orza";
updated = "2014-03-08 11:39:43 +0000";
},
{
completed = 0;
created = "2014-03-07 11:09:59 +0000";
description = "Whatever you like; and of course you can even make it quite long.\n\nYeooww..\nReally long!\n\n\n\n";
title = "Reminder A";
updated = "2014-03-08 11:34:24 +0000";
}
);
version = "1.0";
}
The only catch is that when I reopen the app, it jumps back to the test reminders I did manually put on the server: the Reminders.plist gets never changed.
Thanks!
I'm assuming your NSLog of the responseObject is confirming that the plist was successfully received by the server. If so, then that may eliminate the above "upload" code as the source of the problem. You may want to inspect the data on your server (not through the app, but manually inspect it yourself) and see whether your new list of reminders is there or not. It seems that there a couple of possible logical possibilities:
If the updated data is not there, then look at your server's "save" logic, as it would appear to be failing.
If it is there, then you should look at your client's "retrieve" logic. I wonder, for example, if your app is caching the responses to its requests, and thus when you attempt to download again, perhaps you're getting the cached original response. I'd try turning off caching.
In these cases, a tool like Charles can be useful, where you can inspect the requests and responses that you're getting. That can be helpful in narrowing down precisely where the problem is occurring.
Taking a closer look at your request, I notice that you're not specifying the request type. I would have thought that your request would be a POST:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/plain" forHTTPHeaderField:#"Accept"]; // I'd also personally set the `Accept` here at the request, not at the `NSURLSessionConfiguration`
Having said that, given that your web service is successfully reporting your plist data back at you, I would have inferred that it successfully received it on the basis of the evidence you shared with us thus far. But maybe the failure to make the request a POST request means that the web service concluded it didn't need to save anything.
Generally, when interfacing with a web service, rather than tweaking the request, like I have above, I'd encourage you to post data using one of the standard AFHTTPSessionManager variations of the POST method (one is for multipart/form-data requests, the other is for other requests). But I can't figure out what your server is doing on the basis of what you've provided thus far (e.g. it makes no sense that the server is sending the body of your request back to you at all; it makes no sense that the server would appear to have received your request, but doesn't do anything with it and doesn't report some error; etc.). So maybe try making the request a POST request and see if that fixes it. If not, run Charles on your old ASIHTTP source code, and you'll see precisely what the old request looks like and you should be able to reproduce it with AFNetworking.
I am using NSURLCredentialPersistenceForSession within didReceiveAuthenticationChallenge of NSURLConnection delegate method while login.
Now when I logout and use this code for clearing the storage..
NSURLCredentialStorage *credentialStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *credentialsDicationary = [credentialStorage allCredentials];
NSLog(#"credentialsDicationary..%#",[credentialsDicationary description]);
for (NSURLProtectionSpace *space in [credentialsDicationary allKeys]) {
NSDictionary *spaceDictionary = [credentialsDicationary objectForKey:space];
NSLog(#"spaceDictionary..%#",[spaceDictionary description]);
for (id userName in [spaceDictionary allKeys]) {
NSURLCredential *credential = [spaceDictionary objectForKey:userName];
[credentialStorage removeCredential:credential forProtectionSpace:space];
}
}
But when I suddenly login again exactly after logout the login happens with wrong credentials. Please let mw know how to clear the cache. It works if I relogin after some 5 secs of time.
Thanks in advance..
AJ
If you're using NSURLSession, invalidate the session and create a new one, e.g.:
[self.session invalidateAndCancel];
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
This will clear session-scoped credentials.
If you use NSURLCredentialPersistenceForSession to create the credential then the app stores the credential for the entire session until the app is closed.
You can work around this by either:
changing the url (like appending '#' to the end of the url)
Use NSURLCredentialPersistenceNone and provide the credentials with each nsurlrequest
Append auth info to the url (http://username:password#mywebsite.com), instead of using creds
Append auth info to the request header, instead of using creds
//Pseudo code for appending to header:
NSString *authString = [NSString stringWithFormat:#"%#:%#", self.loginCreds.username, self.loginCreds.password];
NSData *stringData = [authString dataUsingEncoding:NSUTF8StringEncoding];
authString = [NSString stringWithFormat:#"Basic %#", [stringData base64EncodedString]];
[[self requestHeader] setValue:authString forHTTPHeaderField:#"Authorization"];
It's possible to remove the credential but it can take minutes before it is actually removed. However, I don't remember how its done.. It's either done the way you mentioned in the question or through the keychain.
I had the same issue and I tried clear the credential storage, cookies associated with url and even trying to reset the session but nothing seemed to work, finally I just resorted to adding a a random query string value to the end of the url and that did the trick for me
// Random number calculated.
NSInteger randomNumber = arc4random() % 16;
NSURL* apiURL = [NSURL URLWithString:#"https://localhost/api/"];
[[RKObjectManager sharedManager] getObjectsAtPath:[NSString stringWithFormat:#"%#getUser?randomNumber=%d",apiURL,randomNumber]
parameters:nil
success:successBlock
failure:failureBlock];
So instead of trying to remove current cached credentials (which seemed impossible) just use a "fresh" url so there aren't any cached objects associated with it.
I was facing the same problem, now it works.
Using NSURLConnection this issue can be fixed easily by adding a random number to the end of the URL:
So, search for your URLRequest and append the random number to URLRequest
NSInteger randomNumber = arc4random() % 999;
NSString *requestURL = [NSString stringWithFormat:#"%#?cache=%ld",yourURL,(long)randomNumber];
NSURL *URLRequest = [NSURL URLWithString:requestURL];
And make sure you have a random number at the end of all URLs you are calling.