UIWebView with authentication and file downloadDownload two freeware classes for Cocoa/iOS/IPad/iPhone that can perform basic authentication and file downloads in UIWebView
| ||
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 ...) | ||
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 |