Facebook like button not launching new window in Cocoa WebView - objective-c

I'm using a Cocoa WebView which loads an HTML page containing social media buttons. When I click the Facebook like button, no popup window is opened at all, however others such as Twitter and Google+ work fine and launch the popup window as expected.
That same HTML page works without issue in Safari.
I believe I've implemented my WebUIDelegate properly and can't think of what else might be causing this issue. Any ideas?
#pragma mark WebViewUIDelegate Methods
- (WebView *)webView:(WebView *) __unused sender createWebViewWithRequest:(NSURLRequest *)request
{
NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 400, 300) styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES];
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
WebView *webView = [[WebView alloc] init];
[webView setFrameLoadDelegate:self];
window.contentView = webView;
[webView.mainFrame loadRequest:request];
[_popupWindows addObject:window];
return webView;
}
- (WebView *)webView:(WebView *)sender createWebViewModalDialogWithRequest:(NSURLRequest *)request
{
return [self webView:sender createWebViewWithRequest:request];
}
- (void)webViewRunModal:(WebView *)sender
{
[sender.window makeKeyAndOrderFront:self];
}
- (void)webViewShow:(WebView *)sender
{
[sender.window makeKeyAndOrderFront:self];
}
- (void)webViewClose:(WebView *)sender
{
[_popupWindows removeObject:sender.window];
[sender.window close];
}

Apparently I need to call makeKeyAndOrderFront: in webView:createWebViewWithRequest: ... the example here https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DisplayWebContent/Tasks/MultipleWindows.html#//apple_ref/doc/uid/20002026-117294 implies that this is necessary (as openUntitledDocumentAndDisplay:error: will call makeKeyAndOrderFront:) while the documentation for webViewShow: seems to imply that showing the window should be its responsibility exclusively. Confusing. If anyone has a better explanation, it's welcome.

Related

Cocoa WebView doesn't respond to keyboard events

I'm making super-simple one-page browser in pure Objective-C, and everything is fine except the keyboard events. I just can't enter any data in webforms using keyboard! Mouse operations like pasting in webforms and clicking on links works, but typing in webforms doesn't!
code:
#import <WebKit/WebKit.h>
#interface MyWebView : WebView
{
}
#end
#implementation MyWebView
-(void)windowWillClose:(NSNotification *)notification
{
[NSApp terminate:self];
}
-(BOOL)becomeFirstResponder
{
printf("becomeFirstResponder\n"); // this message always appears
return YES;
}
-(void)keyDown:(NSEvent *)event
{
printf("keydown\n"); // this message never appears
// should I use this code to make keyboard work?
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
#end
int main(void) {
NSRect contentRect;
NSWindow *window = nil;
WebView *webView = nil;
NSString *urlForAuthentication = nil;
NSApp = [NSApplication sharedApplication];
contentRect = NSMakeRect(100, 100, 700, 700);
window = [[NSWindow alloc] initWithContentRect:contentRect styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO];
if (!window) {
printf("!window\n");
goto end;
}
webView = [[MyWebView alloc] initWithFrame:window.contentLayoutRect frameName:nil groupName:nil];
if (!webView) {
printf("!webView\n");
goto end;
}
urlForAuthentication = [[NSString alloc] initWithCString:(const char *)"https://yahoo.com" encoding:NSUTF8StringEncoding];
[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlForAuthentication]]];
window.contentView = webView;
window.delegate = (id)webView;
[window makeFirstResponder:webView];
[window makeKeyAndOrderFront:nil];
[window makeMainWindow];
if (!window.keyWindow)
printf("not keyWindow\n"); // this message always appears
if (!window.mainWindow)
printf("not mainWindow\n"); // this message always appears
[NSApp run];
end:
[urlForAuthentication release];
[webView release];
[window release];
[NSApp release];
return 0;
}
makefile:
CC=clang
FRAMEWORKS:=/System/Library/Frameworks/WebKit.framework/WebKit /System/Library/Frameworks/AppKit.framework/AppKit
LIBRARIES:=
WARNINGS=-Wall -Werror
SOURCE=app.m
CFLAGS=-g -v $(WARNINGS) $(SOURCE)
LDFLAGS=$(LIBRARIES) $(FRAMEWORKS) $(LINK_WITH)
OUT=-o app
all:
$(CC) $(CFLAGS) $(LDFLAGS) $(OUT)
What I'm doing wrong? I've read documentation and searched on SO for similar questions, but I couldn't find the solution. I tried to capture keyDown event, but it doesn't happens. I tried to make my window key and main, but seemingly unsuccessful.
To whom it may concern: place your executable 'abc' in folder 'abc.app/Contents/MacOS/', and it will finally work properly!
Edit: my colleague found out that this simple measure affects NSApplicationActivationPolicy. With this path, app's activationPolicy is 0 (NSApplicationActivationPolicyRegular). Without this path, app's activationPolicy is 2 (NSApplicationActivationPolicyProhibited).
Binary with some name should be placed inside "<Insert Name Here>.app" folder, which also should contain "Contents" folder. This way your executable pretends to be a bundled application for macOS.

