fetching an image from a https link

2019-05-10 04:06发布

I have just started learning ios development, and I am trying to get an image from website which uses ssl, when i connect to the site through a browser(laptop) there is a warning which says that the root certificate is not trusted, I am not the owner of the website, however I can fully trust it. My first attempt:

self.eventImage.image = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL  URLWithString:imageUrl]]];

so I get this error

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9807)

I have tried to send users to the picture link by starting ios web browser, when they do that, they would get a message asking them if they could trust it or not, if they hit yes the image will appear, however i want the image to appear inside the application.

I have also tried to use web view but it didn't work.

Most of the similar questions in here suggested using this

- (BOOL)connection:(NSURLConnection *)
  connection canAuthenticateAgainstProtectionSpace: 
  (NSURLProtectionSpace *)protectionSpace {
    return NO;
    //return [protectionSpace.authenticationMethod isEqualToString:
    //         NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)
  connection didReceiveAuthenticationChallenge:
  (NSURLAuthenticationChallenge *)challenge {
     NSString *imageUri =[self.detailItem objectForKey: @"image"];
     NSArray *trustedHosts = [[NSArray alloc]initWithObjects:imageUri, nil];
     if ([challenge.protectionSpace.authenticationMethod   
         isEqualToString:NSURLAuthenticationMethodServerTrust])
        if ([trustedHosts containsObject:challenge.protectionSpace.host])
               [challenge.sender useCredential:[NSURLCredential credentialForTrust:
                challenge.protectionSpace.serverTrust] forAuthenticationChallenge:
                challenge];

 [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

but these two methods were never called when I add them.

标签: ios ssl https
4条回答
霸刀☆藐视天下
2楼-- · 2019-05-10 04:40

Try adding these two methods

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
查看更多
太酷不给撩
3楼-- · 2019-05-10 04:44

I hope you have included the NSURLConnectionDelegate protocol in the interface in .h file?

@interface ConnectionExampleViewController : UIViewController <NSURLConnectionDelegate>
查看更多
Ridiculous、
4楼-- · 2019-05-10 04:56

rmaddy, user2179059, and Anindya Sengupta answers helped in resolving this issue.

first, i used NSURLConnection explicitly, and for the secure connection i used this approach ( got it from this blog post )

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:
(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod
        isEqualToString:NSURLAuthenticationMethodServerTrust];
}

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:
(NSURLAuthenticationChallenge *)challenge {
if ([challenge.protectionSpace.authenticationMethod
      isEqualToString:NSURLAuthenticationMethodServerTrust]) {
      // instead of XXX.XXX.XXX, add the host URL, 
      // if this didn't work, print out the error you receive.
    if ([challenge.protectionSpace.host isEqualToString:@"XXX.XXX.XXX"]) {
        NSLog(@"Allowing bypass...");
        NSURLCredential *credential = [NSURLCredential credentialForTrust:
                                       challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential
             forAuthenticationChallenge:challenge];
    }
 }
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

this differ from user2179059 by limiting unsecure connection to that host only.

查看更多
何必那么认真
5楼-- · 2019-05-10 05:02

Change your code. Instead of using NSData dataWithContentsOfURL: you need to use your own explicit NSURLConnection. Then you can make use of the appropriate NSURLConnectionDelegate methods.

Another option is to use the popular AFNetworking library.

查看更多
登录 后发表回答