Hello I am working on a web view based application, I have a WebController within that I have a variable which holds the current URL.
I have recently added code to launch a view, this works fine, this view also holds another web view, this web view works fine if I load a site into it such as this:
[[mywebview mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:
[#"http://www.google.com/search?hl=en&q=" stringByAppendingString:#"test"]]]];
However I am trying to access the variable which holds the current URL like this:
[[mywebview mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:
[#"http://www.google.com/search?hl=en&q=" stringByAppendingString:currentURL]]]];
However when doing this by linking to the WebController the currentURL seems to equal nothing, however this works perfectly fine when doing it from the first responder (except of course the view no longer shows)
My question is how can I get my currentURL variable working when linked from the WebController?
I am relatively new to cocoa so I am sorry if this is easy question!
EDIT: added from comments
In the method initWithWindowController currentURL is set to #"", and in dealloc to nil. The currentURL comes from the other web view see here:
- (void)webView:(WebView *)wv didStartProvisionalLoadForFrame:(WebFrame *)frame {
if (frame != [self.webView mainFrame])
return;
self.currentUrl = [[[[frame provisionalDataSource] request] URL] absoluteString];
[self retain];
}
I am declaring currentURL in the WebController.h
#interface WebController : NSObject <DOMEventListener>
{
IBOutlet NSString *currentURL;
}
#property (nonatomic, copy) IBOutlet NSString *currentURL;
#end
I am trying to use the currentURL in the WebController.m in the DisplayInView function.
-(IBAction) DisplayInView:(id) sender
{
if ([siteview isInFullScreenMode])
{
[siteview exitFullScreenModeWithOptions:nil];
}
else
{
[[mywebview mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: [#"google.com/search?hl=en&q="stringByAppendingString:currentURL]]]]; siteview enterFullScreenMode:[[siteview window] screen] withOptions:nil];
}
}
#synthesize siteview;
#end
I don't know if this is your problem, or a copy and paste error, but the code you posted is:
[#"google.com/search?hl=en&q="; stringByAppendingString:currentURL]]]];
It has a stray semicolon in the middle. That shouldn't even compile though.
Related
This is a Cocoa-component WebView. For example he called JS-function:
[webView stringByEvaluatingJavaScriptFromString:#"foo"];
I need to somehow wait until this function is executed and start doing another job. How this can be done on the Objective-C? I need something like:
[webView waitUntilJavaScriptCodeIsCompleted];
[webView stringByEvaluatingJavaScriptFromString:] is executed synchronously and will return an NSString of the result of executing the passed in script. So, if you just want to know that script has executed, call the function and when it returns, it has executed.
If, however, you're talking about a script with some sort of asynchronous execution, like an XMLHTTPRequest or setTimeout, then you're going to need to have your JavaScript call back into your Objective-C code to let it know when it's finished. Here is an example project that does just that. The most relevant parts are in AppDelegate:
#import "AppDelegate.h"
#import WebKit;
#import JavaScriptCore;
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#property (weak) IBOutlet WebView *webView;
#end
#interface AppDelegate (WebDelegate) <WebFrameLoadDelegate>
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
JSGlobalContextRef jsGlobalContext = _webView.mainFrame.globalContext;
// Add a function named "allDone" to the window object. It can be called from JavaScript like so:
JSContext* context = [JSContext contextWithJSGlobalContextRef:jsGlobalContext];
context[#"allDone"] = ^{
NSLog(#"All Done was called");
};
context[#"jsLog"] = ^(NSString* message) {
NSLog(#"JSLOG: %#", message);
};
_webView.frameLoadDelegate = self;
NSURL* url = [NSURL URLWithString:#"https://example.com"];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url];
[_webView.mainFrame loadRequest:req];
}
#end
#implementation AppDelegate (WebDelegate)
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
NSLog(#"Page loaded, calling JavaScript");
// Script that logs a message, and then invokes allDone after 2 seconds.
NSString* script =
#"jsLog('Script running');"
#"setTimeout(function() {\n"
#"jsLog('javascript timer fired, invoking allDone...');\n"
#"window.allDone();\n"
#"}, 2000);";
NSLog(#"Before stringByEvaluatingJavaScriptFromString");
[_webView stringByEvaluatingJavaScriptFromString:script];
NSLog(#"After stringByEvaluatingJavaScriptFromString");
}
#end
Which results in the following output:
Page loaded, calling JavaScript
Before stringByEvaluatingJavaScriptFromString
JSLOG: Script running
After stringByEvaluatingJavaScriptFromString
JSLOG: javascript timer fired, invoking allDone...
All Done was called
I'm probably not explaining this logically, as I'm new to Objective-C, but here I go...
I am writing an application in Objective-C that interacts with a WebView. Part of the app involves sharing an image via NSSharingService that is currently displayed in the WebView. Consequently, I have a method like this defined in my AppDelegate.m file:
#import "CCAppDelegate.h"
#import <WebKit/WebKit.h>
#import <AppKit/AppKit.h>
#implementation CCAppDelegate
-(void)shareFromMenu:(id)sender shareType:(NSString *)type{
NSString *string = [NSString stringWithFormat: #"window.function('%#')", type];
[self.webView stringByEvaluatingJavaScriptFromString: string];
}
#end
I then have a subclass of NSMenu, defined in CCShareMenu.m, which creates a menu of available sharing options:
#import "CCShareMenu.h"
#implementation CCShareMenu
- (void)awakeFromNib{
[self setDelegate:self];
}
- (IBAction)shareFromService:(id)sender {
NSLog(#"%#", [sender title]);
// [CCAppDelegate shareFromMenu];
}
- (void)menuWillOpen:(NSMenu *)menu{
[self removeAllItems];
NSArray *shareServicesForItems = #[
[NSSharingService sharingServiceNamed:NSSharingServiceNameComposeMessage],
[NSSharingService sharingServiceNamed:NSSharingServiceNameComposeEmail],
[NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook],
[NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnTwitter]
];
for (NSSharingService *service in shareServicesForItems) {
NSMenuItem *item = [[NSMenuItem alloc] init];
[item setRepresentedObject:service];
[item setImage:[service image]];
[item setTitle:[service title]];
[item setTarget:self];
[item setAction:#selector(shareFromService:)];
[self addItem:item];
}
}
#end
These methods both work fine on their own, except I need to call the shareFromMenu method from within the shareFromService IBAction.
I attempted moving the IBAction method to AppDelegate.m, then realized that made zero sense as the menuWillOpen-created selectors would never find the correct methods. Similarly, I tried following the instructions posted here, but:
[CCAppDelegate shareFromMenu];
Also responded with an error saying that the method was not found.
I realize I'm doing something fundamentally wrong here, so guidance would be appreciated.
-[CCAppDelegate shareFromMenu]
is different from
-[CCAppDelegate shareFromMenu:shareType:]
I would try adding the following to CCAppDelegate.h between #interface and #end:
-(void)shareFromMenu:(id)sender shareType:(NSString *)type
Then change your shareFromService: method to something like:
- (IBAction)shareFromService:(id)sender
{
NSString *shareType = #"Set your share type string here.";
CCAppDelegate *appDelegate = (CCAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate shareFromMenu:sender shareType:shareType];
}
-(void)shareFromMenu is a member method, but
[CCAppDelegate shareFromMenu]
is calling a class function which is not the correct way to call a member function.
You may try to get the CCAppDelegate instance and then call the function like this
CCAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate shareFromMenu];
I have a string of HTML that was parsed by libxml2.dylib that looks like:
Hello,<br />\n<br />\nThis is almost HTML.<br />\n<br />\n
I've unsuccessfully tried to display certain strings parsed from the XML in a WebView; I'm hoping there's a simple way to do it such as how an HTML page is displayed in my Cocoa application:
HTMLView.h
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#interface htmlView : NSObject {
IBOutlet WebView * webview;
}
-(IBAction) showHTML:(id) sender;
#end
HTMLView.m
#import "HTMLView.h"
#implementation htmlView
-(IBAction) showHTML:(id) sender
{
[[webview mainFrame] loadRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:#"http://www.example.com"]]];
NSString * string = #"<br>test</br>";
[self loadHTMLString:string baseURL:(NSURL *)baseURL];
}
-(void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL {
}
#end
try this... [[aWebView mainFrame] loadHTMLString:aString baseURL:nil];
I've unsuccessfully tried to display certain strings parsed from the XML in a WebView
How did you try to display the strings and what was the problem? I think
-(void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
Might be what you need...!?
Edit:
You have to call the method on your webview!
What you did now is implementing your own loadHTMLString method in your viewController. Which would be fine if it did anything and did call loadHTMLString on the webview at some point.
[self.webView loadHTMLString....]
I think you have to familiarise yourself a bit more with objective-c.
I have HTML I am generating in my app. I know it's valid because I ran it through W3Schools "edit and try it". It performs exactly as I designed it.
Here is the definition of the website in the header file:
#interface ReportViewController : UIViewController <UIWebViewDelegate> {
IBOutlet UIWebView *reportWebView;
}
#property (nonatomic, retain) UIWebView *reportWebView;
#property (nonatomic, retain) NSMutableString *html;
- (void) generateReport;
- (void) Alert: (NSString *) title andData: (NSString *) errorMsg;
#end
Here is where I finish creating the HTML and try to display it:
// now do the table
[html appendString:#"<div><table border class=\"boldtable\">"
"<tr BGCOLOR=\"ADDAFE\">"
"<th>STA </th><th>BS </th><th>HI </th><th>FS </th><th>ELEV </th><th>Desc</th>"
"</tr><p>"];
}
// finally, end the table, etc.
[html appendString:#"</table></div></body></html>"];
// UIWebView *reportWebView = [[UIWebView alloc] init];
//[reportWebView loadHTMLString: html baseURL:nil];
[self.reportWebView loadHTMLString:html baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
}
As you can see, I have tried several different variations of displaying the HTML string. What is the correct way to do this?
Iulius Caesar Jacques Cousteau gave the correct answer in a comment:
reportWebView is an IBOutlet, indicating that it's created in an xib. Is the outlet connected? Is the nib loaded? What's with the commented-out UIWebView *reportWebView = [[UIWebView alloc] init];? Is this your exact code? Are you creating a local variable reportWebView that's shadowing the ivar?
but never came back to set it, therefore I am answering it for him.
I've created a very simple Mac program to load a web page. It works and loads it well but I can't run events! Nothing is logged!
#import "BenotaAppDelegate.h"
#implementation BenotaAppDelegate
#synthesize webViewIns;
#synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSURL *url = [NSURL URLWithString:#"http://example.com"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[[webViewIns mainFrame] loadRequest:req];
}
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
NSLog(#"didFinishLoadForFrame");
}
#end
I can not use delegate right....
You need to set outlet frameLoadDelegatefrom your webView object to a class, that contains a method webView:didFinishLoadForFrame:
Just a note that my (iOS) app was rejected due:
non-public API/s in your app:
webView:didFinishLoadForFrame
You might want to reconsider your app, I definitely must find the 3rd party lib, which called that, and get rid of it. "It wasn't me!" is not a valid excuse :)