WebView loads slowly in Mac OS - macos

I have created plugin for Mail.app on Mac OS.
I'm using WebView to display web pages, all would be fine but web pages load slowly.
Then I created test cocoa application to compare loading time.
I was surprised when the test application loads page ~5 times faster.
In developer bar I saw my test application receives 304 code that indicates "the resource for the requested URL has not changed and cached resource can be used".
In contrast to the test application the plugin always receives 200 http code and loads resource again.
Maybe I should specify to use a cache in the webview, or I have some bundle permissions problems.
In the plugin, I tried to specify SharedURLCache like this
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024*20
diskCapacity:1024*1024*5
diskPath:NSHomeDirectory()];
[NSURLCache setSharedURLCache:cache];
Then I tried subscribe to the ResourceLoadDelegate on the WebView and change request object like this
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
if ([request cachePolicy] != NSURLRequestReturnCacheDataElseLoad)
{
return [NSURLRequest requestWithURL:[request URL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:[request timeoutInterval]];
} else {
return request;
}
}
Also I tried to change properties on WebView
[[webView preferences] setUsesPageCache:YES];
[[webView preferences] setCacheModel:WebCacheModelPrimaryWebBrowser];
but it's all not working.
Thanks for help.

Related

Has there been a change to the way Mac OSX Mavericks handles CFBundleURLName "Custom url" launches for applications?

I created an app which is launched from a custom url in any OSX browser. This worked just fine by adding a standard CFBundleURLName entry to the app's plist.
My application works by reading by parsing some of the parameters on the custom url and then reacting to them.
So for example with a custom url of:
foobar://param1/param2/param3
When clicking on the above url in a browser, OSX would launch my app and pass the actual custom url itself as the first argument to the app. Therefore in the app I could read the first arg and get the url the opened the app, and parse it for params I need.
This works fine in OSX 10.5-10.8, but in 10.9 Mavericks it appears to work slightly differently. Namely that if the application is not already running, it still launches the app but does not pass the custom url as first argument - so the app thinks it's just been launched manually by the user (such as selecting it from launchpad) rather than directly from a browser.
Weirdly, if the application is already open, then clicking the custom url DOES send the url string over to the app as first argument and functionality within the app occurs as expected.
I've tested this across 10.6->10.9 with new and old versions of my app and all exhibit the same behaviour. All work fine on first launch with versions before 10.9 Mavericks, but in 10.9 they don't get the url passed as first arg but then work on 2nd click once already running.
If anyone could shed some light on this I would be very grateful.
Where do you set up your URL handler? It needs to happen early. If you currently have it in applicationDidFinishLaunching, try to move it to applicationWillFinishLaunching.
The following works for me and logs the URL at launch even when the app is not running before I open the URL in Safari, for example. When I change WillFinishLaunching to DidFinishLaunching, I see exactly the behavior you describe.
#implementation AppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self andSelector:#selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
NSAppleEventDescriptor *obj = [event descriptorForKeyword:keyDirectObject];
DescType type = [obj descriptorType];
if (type == typeChar) {
NSData *data = [obj data];
if (data) {
NSString *urlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"url: %#", url);
}
}
}
#end

Catch mailto links in WebView

