Tuesday 22 March 2011

Authentication in UIWebView and NSURLConnection (Documented API)

in IOS 4.3, you cannot use private API :

@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end

for ignoring https certificate. I have been using this method for several projects, doing testing before the app is release. testing url that my client gave to me wasn't trusted site. thus, we need to ignore authentication on that site.

 Solution:

implement NSURLConnection delegate : document api

  • – connection:canAuthenticateAgainstProtectionSpace:  delegate method
  • – connection:didReceiveAuthenticationChallenge:  delegate method

when you are using NSURLConnection, implement two of this method. (don't forget to delegate your NSURLConnection).


NSURLConnection *theConnection=[[[NSURLConnection allocinitWithRequest:theRequest delegate:self]autorelease];


then impelent 2 of these delegate :

#pragma mark - NSURLConnection delegate
- (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])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}


If you are using UIWebView only, add this inside webView:shouldStartLoadWithRequest:navigationType:
 (don't forget to delegate your NSURLConnection).

[NSURLConnection connectionWithRequest:request delegate:self];

Then add 2 NSURLConnection delegate above. you UIWebView will ignore base on your NSURLConnection.




Note:

  • You may check ASIHTTPConnection to do the same and easier. 
  • This checking only requires once. you don't need to add this delegate everytime you connect to your site.
  • when using UIWebView + NSURLConnection, make sure you have boolean to check that [NSURLConnection connectionWithRequest:request delegate:self]; only done once. set boolean off to disable :
    if (!isAuth) {
isAuth = YES;
[NSURLConnection connectionWithRequest:request delegate:self];
}

  • declare isAuth in header file. it will set default to NO. 
  • close connection in didReceiveResponse:
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[connection cancel];
connection=nil;
}




Happy coding :). leave a comment if you like / have another approach.

Saturday 19 March 2011

(Solved) UITableViewCell not load data entirely!

I have been working around this problem since 5 months ago. When i used UITextField inside UITableView for 15 of cell inside table, it changed UITextField that I wasn't originally edited.

This problem cause by using of this method :










it will only reload as many rows visible, when you are scrolling down, it wont load inside if statement. because we use reusable cell on all rows/section.

I found out the solution to overcome this problem, it might not the best solution but I couldn't find any.

solution :



by doing this, you will only load one time per cell. you can also set your label here (if your label is static, not change further). I'm not sure what will happen if i have many Identifier. but I only have 15 rows for my project I'm working on, so it won't affect much. 

On next post, I will post  on how to create UITableView with UITextField inside with using this approach. but right now, i have to finish this project first :).

as always, drop an comment if you have better approach or feedback. Have a nice code.