Get the Query Of a UIWebView URL - iphone

Hey guys I'm trying to find a way to specifically grab the Query String out of the URL that my UIWebView currently has loaded up.
So for example:
www.google.com?page=235
I want to end up with a NSString with the text "page=235".
Or even better Page at a NSData Key of Title and 235 at a Key of ID.
Im basically trying to organise the Query String into useable data.
In my project I have a button:
[HTML appendString:#"<a href='didtap://goto?Page=56'>Post Comment</a>"];
That i access with checking the absolute URL to see if the button was fired.
Is there any way to profile the information the way i want to?

I create the demo what you want get which is describe further..
Following is the viewcontroller.h file code
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
NSURL *Url;
}
#property(nonatomic,retain)IBOutlet UIWebView *webVctr;
#end
This may helping to solve your problem
Thanks
Following is the viewcontroller.m file code
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize webVctr = _webVctr;
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"%#",request);
Url = [request URL];
// if ([[UrlParts objectAtIndex:(1)] isEqualToString:#"NeverGonnaFindMe"]) {
// CONVERT TO STRING AN CLEAN
NSString *urlResources = [Url resourceSpecifier];
urlResources = [urlResources stringByReplacingOccurrencesOfString:#"?" withString:#"/"];
// SEPORATE OUT THE URL ON THE /
NSArray *urlResourcesArray = [urlResources componentsSeparatedByString:#"/"];
// THE LAST OBJECT IN THE ARRAY
NSString *urlParamaters = [urlResourcesArray objectAtIndex:([urlResourcesArray count]-1)];
// SEPORATE OUT THE URL ON THE &
NSArray *urlParamatersArray = [urlParamaters componentsSeparatedByString:#"&"];
if([urlParamatersArray count] == 1) {
NSString *keyValue = [urlParamatersArray objectAtIndex:(0)];
NSArray *keyValueArray = [keyValue componentsSeparatedByString:#"="];
if([[keyValueArray objectAtIndex:(0)] isEqualToString:#"page"]) {
NSLog(#"%#",[keyValueArray objectAtIndex:1]);
}
[self dismissModalViewControllerAnimated:YES];
return NO;
}
return YES;
}
// ACTIVITY INDICATOR
- (void)webViewDidStartLoad:(UIWebView *)webView{
/// [_activityIndicator startAnimating];
NSLog(#"Resting to server");
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
// [_activityIndicator stopAnimating];
NSLog(#"Finish request server");
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(#"Error");
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *fullAuthUrlString =[[NSString alloc] initWithFormat:#"www.google.com?page=235"];
NSURL *authUrl = [NSURL URLWithString:fullAuthUrlString];
NSURLRequest *myRequest = [[NSURLRequest alloc] initWithURL:authUrl];
[self.webVctr loadRequest:myRequest];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end

To get the query string, get the query string of a NSURL object.
NSURL *url = …;
NSString *queryString = url.query;
For more information, see Accessing the Parts of the URL in the NSURL class documentation.

Related

Reading JSON from URL and adding MKAnnotations

I've been through several different tutorials trying to get this working, but they seem to gloss over some crucial steps that a beginner might not know.
I have a JSON file at a URL with name, latitude, and longitude listed. How can I import that to an array or dictionary (I don't know the difference), and then iterate over it and create a new annotation with each iteration.
IOS6, Storyboards
_ Added Code _
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController {}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (nonatomic, strong) NSMutableData *downloadData;
#end
ViewController.m
#import "ViewController.h"
#import "MapViewAnnotation.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_downloadData = [NSMutableData new];
NSURL *requestURL = [NSURL URLWithString:#"OMITTED/apptest/locations.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_downloadData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
id parsed = [NSJSONSerialization JSONObjectWithData:_downloadData options:kNilOptions error:nil];
for (NSDictionary *pointInfo in parsed)
{
NSLog([parsed objectForKey:#"name"]);
double xCoord = [(NSNumber*)[parsed objectForKey:#"lat"] doubleValue];
double yCoord = [(NSNumber*)[parsed objectForKey:#"lon"] doubleValue];
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(xCoord, yCoord);
MKPointAnnotation *point = [MKPointAnnotation new];
point.coordinate = coords;
point.title = [parsed objectForKey:#"name"];
[self.mapView addAnnotation:point]; // or whatever your map view's variable name is
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidUnload {
[super viewDidUnload];
// ARC Problem --- [_mapView release];
self.mapView = nil;
}
#end
With iOS 5 there's a JSONSerializer class that can convert the raw JSON data from your URL into an array or dictionary as appropriate.
You'll need to download the data from the server:
NSURL *requestURL = [NSURL URLWithString:#"<your url here>"];
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
Then you'll add these delegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_downloadData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
id parsed = [NSJSONSerialization JSONObjectWithData:_downloadData options:kNilOptions error:nil];
}
_downloadData is an instance variable or property of your class of type NSMutableData.
That parsed variable will contain your data from the server. It's probably an array if it's a list of points, so you can iterate through it using fast enumeration:
for (NSDictionary *pointInfo in parsed) {
double xCoord = [(NSNumber*)[parsed objectForKey:#"<key for lat coord>"] doubleValue];
double yCoord = [(NSNumber*)[parsed objectForKey:#"<key for long coord>"] doubleValue];
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(xCoord, yCoord);
MKPointAnnotation *point = [[MKPointAnnotation new] autorelease];
point.coordinate = coords;
point.title = [parsed objectForKey:#"<key for title>"];
[self.mapView addAnnotation:point]; // or whatever your map view's variable name is
}
I have an open source project on GitHub that uses the serializer with the NSCoding protocol so you can automatically create instances right from the JSON stream.
It's here.

Opening a pdf inside the app breaks the design

I'm having some kind of problems with one thing, i'm making an app and i have a webview that shows a pdf file, and i have a button if clicked will call an UIDocumentInteractionController (open the pdf in a new window).
I will leave screenshots to make it easier:
When i open the app:
http://imgur.com/dpIEd
After i open the UIDocumentInteractionController:
http://imgur.com/VYV2N
Here's the code too
.h file
#interface pdfView : UIViewController <UIDocumentInteractionControllerDelegate>
{
IBOutlet UIActivityIndicatorView *loading;
IBOutlet UIWebView *Wview;
UIDocumentInteractionController *controller;
}
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *loading;
#property (nonatomic, retain) IBOutlet UIWebView *Wview;
#property (nonatomic, retain) UIDocumentInteractionController *controller;
-(void)buttonPressed;
-(IBAction)open_in:(id)sender;
-(IBAction)back:(id)sender;
#end
.m file
#import "pdfView.h"
#implementation pdfView
#synthesize loading,Wview;
#synthesize controller;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)viewDidLoad
{
[loading startAnimating];
[super viewDidLoad];
Wview.scalesPageToFit = TRUE;
Wview.multipleTouchEnabled = TRUE;
[Wview setOpaque:NO];
NSString *path = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[Wview loadRequest:request];
[loading stopAnimating];
}
-(IBAction)open_in:(id)sender
{
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
preview.delegate = self;
[preview presentPreviewAnimated:YES];
[preview retain];
}
-(IBAction)back:(id)sender
{
[self.view removeFromSuperview];
}
-(void)buttonPressed
{
//[self.view removeFromSuperview];
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"guia_seguranca_2" ofType:#"pdf"];
UIDocumentInteractionController* preview = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
preview.delegate = self;
[preview presentPreviewAnimated:YES];
[preview retain];
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
[self.controller autorelease];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[super dealloc];
[Wview release];
[loading release];
}
#end
Thanks in advance.....
I would suggest not useing the webview and using a pdf app (ibook, cloudreader) like this.
//name of pdf
NSString * pathString = #"userguide";
//get pdf path
NSString * filePath = [[NSBundle mainBundle] pathForResource:pathString ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:filePath];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:url];
BOOL isValid = [self.docController presentOpenInMenuFromRect:self.handBookLaunch.frame inView:self.view animated:YES];
if (!isValid) {
NSString * messageString = [NSString stringWithFormat:#"No PDF reader was found on your device. Please download a PDF reader (eg. iBooks)."];
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:messageString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
Solved, added this code for layout verification:
-(void) viewWillAppear:(BOOL)animated
{
CGRect arect=[[UIScreen mainScreen]applicationFrame];
CGRect anotherrect=[[UIApplication sharedApplication]statusBarFrame];
if(self.view.center.y==arect.size.height/2)
self.view.center=CGPointMake(self.view.center.x, self.view.center.y+anotherrect.size.height); // fix silliness in IB that makes view start 20 pixels higher than it should on iPhone
}
source: https://discussions.apple.com/thread/2658315?start=0&tstart=0

NSURLConnection and JSON Data

I am stuck with something crazy. I used ASIHTTPRequest to receive my data from a web service and everything worked fine. I switched to using a NSURLConnection and I am receiving the same data and parsing it the same way but my code won't recognize the data with the NSURLConnection.
Here is the data I am receiving (from NSLog)
Did receive data: {"d":"[{\"id\":1.0,\"Category\":1,\"hPlan\":0.0,\"Tip\":\"It takes 3500
calories to gain a pound. If you want to lose a pound per week, reduce your calorie
intake by 250 calories and incorporate daily physical activity that will burn 250
calories.\",\"TipDate\":\"2012-05-12T00:00:00\",\"TimeStamp\":\"AAAAAAAAB9I=\"}]"}
2012-06-06 09:42:11.809 StaticTable[27488:f803] Jsson Array: 0
2012-06-06 09:42:11.809 StaticTable[27488:f803] Jsson Array: (null)
Code:
#import "UYLFirstViewController.h"
#import "MBProgressHUD.h"
#import "JSON.h"
#interface UYLFirstViewController ()
#end
#implementation UYLFirstViewController
#pragma mark -
#pragma mark === UIViewController ===
#pragma mark -
#synthesize MessageField;
#synthesize jsonArray = _jsonArray;
#synthesize TipLabelField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Tickle!", #"Tickle!");
self.tabBarItem.image = [UIImage imageNamed:#"heart_plus"];
[self GetTipOfDay];
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(BOOL)GetTipOfDay{
NSDate *date = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:#"EEEE MMMM d, YYYY"];
NSString *dateString = [dateFormat stringFromDate:date];
NSString *yourOriginalString = #"Tip of the Day for ";
yourOriginalString = [yourOriginalString stringByAppendingString:dateString];
TipLabelField.text = yourOriginalString;
NSURL *url = [NSURL URLWithString:#"http://www.mysite.com/api/GetHealth.asmx/getTipOfDay"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection connectionWithRequest:request delegate:self];
// Clear text field
MessageField.text = #"";
// Start hud
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Gathering Tip of the Day...";
return TRUE;
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(#"Did receive data: %#", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSDictionary *responseDict = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] JSONValue];
NSString *jsonResponse = [responseDict objectForKey:#"d"];
self.jsonArray = [jsonResponse JSONValue];
NSLog(#"Jsson Array: %d", [jsonArray count]);
NSLog(#"Jsson Array: %#", jsonArray);
NSEnumerator *myEnumerator;
myEnumerator = [jsonArray objectEnumerator];
int i;
i=0;
id myObject;
while (myObject = [myEnumerator nextObject])
{
NSDictionary *itemAtIndex = (NSDictionary *)[self.jsonArray objectAtIndex:i];
NSLog(#"Checking for games");
NSString *myCheck = [itemAtIndex objectForKey:#"FName"];
if ([myCheck length] != 0)
{
// NSLog(myCheck);
MessageField.text = myCheck;
}
}
}
- (void)viewDidUnload {
[self setMessageField:nil];
[self setTipLabelField:nil];
[super viewDidUnload];
}
#end
#import <UIKit/UIKit.h>
#interface UYLFirstViewController : UIViewController{
NSMutableArray *jsonArray;
}
#property (weak, nonatomic) IBOutlet UILabel *MessageField;
#property (weak, nonatomic) NSMutableArray *jsonArray;
#property (weak, nonatomic) IBOutlet UILabel *TipLabelField;
-(BOOL)GetTipOfDay;
#end
-didRecieveData can be called multiple times as the bytes and chunks come in. You should move your logic to -connectionDidFinishLoading. This will let you know when the connection is completely done and the data is ready to be parsed.
You're only implementing one of the NSURLConnectionDelegate methods. Try adding this
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//set up *receivedMutableString as instance variable in .h
if (!receivedMutableString) {
self.receivedMutableString = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];
} else {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[receivedMutableString appendString:dataString];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Now receivedMutableString contains all json data
...continue with your code
}
NSURLConnection is a bit of overkill if you're just doing a simple GET request (and you're developing for an iOS version that supports blocks). You can do this in a dispatch_async block:
- (void) getData
{
dispatch_async(<some_queue>, ^{
NSError * error = nil;
NSString * response = [NSString stringWithContentsOfURL: stringWithContentsOfURL: requestUrl error: &error];
// process JSON
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI on main thread
}
});
}
As you can see from my example code, you can also perform your JSON processing on the background queue (provided the method you're calling is thread safe). Just pass back to the main queue to update the UI.
Seems like the issue had nothing to do with fetching from the webservice. I had to define my array as __strong. Thanks for all the help. I did get some good ideas on how to do things better.

Links inside Pdf on Webview are not opening in a browser in iPhone

I have parsed urls of pdfs and showing pdf on a webView, but my Links inside webviews are not opening in a browser.i have not used CGPDFDocument. my code is simple :). can anyone help me out.i have seen many similar questions but all are using Quartz.
code :-
#class AppDelegate_iPhone;
#interface PdfShowViewController : UIViewController<UIWebViewDelegate> {
IBOutlet UIWebView *pdfWebview;
AppDelegate_iPhone *appDelegate;
NSMutableData *receivedData;
IBOutlet UIActivityIndicatorView *myIndicator;
IBOutlet UIProgressView *progress;
NSURLRequest* DownloadRequest;
NSURLConnection* DownloadConnection;
long long bytesReceived;
long long expectedBytes;
IBOutlet UILabel *downloadLabel;
}
#property (nonatomic,retain) IBOutlet UILabel *downloadLabel;
#property (nonatomic,retain) IBOutlet UIWebView *pdfWebview;
#property (nonatomic,retain) IBOutlet UIActivityIndicatorView *myIndicator;
#property (nonatomic,retain) IBOutlet UIProgressView *progress;
#property (nonatomic,retain) NSMutableData *receivedData;
#property (nonatomic, readonly, retain) NSURLRequest* DownloadRequest;
#property (nonatomic, readonly, retain) NSURLConnection* DownloadConnection;
#property (nonatomic, retain, readwrite) NSURL *openURL;
-(IBAction)onTapBack;
#end
#implementation PdfShowViewController
#synthesize pdfWebview,myIndicator,progress,receivedData,DownloadRequest,DownloadConnection,downloadLabel,openURL;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
unsigned char byteBuffer[[receivedData length]];
[receivedData getBytes:byteBuffer];
NSLog(#"Data === %ld",receivedData);
NSInteger receivedLen = [data length];
bytesReceived = (bytesReceived + receivedLen);
NSLog(#"received Bytes == %f",bytesReceived);
if(expectedBytes != NSURLResponseUnknownLength)
{
NSLog(#"Expected Bytes in if == %f",expectedBytes);
NSLog(#"received Bytes in if == %f",bytesReceived);
float value = ((float) (bytesReceived *100/expectedBytes))/100;
NSLog(#"Value == %f",value);
progress.progress=value;
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
expectedBytes = [response expectedContentLength];
NSLog(#"%f",expectedBytes);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[myIndicator stopAnimating];
[myIndicator removeFromSuperview];
[progress setHidden:YES];
[downloadLabel setHidden:YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:#"iPhonePdf.pdf"];
unsigned char byteBuffer[[receivedData length]];
[receivedData getBytes:byteBuffer];
[self.receivedData writeToFile:pdfPath atomically:YES];
[DownloadConnection release];
//Now create Request for the file that was saved in your documents folder
NSURL *url = [NSURL fileURLWithPath:pdfPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[pdfWebview setScalesPageToFit:YES];
[pdfWebview loadRequest:requestObj];
}
-(BOOL)webView:(UIWebView *)webView1 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *requestURL = [request URL];
if(navigationType==UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication] openURL:requestURL];
return NO;
}
else
{
return YES;
}
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
pdfWebview.delegate = self;
appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
[downloadLabel setText:#"Downloading..."];
[downloadLabel setHidden:NO];
[myIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
myIndicator.hidesWhenStopped = YES;
[myIndicator startAnimating];
// NSString *urlString = [appDelegate.currentBookPressed stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *urlString = [appDelegate.currentBookPressed stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// NSLog(#"The Url Stirng=======%#",urlString);
NSURL *targetURL = [NSURL URLWithString:urlString];
//NSLog(#"Trageted String ------======++++++++%#",targetURL);
DownloadRequest = [NSURLRequest requestWithURL:targetURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:1200.0];
DownloadConnection = [[NSURLConnection alloc] initWithRequest:DownloadRequest delegate:self];
if (DownloadConnection) {
receivedData = [[NSMutableData data]retain];
}
[pdfWebview setScalesPageToFit:YES];
[pdfWebview loadRequest:DownloadRequest];
}
-(IBAction)onTapBack
{
[self dismissModalViewControllerAnimated:YES];
}
#end
here is the link which i am trying to open but not opening :-
No, links inside pdf files loaded in a UIWebView won't open when you tap them by default.
You can go the hard way and parse the links out using Quartz as is shown in this other post I answered.
Or, instead of loading a pdf, can you convert the content you are loading to an html file instead? That would be easier, and the links should work then.
You have to use below delegate method
-(BOOL)webView:(UIWebView *)webView1 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *requestURL = [request URL] ;
if(navigationType==UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication] openURL:requestURL];
return NO;
}
else
{
return YES;
}
}

How to load table with some default image till it get the original image from internet iPhone?

I have a uitableview which stores one image in one cell. Its image get loaded from internet. The problem is the application get slow till its image get loaded from internet. So I want to put a mechanism that it first get loaded with a default image and when it gets the original then the default image will be replaced by the original one.
Give me any tutorial or any sample code for it.
Thanks in advance.
Get your image trough some other thread .... and use notification or delegate to keep track of any change in image download ... suppose you are using notification .... then in class which you set as observer for that notification reload the data of tableView .... so your table image will get updated where there was so default image .... for more detail lets take an example ..... Make a operation class to downloading the image we call it thumb .... In this example I make 2 classes
1. PhotoGalleryVC which shows a list of thumbs and some detail of each thumb and
2. LoadGalleryThumbOp [Op = operation] downloads thumbs and post notification when done
#protocol LoadGalleryThumbDelegate;
#interface LoadGalleryThumbOp : NSObject{
NSIndexPath* indexPathInTableView;
id <LoadGalleryThumbDelegate> delegate;
NSMutableData *activeDownload;
NSURLConnection *imageConnection;
NSString * documentPath;
BOOL imageDownload;
}
#property (nonatomic, assign) NSIndexPath* indexPathInTableView;
#property (nonatomic, retain) NSMutableData *activeDownload;
#property (nonatomic, retain) NSURLConnection *imageConnection;
#property (nonatomic, assign) id <LoadGalleryThumbDelegate> delegate;
#property (nonatomic, retain) NSString * documentPath;
#property (nonatomic) BOOL imageDownload;
- (void)startDownload;
- (void)cancelDownload;
- (void) persistData:(NSData*) data;
#end
#protocol LoadGalleryThumbDelegate
- (void)appImageDidLoad:(NSIndexPath *)indexPath;
#end
in LoadGalleryThumbOp.m do it as
#implementation LoadGalleryThumbOp
#synthesize year;
#synthesize indexPathInTableView;
#synthesize delegate;
#synthesize activeDownload;
#synthesize imageConnection,documentPath,imageDownload;
#pragma mark
- (void)startDownload
{
self.imageDownload = YES;
self.activeDownload = [NSMutableData data];
NSFileManager* fm = [NSFileManager defaultManager];
NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:#"images/thumb.jpg"]];
if ([fm fileExistsAtPath:galleryDocumentPath])
{
UIImage *image = [[UIImage alloc] initWithContentsOfFile:galleryDocumentPath ];
self.gallery.thumpImage = image;
self.activeDownload = nil;
[image release];
self.imageConnection = nil;
[delegate appImageDidLoad:self.indexPathInTableView];
}
else {
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:#error yourImageUrl]] delegate:self];
self.imageConnection = conn;
[conn release];
}
}
- (void)cancelDownload
{
[self.imageConnection cancel];
self.imageConnection = nil;
self.activeDownload = nil;
}
#pragma mark -
#pragma mark Download support (NSURLConnectionDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.activeDownload appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.activeDownload = nil;
self.imageConnection = nil;
self.imageDownload = NO;
[NSString stringWithFormat:#"images/thumb.jpg"]];
[delegate appImageDidLoad:self.indexPathInTableView];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self persistData:self.activeDownload];
self.activeDownload = nil;
self.imageConnection = nil;
[delegate appImageDidLoad:self.indexPathInTableView];
}
- (void) persistData:(NSData*) data
{
NSFileManager* fm = [NSFileManager defaultManager];
NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:#"images/thumb.jpg"]];
if ([[NSFileManager defaultManager] fileExistsAtPath:galleryDocumentPath])
{
NSError* err = nil;
[fm removeItemAtPath:galleryDocumentPath error:&err];
if (err)
NSLog(#"%s:%#",__FUNCTION__,err);
}
[fm createFileAtPath:galleryDocumentPath contents:data attributes:nil];
}
this class will download the image you wanted and will call its delegate when the image is download ..
Now comes its use part in PhotoGalleryVC use it like this
#interface PhotoGalleryVC : UIViewController <LoadGalleryThumbDelegate>{
IBOutlet UITableView* albumListTableView;
NSMutableDictionary *imageDownloadsInProgress;
NSArray* allThumbs;
}
#property (nonatomic, retain) NSMutableDictionary *imageDownloadsInProgress;
- (void)appImageDidLoad:(NSIndexPath *)indexPath;
#end
in .m part
- (void)viewDidLoad {
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
.....
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSFileManager* fm = [NSFileManager defaultManager];
NSString* galleryDocumentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:#"Gallery/%#/images/thumb.jpg",[someObj.title stringByReplacingOccurrencesOfString:#" " withString:#"_" ]]];
//this above line is just make a seperate folder for each object and store thumbs of that object in that folder ... so make it unique some how
if (![fm fileExistsAtPath:galleryDocumentPath])
{
LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader != nil && galleryThumbDownloader.imageDownload == NO)
{
[cell.activityIndicator stopAnimating];
cell.albumCoverImageView.image = [UIImage imageNamed:#"no_thumb.png"];
}
else {
[cell.activityIndicator startAnimating];
}
[self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:#"%d",selectedYear]];
}
else
{
[cell.activityIndicator stopAnimating];
cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
}
return cell ;
}
//The following method see if there is already so downloader that is downloading same image then it simply do nothing else it create a downloader and start it
- (void)startIconDownload:(Gallery *)gallery forIndexPath:(NSIndexPath *)indexPath andYear:(NSString*)yr
{
LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader == nil)
{
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* nameWithoutSpace = [gallery.title stringByReplacingOccurrencesOfString:#" " withString:#"_" ];
NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"Gallery//%#",nameWithoutSpace]];
galleryThumbDownloader = [[LoadGalleryThumbOp alloc] init];
galleryThumbDownloader.documentPath = galleryDocumentPath;
galleryThumbDownloader.indexPathInTableView = indexPath;
galleryThumbDownloader.delegate = self;
[imageDownloadsInProgress setObject:galleryThumbDownloader forKey:indexPath];
[galleryThumbDownloader startDownload];
[galleryThumbDownloader release];
}
else if(galleryThumbDownloader.imageDownload == NO)
{
if (albumListTableView.dragging || albumListTableView.decelerating) {
[galleryThumbDownloader startDownload];
}
}
}
finally the method which is called when a particular image is downloaded
- (void)appImageDidLoad:(NSIndexPath *)indexPath
{
CustomCellPhotoGalary* cell = (CustomCellPhotoGalary*)[albumListTableView cellForRowAtIndexPath:indexPath];
LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader != nil)
{
if (galleryThumbDownloader.imageDownload)
{
[cell.activityIndicator stopAnimating];
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* nameWithoutSpace = [temp.title stringByReplacingOccurrencesOfString:#" " withString:#"_" ];
NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"Gallery/%#",nameWithoutSpace]];
cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
//galleryThumbDownloader = nil;
}
else {
[cell.activityIndicator stopAnimating];
cell.albumCoverImageView.image = [UIImage imageNamed:#"no_thumb.png"];
[self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:#"%d",selectedYear]];
}
[albumListTableView reloadData];
}
}
woooh.....! thats a lot of code for one example
Note : I cut out so many line so this code may not work for u directly {there may be so many errors .. }, But i hope you get the main idea behind the scene ... :)
This sample code is great, It taught me a lot.
This uses the ASIHttpRequest framework, if you are going to use this technique, I recommend you use the latest version from here, because the version in the sample code is quite old now.
This sample code should help you with custom delegation of your cells etc.
As per above scenario, its always better to use LazyTableImages.
The best example given here