Is there a method to this madness? I am trying to build a browser app for a kiosk that restrict much need for running additional applications and simply stay within one website.
I research and found decidePolicyForNavigationAction should work for what I want, but how do I start filtering URI schemes (mailto://, irc://, etc.)? Thanks!
You're implementing a WebView in your application to browse the web, right?
If yes, look into the WebPolicyDelegate Protocol reference.
Especially the following delegate might be of interest:
- (void)webView:(WebView *)webView
decidePolicyForNewWindowAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
newFrameName:(NSString *)frameName
decisionListener:(id < WebPolicyDecisionListener >)listener
Using the above delegate, you can validate any request, including mailto requests.
Quick example how to detect the URL scheme and decide wether to block:
NSLog(#"Request URL scheme = %#",[[request URL] scheme]);
if([[[request URL] scheme]isEqualToString:#"mailto"])
{
[listener ignore]; // Block Request
}
else
{
[listener use]; // Allow Request
}

Memory continues to increase when loading images to Webview + Safari

I load HTML file which loads images using Javascript files to WebView. Every time when I load html file to Web view it shows me some memory increased in Activity Monitor. Even, when I release Webview then also it does not release the memory.
I am not caching the resources in Webview. But, when I used instruments to analyse the memory , it shows me images resources are cached in memory which does not get released.
I tried to load same HTML files in Safari browser, I found the same behavior.
Can anyone please guide me where I am missing? How can I optimize the memory loading to WebView?
Do not use Activity Monitor for profiling memory performance in your app.
Use the Instruments app and the various memory-related tools it provides, such as Allocations and Leaks. You will then be able to determine if your app is truly leaking.
More inputs how I try to avoid caching in WebView.
I am using below piece of code to remove caching.
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
WebPreferences *the_pPrefs = [m_pWebView preferences];
[the_pPrefs setCacheModel:WebCacheModelDocumentViewer];
[the_pPrefs setUsesPageCache:NO];
[m_pWebView setResourceLoadDelegate:self];
Even I handle resource load request in below delegate method.
- (NSURLRequest *)webView:(WebView *)sender
resource:(id)identifier
willSendRequest:(NSURLRequest *)aRequest
redirectResponse:(NSURLResponse *)redirectResponse
fromDataSource:(WebDataSource *)dataSource
{
NSURL * url = [aRequest URL];
NSURLRequest * cachelessRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:100];
return cachelessRequest;
}
I hope I doing the right things to avoid caching. Please give your thoughts for the same.

how to make web browser in Xcode load a web page automatically

I am building a web browser in Xcode cocoa application, using the interface builder. I have it all working when it comes to typing in web address and clicking go.
but I would like for it to automatically load a web page instead of seeing white when I open my project, I looked in inspector to see if you can set a specific web address but I couldn't find anything to do this.
How about if you load the URL that you would like in the viewdidload function:
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *targetURL = [NSURL fileURLWithPath:WebsitePath];
NSURLRequest *WebRequest = [NSURLRequest requestWithURL:targetURL];
[self.WebViewer loadRequest:WebRequest];
self.WebViewer.scalesPageToFit = YES;
}
Maybe you can try to load the WebView when the application finish launching,just add the URL Request in the applicationDidFinishLauching parameter,else if your WebView is on the MainView you can add a loadingScreen that appear while the webView is loading!
Lucky!

Using web view behind a proxy (cocoa)

I'm creating a web-browser type app (using a web view object) that needs to be able to connect to the internet via a proxy. Server, port, username and password can all be hardcoded into the app but unfortunately I have no idea how to customise the proxy settings of a web view without changing the system wide proxy settings.
If you know how to do this please provide some example code, thanks a lot!
(Also, if it changes anything - I'm developing for mac, not iPhone)
The easiest way I know is to wire up a UIWebView delegate and listen to all requests before they go through, and redirect the ones you care about through ASIHttpRequest and your custom proxy settings.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// Configure a proxy server manually
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:#"192.168.0.1"];
[request setProxyPort:3128];
// Alternatively, you can use a manually-specified Proxy Auto Config file (PAC)
// (It's probably best if you use a local file)
[request setPACurl:[NSURL URLWithString:#"file:///Users/ben/Desktop/test.pac"]];
// fire the request async
[request setDelegate:self];
[request startAsynchronous];
return NO;
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
// todo: save data to disk and load with [self webView]
}
It's a bit wonky,but it should work. Just remember to manage your memory properly and don't use this leaky example code... YMMV, I haven't even tested if this compiles, typed it all in the browser window with some copy and paste hackery.

Resources