我有一个基本问题,我希望有一个我错过的简单答案。基本前提是我要连接到一个网站并下载一些JSON数据。我正在使用Stig Brautaset提供的框架,该教程非常有效。
我的问题是我所连接的网站格式正确,我的应用程序的用户名和密码是固定的,因此用户永远不会输入它们。
curl -u username:password http://website.com/page
如何将网址和密码传递给NSURLConnection
?
它不一定是NSURLConnection
,它似乎是最好的选择。
我查看了AdvancedUrlConnections
样本,但它看起来过于复杂而且已经很老了。在网上搜索并没有好多少。我希望你们中的一个人能说出这两个属性,然后选择合适的侮辱......
答案 0 :(得分:3)
NSURLConnection可以正常工作。正如另一个答案所指出的那样,实现didReceiveAuthenticationChallenge
回调非常容易。
- (void) someMethod
{
NSURLRequest* request = [[NSURLRequest alloc]
initWithURL:[NSURL urlWithString:@"someURL"]
NSURLConnection* connection = [[NSURLConnection alloc]
initWithRequest:request delegate:self];
[connection release];
[request release];
}
这一切都非常直截了当。它位于NSURLConnection的委托方法中,所有的魔法都发生了:
这是您处理凭据挑战的地方。我已经硬编码了一个假的用户名和密码来演示它是如何工作的。我个人有一个单独的委托对象处理挑战。请记住,连接将处于空闲状态,直到您对其进行响应或连接超时为止。
- (void) connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
// Make sure to use the appropriate authentication method for the server to
// which you are connecting.
if ([[challenge protectionSpace] authenticationMethod] ==
NSURLAuthenticationMethodBasicAuth)
{
// This is very, very important to check. Depending on how your
// security policies are setup, you could lock your user out of his
// or her account by trying to use the wrong credentials too many
// times in a row.
if ([challenge previousFailureCount] > 0)
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
UIAlertView* alert = [[UIAlertView alloc]
initWithTitle:@"Invalid Credentials"
message:@"The credentials are invalid."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
[challenge useCredential:[NSURLCredential
credentialWithUser:@"someUser"
password:@"somePassword"
persistence:NSURLCredentialPersistenceForSession
forAuthenticationChallenge:challenge]];
}
}
else
{
// Do whatever you want here, for educational purposes,
// I'm just going to cancel the challenge
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
您还需要为NSURLConnection实现这些其他方法:
// So you know when it's done downloading
- (void) connectionDidFinishLoading:(NSURLConnection *)connection;
// In case of failure
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
// Gather the downloaded file data
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
答案 1 :(得分:0)
有几种可能性。
如果使用异步NSURLConnection,将在连接的委托上调用方法-connection:didReceiveAuthenticationChallenge:
。该方法的文档解释了如何处理它。这是AdvancedUrlConnections
使用的,是的,它有点混乱。
更简单的方法是在创建连接时创建NSMutableURLRequest
(而不是不可变的NSURLRequest
)。这允许您添加任意HTTP标头。构造一个基本的auth标头很简单 - 类似于
NSMutableURLRequest *request = .... // details omitted
NSString *username = // ....
NSString *password = // ....
NSData *authRawData = [[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *authEncoded = [authRawData asBase64EncodedString];
[request setValue:[NSString stringWithFormat:@"Basic %@", authEncoded] forHTTPHeaderField:@"Authorization"];
以上使用TouchFoundation
中包含的-asBase64EncodedString
方法