Products for Cocoa (tm) and iOS (tm)

UIWebView with authentication and file download

Download two freeware classes for Cocoa/iOS/IPad/iPhone that can perform basic authentication and file downloads in UIWebView

Note: Both classes does NOT use undocumented functions, hacks etc. so they CAN be used in AppStore!!!

DOWNLOAD the EASY solution: TKAWebView (NOT reccomended for serious projects)
DOWNLOAD the PROFESSIONAL solution: TKAURLProtocol ver. 2.0
DOWNLOAD the ULTIMATE solution: TKAWebViewPro (coming soon ...)
UIWebView is an amazing tool for iOS programmers
Until they start programming and see that UIwebView is different from mobile Safari
1. Safari can perform authentication - UIWebView can NOT.
2. Both Safari and UIWebView cannot download files - they only can display pages, images, pdf's etc.

Many modern iOS applications need to download files and access a secure locations
Recently i created a E-Book HTTP server where i store my favorite e-books
This server is protected by basic authentication so i can acces my books over the internet
So i start my favorite e-book reader on iPad connect to the book server and download the books i wish to read
I was very dissapointed when i saw that some e-book readers cannot connect just becouse of authentication
Others have funny interface and ask me each time i click a link to download link or just to browse it.
I understand why when i started to program with UIWebView - there are no such capabilities in this component at all.
Well i have many years experiance with creating Delphi components for windows so i started to explore how to hack the UIWebView
After a 3 weeks of research i found 2 ways
First way is an approximation and i call him EASY solution. Second way is more complicated but is perfect with no drawbacks and i call him PROFESSIONAL solution.

 

THE ULTIMATE SOLUTION: TKAWebViewPro
What to expect from TKAWebViewPro
Based on TKAURLProtocolPro
1. One visual view with embedded Webview supporting Authentication and file downloading
2. Support for Windows NTLM authentication
3. Ability to create and display Safari webarchive files (with limitations)
4. Ability to create and display IE MHT/MHTML files (with limitations)
This is the ultimate solution for lasy programmers - thats why it has a price - $50
Current status: RC1 - no known bugs
THE PROFESSIONAL SOLUTION: TKAURLProtocol
OK the perfect solution will be to intercept all calls from UIWebView and examine them
First i think that a good idea is to create NSURLcache subclass, set this subclass as a SharedURLCache and examine all calls coming from UIWebView
I started coding but one good day i found the real solution - it is called NSURLProtocol and beleve me THIS IS THE REAL HACK
NSURLProtocol subclassing is used to handle cutom URL schemes for example instead of http://www.kadao.com/ use wwtp://www.kadao.com/
Subclas can be registered in the URL loading system and each time it encounters custom URL scheme it will use my subclass to load the url
But what if we register a scheme for http:?
The result is amasing - each time a UIWebView needs to load URL it uses my subclass TKAURLProtocol
My protocol examines the request header and add a custom header to match this request.
For requests that are not yet matched i initiate a NSURLConnection with custom header added
This NSURLConnection will download all data requested by UIWebView and by any other classes that download data via HTTP
For already matched reguests my subclass just refuses to handle the request and it is handled by the standard URL loading protocol
WOW and this is a really perfect solution
It does not have drawbacks and for now it was not failed in my tests
THE EASY SOLUTION: TKAWebView
EASY solution is based on creating a subclass of UIWebView
The idea is the following

Downloading:
1. Intercept all UIWebView requests in webView:shouldStartLoadWithRequest:navigationType: delegate
2. Before returning from delegate method create an NSURLConnection with the same URL
3. When connection receive NSURLResponce from HTTP server cancel the connection and examine the content type of the responce
4. If responce should be downloaded return NO from webView:shouldStartLoadWithRequest and initiate a separate download using NSURLConnection

Authentication:
1. Using same approach When a NSURLConnection receive an authentication challenge present login dialog
2. If authentication is successful store credentials for the session and subsequent calls from UIWebView will use stored creadentials
3. When connection receive NSURLResponce from HTTP server cancel the connection and examine the content type of the resopnce
4. If responce should be downloaded return NO from webView:shouldStartLoadWithRequest and initiate a separate download using NSURLConnection

Unfortunatelly this approach have some drawbacks
1. if requested page is in nonsecure place but uses images or css files from secure locations there is no way to intercept request and these images css etc will not be loaded
2. Also webView:shouldStartLoadWithRequest has a timeout of 10 seconds and a nasty message appears in the console. This message does nothing but it is shame for programming
There is a way to avoid this message by returning NO from webView:shouldStartLoadWithRequest, examine the url and call loadRequest: again if the content type should be loaded in WeBView or initiate a download if content type is something like zip etc.

 

Thats why i created two demo projects - one using EASY solution and one using PROFESSIONAL solution
Both subclasses have many delegate methods so you can examine all the possible things that can be examined

Visit this page next month - it will contain documentation for all delegates and properties (their names are self explaining but just for sure)

This is my gift for the iOS society - i learned a much from free products.
And both calasses are absolutely free - use them for ANY purpouse.
Happy coding ...

Kiril Antonov
24.11.2010


All mentioned trademarks are property and copyright of their respective owners
 
 
 
Copyright (c) 2010 by Kiril Antonov, Sofia, Bulgaria
If you have any comments or notes and suggestions, please
send e-mail to Kiril Antonov at: kirila@abv.bg