I'm making an iphone app...can I get the source from it in objective-c?
Thanks!
Elijah
You can get anything from the web view that JavaScript can return using stringByEvaluatingJavaScriptFromString:. Try something along the lines of
document.lastChild.outerHTML
The document will likely have two child nodes; the first will be the DOCTYPE, and the second the <html> element.
If you need to get the contents of the current URL in your web view you could have something like this in a UIViewController. I didn't compile this code, so there may be some syntax errors, but this should be a solid starting point for your problem.
#interface aViewController : UIViewController <UIWebViewDelegate>
UIWebView *webView;
NSString *htmlSource;
#end
#implementation aViewController
-(void) viewDidLoad {
CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
self.webView = [[UIWebView alloc] initWithFrame:webFrame];
self.webView.delegate = self;
NSURL *aURL = [NSURL URLWithString:#"http://www.myurl.com"];
NSURLRequest *aRequest = [NSURLRequest requestWithURL:aURL];
//load the index.html file into the web view.
[self.webView loadRequest:aRequest];
}
//This is a delegate method that is sent after a web view finishes loading content.
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(#"finished loading");
self.htmlSource = [[NSString alloc] initWithData:[[webView request] HTTPBody] encoding:NSASCIIStringEncoding];
}
#end
Related
I am newbie to Objective-C.I want to know how to load the local html file(say index.html) into UIWebView,i can able to load the url like this,
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"willAppear");
UIWebView *myWebView=[[UIWebView alloc]initWithFrame:CGRectMake(20, 20, 400, 400)];
NSURL *url = [[NSURL alloc] initWithString:#"http://www.google.co.in/"];
[myWebView loadRequest:[NSURLRequest requestWithURL:url]];
myWebView.scalesPageToFit = YES;
[self.view addSubview:myWebView];
}
I want to load the local html file instead of loading url.How do i do that?.
and also i want to call the delegate method
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType,which is not being called.Any guidance is neatly appreciated.Thanks.
First of all,please go through the apple document before searching in google.I suggest you to go through the basic objective c programming concept.
In reference to UIWebView,i would like to tell you how to load the local html.
UIWebView *myWebView=[[UIWebView alloc]initWithFrame:CGRectMake(20, 20, 400, 400)];
NSString *indexPath = [NSBundle pathForResource:#"index" ofType:#"html" inDirectory:nil];
[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:indexPath]]];
[self.view addSubview:myWebView];
To call any delegate methods first implement the UIWebViewDelegate protocol in your class..i.e. in your interface's declaration like below…
#interface YourViewController : UIViewController<UIWebViewDelegate>
Then set your webview delegate to your class..ie.,next after you initialize your web view.
myWebView.delegate = self;
Hope it works…Happy Coding :-)
I am trying to learn Xcode by making a simple app.
But I been looking on the net for hours (days) and I cant figure it out how I make a button that open a UIWebView in another ViewController :S
first let me show you some code that I have ready:
I have a few Buttons om my main Storyboard that each are title some country codes like UK, CA and DK.
When I press one of those Buttons I have an IBAction like this:
- (IBAction)ButtonPressed:(UIButton *)sender {
// Google button pressed
NSURL* allURLS;
if([sender.titleLabel.text isEqualToString:#"DK"]) {
// Create URL obj
allURLS = [NSURL URLWithString:#"http://google.dk"];
}else if([sender.titleLabel.text isEqualToString:#"US"])
{
allURLS = [NSURL URLWithString:#"http://google.com"];
}else if([sender.titleLabel.text isEqualToString:#"CA"])
{
allURLS = [NSURL URLWithString:#"http://google.ca"];
}
NSURLRequest* req = [NSURLRequest requestWithURL:allURLS];
[myWebView loadRequest:req];
}
How do I make this open UIWebview on my other Viewcontroller named myWebView?
please help a lost man :D
Well, you've firstViewController already designed and coded, now you've to create secondViewController with a UIWebView binded in IB it self, also it have a setter NSString variable like strUrl that you need to pass at the time of pushing or presenting secondViewController, and assign it to UIWebView in viewDidLoad of secondViewController. See my answer about how to pass a NSString? Also UIWebView has its delegates method (What's delegate & datasource methods? - Apple Doc) Which you can use to handle URL request.
These are the delegate of UIWebView, if you'll going to use it, you need to give UIWebView delegate to self.
- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView *)webView;
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
firstViewController.m
- (IBAction)ButtonPressed:(UIButton *)sender {
NSURL* allURLS;
//get your URL
secondViewControlelr *secondView=[[secondViewControlelr alloc]init];
second.urlToLoad=allURLS;
[self.navigationController pushViewController:secondView animated:YES];
}
secondViewControlelr.h
//declare url and set property
NSURL *urlToLoad;
secondViewControlelr.m
- (void)viewDidLoad
{
myWebView=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:myWebView];
NSURLRequest *urlReq=[NSURLRequest requestWithURL:self.urlToLoad cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:10];
[myWebView loadRequest:urlReq];
}
I'm getting memory leaks that i can't figure out through leaks, build/analyze or overall inspection how to repair. I have a very strong notion that it's due to the loadRequest command from my UIWebview loading javascript, but I can't figure out what's wrong.
Here's my setup:
I have a tabbarcontroller that i programatically create with 4 view controllers: a table view, a mapview, another table view and a webview, respectively.
the 1st tableview shows static data.
the mapview shows annotations that when clicked populates a variable of the 4th tab, the webview, and switches to the webview to display a locally stored html/javascript file that is a 3d model
the 2nd tableview is a listing of all the same information each annotation in the mapview represents, just in table form. it has the same functionality in terms of populating the variable, switching and displaying the html/javascript file in the webview
the webview displays the html/javascript file loaded, if not it shows a UIAlertView to select one from the mapview or the list
when i finally get to executing the loadRequest() from the webview, initially everything works fine. however, when i begin to switch between tabs and view different 3d models (i.e. go to the map view click an annotation to show say model x, watch it load in the webview, then switch to the listing table and click a row to show model y (or x too) and watch it load in the webview) i start receiving memory leaks on the ipad, not the simulator. these memory leaks are almost always: General-Block 56, 1024, 8, 244 & 24 and have no responsible frames, libraries or stack traces to follow up with.
in the webview if i comment out the loadrequest line or do a loadrequest with the request object = nil, i have no memory leaks, but when i switch to using a url object that points to the local files (i even tried pointing it to google.com, which has javascript) it erupts in memory leaks.
i've attempted to do each of these:
[self.webView loadRequest:nil];
[self.webView loadHTMLString:#"" baseURL:nil];
[self.webView stopLoading];
in viewWillDisappear of my webViewController in attempt to completely clean out the webview for reuse in the future, but it doesn't seem to be doing much help. i've also attempted doing this prior to doing the loadRequest but i get the same memory leaks.
fyi, i'm running the latest xcode 4.0.2 and the ipad has the latest update, 4.3.2
from a previous post i commented on and haven't heard back from (general-block memory leak) i believe the problem has to do with the fact that webview doesn't know how to fully rid itself of the javascript when i switch views
i did a test with a simple html file with no javascript and the general-block memory leaks are gone. however, i get other cfnetwork / http message memory leaks but that's a different story and not of my concern at the moment.
below is example code of when one of the annotations on the mapView is clicked which triggers the loadModel function in the webViewController:
- (void) mapCallOutPressed: (UIView *) sender {
NSInteger selectedIndex = sender.tag;
MyLocation *selectedObject = [_mapView.annotations objectAtIndex:selectedIndex];
MyModel *model = selectedObject.model;
NSLog(#"Model selected from mapview = %#", model.description);
// Get reference to the webview from the tabBarController (viewController's index=3)
WebViewController *webViewController = [self.tabBarController.viewControllers objectAtIndex:3];
webViewController.model = model;
[webViewController loadModel];
// Switch tabs to the webView
self.tabBarController.selectedIndex = 3;
[self.tabBarController.selectedViewController viewDidAppear:YES];
below is my webViewController.h & .m:
WebViewController.h:
WebViewController : UIViewController <UIWebViewDelegate> {
UIWebView *webView;
NSString *templateRunFilePath;
MyModel *model;
NSString *templateRunTitle;
#property (nonatomic, retain) UIWebView *webView;
#property (assign) MyModel *model;
#property (nonatomic, copy) NSString *templateRunFilePath;
#property (nonatomic, copy) NSString *templateRunTitle;
-(void) loadModel;
WebViewController.m:
- (void) viewDidLoad {
[super viewDidLoad];
NSLog(#"in webview did load");
self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
self.webView.delegate = self;
self.webView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.webView.scalesPageToFit = YES;
[self.view addSubview:self.webView];
}
- (void) viewWillAppear:(BOOL)animated {
if (self.model) {
self.tabBarController.navigationItem.title = [NSString stringWithFormat: #"%# - %#", self.tabBarController.navigationItem.title, self.model.description];
}
else {
UIAlertView *msg = [[UIAlertView alloc] initWithTitle:#"No Model Selected"
message:#"Please select a model from the map or list tab to view."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[msg show];
[msg release];
}
}
- (void) loadModel {
NSString *localURLPath = [NSString stringWithFormat:#"%#/%#/%#", self.templateRunFilePath, self.model.folderName, self.model.modelFileName];
NSURL *url = [NSURL fileURLWithPath:localURLPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL: url];
[self.webView loadRequest:requestObj];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"WebKitCacheModelPreferenceKey"];
}
-(void)viewWillDisappear:(BOOL)animated {
NSLog(#"webview view will disappear");
[super viewWillDisappear:animated];
//[self.webView loadRequest:nil];
//[self.webView loadHTMLString:#"" baseURL:nil];
self.webView.delegate = nil;
}
- (void)dealloc {
self.webView.delegate = nil;
[self.webView release];
[super dealloc];
}
if you have any advice or corrections, i'd greatly appreciate it. i have < 1 week to figure this out and would highly thank you if you could give me any insight.
thanks!
-Mike
Mike, I am not sure whether you are doing following intentionally or by mistake?
- (void) loadModel {
[self.webView loadHTMLString:#"" baseURL:nil]; // here you are loading... or you have tried with commenting it also?
NSString *localURLPath = [NSString stringWithFormat:#"%#/%#/%#", self.templateRunFilePath, self.model.folderName, self.model.modelFileName];
NSURL *url = [NSURL fileURLWithPath:localURLPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL: url];
[self.webView loadRequest:requestObj]; // again here you are also loading?
}
Every time I load a new page with UIWebView the before loaded page is shown for a short time.
How can I clear that cache? Another possibility would be to dealloc UIWebview. I tried that but than my UIWebView is always "empty". How should the alloc and dealloc be done in this case?
I noticed that the UIWebView is consuming about 10 MB RAM. Now the UIWebView is loaded together with the ViewController. And the view is autoreleased as well as the UIWebView is autoreleased. Wouldn't it be better to dealloc the WebView each time?
Solution:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGRect frame = CGRectMake(0, 0, 320, 480);
self.webView = [[[UIWebView alloc]initWithFrame:frame] autorelease];
self.webView.scalesPageToFit = YES;
[self.view addSubview:self.webView];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.webView removeFromSuperview];
self.webView = nil;
}
I had nearly the same problem. I wanted the webview cache to be cleared, because everytime i reload a local webpage in an UIWebView, the old one is shown. So I found a solution by simply setting the cachePolicy property of the request. Use a NSMutableURLRequest to set this property. With all that everything works fine with reloading the UIWebView.
NSURL *url = [NSURL fileURLWithPath:MyHTMLFilePath];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[self.webView loadRequest:request];
Hope that helps!
My solution to this problem was to create the UIWebView programmatically on viewWillAppear: and to release it on viewDidDisappear:, like this:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.webView = [[[UIWebView alloc]initWithFrame:exampleFrame] autorelease];
self.webView.scalesPageToFit = YES;
self.webView.delegate = self;
self.webView.autoresizingMask = webViewBed.autoresizingMask;
[exampleView addSubview:self.webView];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.webView removeFromSuperview];
self.webView.delegate = nil;
self.webView = nil;
}
If you do this and your UIWebView doesn't get released you should check it's retain count and understand who is retaining it.
If you want to remove all cached responses, you may also want to try something like this:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
If I had to make a guess your property for webView is
#property (nonatomic, retain) IBOutlet UIWebView *webView;
Correct? The important part is the retain.
self.webView = [[UIWebView alloc]initWithFrame:frame];
The above code allocates a UIWebView (meaning retainCount = 1) and then adds it to self.webView, where it is retained again (retainCount = 2).
Change the code to the following, and your webView should be deallocated.
self.webView = [[[UIWebView alloc]initWithFrame:frame] autorelease];
addSubview: can only be called on UIViews.
//[self.navigationController addSubview:self.webView];
should be
[self.navigationController.view addSubview:self.webView];
I did something simpler, I just set the webView's alpha to 0 on loadRequest and 1 on webViewDidFinishLoad.
thewebview.alpha=0.0;
thewebview.backgroundColor=[UIColor whiteColor];
[thewebview loadRequest:[NSURLRequest requestWithURL:url(str)]];
and
- (void)webViewDidFinishLoad:(UIWebView *)webView {
thewebview.alpha=1.0;
}
(Actually I have a fade-in, as rendering f.ex. a PDF can take 1/5 seconds or so.)
You could also load #"about:blank" after the webview disappears, then it will be empty the next time you access it.
I have one view holding a list of videos(buttons which can be clicked, each hold a url) which currently bring up a new view which holds the UIWebview, the only problem is I cant pass the url to the webview depending on which button was clicked.
At the moment I just get an empty UIWebview.
How can the url string be passed to the webview so it can load the correct url for each button?
Regards
NSURL *videoURL = [NSURL URLWithString:#"http://..."];
[webView loadRequest:[NSURLRequest requestWithURL:videoURL]];
UPDATE:
In response to comment #3, here's what you can do:
This goes without saying, but keep a reference to the UIWebView instance in Browser
Add an NSString or NSURL #property to Browser
Pass the URL to the Browser instance right after init
In viewDidLoad:, call loadRequest:
So your code might look like this:
- (void)buttonClicked {
Browser *browser = [[Browser alloc] initWithNibName:nil bundle:nil];
browser.URL = [NSURL URLWithString:#"http..."];
[self presentModalViewController:browser animated:YES];
[browser release];
}
and in Browser's viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[webView loadRequest:[NSURLRequest requestWithURL:URL]];
}