How to enable pinch zoom on a Mac WebView?

I've already searched "everything" about this in Google/Stackoverflow, but I'm still stuck. I have just started developing OSX Apps, so I'm a (almost) complete newbie in Objective-C and Xcode 5 (5.0.2).
All I need is a simple webview to load a webgame from a given URL. This webview must behave just like a very simple Safari browser. My app is already working relatively well. It loads the game OK, and after a lot of struggling I succeeded making it show javascript alerts and confirms.
My task is now make the pinch zoom work. That's my appDelegate.M:
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize myWebView;
// Enables confirms:
- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSInteger result = NSRunInformationalAlertPanel(NSLocalizedString(#"Confirmação", #""), // title
message, // message
NSLocalizedString(#"OK", #""), // default button
NSLocalizedString(#"Cancelar", #""), // alt button
nil);
return NSAlertDefaultReturn == result;
}
// Enables alerts:
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:message];
[alert runModal];
//[alert release];
}
// This was supposed to enable pinch zoom:
- (void)magnifyWithEvent:(NSEvent *)event {
//[resultsField setStringValue:
//[NSString stringWithFormat:#"Magnification value is %f", [event magnification]]];
NSSize newSize;
newSize.height = [[NSScreen mainScreen] frame].size.height * ([event magnification] + 1.0);
newSize.width = [[NSScreen mainScreen] frame].size.width * ([event magnification] + 1.0);
//[self setFrameSize:newSize];
[myWebView setFrameSize:newSize];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
[self.window setContentView:self.myWebView];
[self.window toggleFullScreen:#""];
[myWebView setMainFrameURL:#"http://www.mywebgameurl.com"];
}
#end
Evidently, the code inside - (void)magnifyWithEvent:(NSEvent *)event is not working. The app builds and runs, but nothing happens when I pinch.
In other words, I need to enable the webview to zoom in and out using the trackpad pinch functionality. I've already developed a very similar webview in Android, and all I had to do was add webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);. I'm just looking for something like that. Any help is welcome, thanks!!
You just can't, Cocoa webviews doesnt have such control over pinch zoom functionality.

Generic "help" view which is accessible from all views in uinavigationView

Assuming an application has many views pushed to a uinavigationViewController, each view is different in content.
since the elements in the app are complex, I would like to show a small help view for specific views or elements in a specific view.
Imagine a "?" button that when pressed on will pop a new view in the center of the screen, playing youtube help video, or just a textual HTML loaded from a remote server.
Question: what is the best strategy for doing such a thing?
where should I place this code (App Delegate?)
if so, how would I call it from other views (with URL Parameter)
-(void)showHelpView:(NSString *)theURLString{
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
//webView.delegate= self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:theURLString]]];
[window addSubview:webView];
[window makeKeyAndVisible];
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
}
I'd prefer using pseudo-modal views. So that you create view every time, and add it on top of current window. I've used this approach for OAuth 2.0 authorisation popup in my last app.
Basically you create custom UIViewController subclass, provide custom initialisator, such as, for example:
// - (id) initWithURL: (URL*)url {
// ...
// self.url = url;
// ...
// return self;
PseudoModalViewController* pmvc = [[PseudoModalViewController alloc] initWithURL:#"http://www.google.com/"];
After you've created view you add it on top of current window:
UIWindow* window = [[UIApplication sharedApplication] keyWindow];
if(!window)
{
window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
}
[window addSubview:pmvc.view];
In, for example, viewDidLoad you load url obtained in initialisator:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
You may even design UI in Interface Builer for that. As a last piece I'd recommend add to include full screen transparent background view to ensure that all views below are disabled.
Oh, almost forgot, you hide that view with just a simple [self.view removeFromSuperview]. Don't forget to provide correct memory management for that view (i.e. release it in time, etc).

Cancel button/touch for UIWebView

I wonderd if there is any way to make the user dismiss the WebView window if he doesn't want it anymore on the screen...?
I looked at this post but i didn't understand it well.
How to cancel a UIWebView?
can anyone give me an example please?
This is the code i have:
CGSize webScreen1;
webScreen1 = [[UIScreen mainScreen] applicationFrame].size;
CGRect webFrame1 = CGRectMake((webScreen1.width/11.0) ,(webScreen1.height/19.0) ,webScreen1.width/1.2,webScreen1.height/1.25);
defaultWebView.frame = webFrame1;
self.defaultWebView = [[UIWebView alloc] initWithFrame:webFrame1];
self.defaultWebView.backgroundColor = [UIColor whiteColor];
self.defaultWebView.scalesPageToFit = YES;
self.defaultWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
defaultWebView.inputView.hidden = YES;
[self.view addSubview: self.defaultWebView];
[self.defaultWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:
[NSString stringWithFormat:(NSString *)#"%#", #"http://www.google.com"]]]];
Thanks!
There is no such thing as cancel a webView, what you need to do is remove the UIWebView from the parent view. If your UIWebView is a subview of self.view then you can provide a button named Close which behaves like this -
- (IBAction)closeWebView:(id)sender
{
[self.webView removeFromSuperView];
self.webView = nil;
return;
}
This should remove the webview from your view.
...way to make the user dismiss the WebView window...
[self.defaultWebView removeFromSuperview];
look I will explain what happenes in the post you attached above and you will understand the technique,
the UIWebview is a component which views an web page, it may be html or other types,
there is one way to hide your webview is to add an action in the html of the webview and ovveride the request in the code of your app,
when you click on link or ahref or any action on UIwebview there is a delegate method which automatically runs before continuing with the request
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
you can add a button or link on the html page and ovveride the request on this method
for example
Thing to click
and in the delegate method
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] absoluteString] isEqualToString:#"http://hideWebView/"]) {
[self.webview setHidden:YES];
return NO;
}
return YES;
}
here you ovveride the request http://hideWebView/ and in the delegate you searched for this request and then hiddes the web view or anything else you want to do

NSWindow windowDidResignKey not getting invoked after redisplaying window

I have a custom NSWindow subclass that the user can toggle the display of with the click of a button. I'd also like the window to disappear when the window resigns key status (e.g. by the user clicking outside the window).
I have a delegate that implements windowDidResignKey: but I find that this delegate method is only invoked the first time the window resigns key.
Here's how I toggle the display of the window (via user action or windowDidResignKey):
- (void) toggleWindowAtPoint:(NSPoint)point
{
// Attach/detach window.
if (!attachedWindow)
{
attachedWindow = [[CustomWindow alloc] attachedToPoint:point];
attachedWindow.delegate = self;
[attachedWindow setLevel:NSMainMenuWindowLevel+1]; // show window in front of all other apps on desktop
[attachedWindow makeKeyAndOrderFront:self];
}
else
{
attachedWindow.delegate = nil;
[attachedWindow orderOut:self];
[attachedWindow release];
attachedWindow = nil;
}
}
Here's my implementation of windowDidResignKey:
- (void) windowDidResignKey:(NSNotification *)note
{
[self toggleWindowAtPoint:NSMakePoint(0, 0)];
}
I'm finding that the first time the custom window is displayed, windowDidResignKey: gets called. Every time the custom window is re-displayed after that, windowDidResignKey: is not getting invoked.
The issue was that in some cases, the custom window was not actually becoming the key window after calling [attachedWindow makeKeyAndOrderFront:self].
I fixed this by adding the following line before re-creating the window:
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
In the context of the code snippet above:
- (void) toggleWindowAtPoint:(NSPoint)point
{
// Attach/detach window.
if (!attachedWindow)
{
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
attachedWindow = [[CustomWindow alloc] attachedToPoint:point];
....
Have you tried calling [attachedWindow makeFirstResponder:attachedWindow] in your toggle method?
If you want to activate a window without using activateIgnoringOtherApps: you should use a NSPanel with a NSNonactivatingPanelMask:
[[CustomPanel alloc]
initWithContentRect: NSZeroRect
styleMask: NSNonactivatingPanelMask
backing: NSBackingStoreBuffered
defer: NO];