performSelectorOnMainThread return value...

This is other approach kind of question to return value from performSelectorOnMainThread…

I do not have any example yet but was reading on stackoverflow how it would be possible to
return values from performSelectorOnMainThread method. From the info I read from the forum
they apply to use NSMutableDictionary for withObject: parameter.

Anyone with more knowledge of this…

Here is the link:
https://stackoverflow.com/questions/3346100/iphone-performselectoronmainthread-with-return-value

I would be very happy if I could do something like that in ASObjC, any help would be wonderful.

Thanks


use scripting additions
use framework "Foundation"

on run
	set myDict to current application's NSMutableDictionary's dictionary()
	my performSelectorOnMainThread:"targetFunction:" withObject:myDict waitUntilDone:true
	log ((myDict's objectForKey:"Result") as text)
       --> Hello
end run

on targetFunction:theArg
	theArg's setObject:"Hello" forKey:"Result"
end targetFunction:

The parameter “withObject” is apparently passed byRef.

Wonderful @db123

I made something similar before I read your message. (thanks for your quick respond).

Here is the example I did, fill free to comment it…

use framework "Foundation"
use framework "AppKit"
use scripting additions

set arguments to current application's NSMutableDictionary's dictionary()

tell arguments
	its setObject:800 forKey:"width"
	its setObject:800 forKey:"height"
end tell

if my NSThread's isMainThread() as boolean then
	my performWindow:arguments
else
	my performSelectorOnMainThread:"performWindow:" withObject:arguments waitUntilDone:true
end if

return (arguments's objectForKey:"result")'s |description|() as text

on performWindow:arguments
	set {width, height} to {arguments's valueForKey:"width", arguments's valueForKey:"height"}
	set theWindow to createWindowWithRect(0, 0, width, height)
	theWindow's |center|()
	theWindow's makeKeyAndOrderFront:me
	tell arguments to its setObject:theWindow forKey:"result"
end performWindow:

on createWindowWithRect(x, y, width, height)
	set windowSize to current application's NSMakeRect(x, y, width, height)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer) + (current application's NSWindowStyleMaskMiniaturizable as integer) + (current application's NSWindowStyleMaskResizable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:true
	return theWindow
end createWindowWithRect

Do you know how to do the same for script object… ??

I call the script object with webLib : script “myScriptLib”

set theWindow to webLib’s myhandlerName

the problem here is… theWindow variable do not return anything.
but if I put all the code in same script it does… little confusing what going on…

Never mind I find a solution to use objectForKey to get my notification to work.

Here is the running script (applet)

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
use webLib : script "WKWebViewLib"

property domain : "https://www.google.com/search?q=site:developer.apple.com" & "%20"

set theDefaultAnswer to ""
set theString to (display dialog "Type the tag text from Apple Developer Documentation" default answer theDefaultAnswer)'s text returned
if theString is "false" then return -128

set theUnicodeString to (my stringWithURLPathEncoding:theString) as text
set theURL to domain & theUnicodeString
set theWebView to webLib's displayWebView:theURL windowSize:{900, 850}

set notificationCenter to current application's NSNotificationCenter's defaultCenter()
notificationCenter's addObserver:me selector:"windowWillClose:" |name|:"NSWindowWillCloseNotification" object:(theWebView's objectForKey:"window") -- or the NSWindow

on windowWillClose:param
	set theWindow to param's object
	my (notificationCenter's removeObserver:me |name|:"NSWindowWillCloseNotification" object:theWindow)
	tell me to quit
end windowWillClose:

on stringWithURLPathEncoding:theURL
	set escapedString to current application's NSString's stringWithString:theURL
	return (escapedString's stringByAddingPercentEncodingWithAllowedCharacters:(current application's NSCharacterSet's URLPathAllowedCharacterSet()))
end stringWithURLPathEncoding:

And here is the Script Library that I name WKWebViewLib

use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property theURL : missing value

(**
* [Class] WKWebView
* 	An object that displays interactive web content, such as for an in-app browser.
*
**
* set thePath to POSIX path of (path to desktop) & "AppleScript key codes.webarchive"
* set theURL to current application's |NSURL|'s fileURLWithPath:thePath
* set theURLString to theURL's absoluteString() as text
* my displayWebView:theURLString windowSize:{900, 900}
*)

on displayWebView:theURLString windowSize:theWindowSize
	set arguments to current application's NSMutableDictionary's dictionary()
	set {theWidth, theHeight} to theWindowSize
	tell arguments
		its setObject:theURLString forKey:"theURL"
		its setObject:theWidth forKey:"width"
		its setObject:theHeight forKey:"height"
	end tell
	
	if current application's NSThread's isMainThread() as boolean then
		my performWebView:arguments
	else
		my performSelectorOnMainThread:"performWebView:" withObject:arguments waitUntilDone:true
	end if
	
	return arguments
end displayWebView:windowSize:

on performWebView:arguments
	set {width, height} to {arguments's objectForKey:"width", arguments's objectForKey:"height"}
	set theURLString to (arguments's objectForKey:"theURL")
	set theWebView to createWebView(theURLString, width, height)
	
	set theWindow to createWindowWithRect(0, 0, width, height)
	theWindow's setContentView:theWebView
	
	set windowController to createWindowController(theWindow)
	windowController's showWindow:me
	windowController's |window|'s |center|()
	windowController's |window|'s makeKeyAndOrderFront:me
	
	tell arguments to its setObject:theWindow forKey:"window"
end performWebView:

on createWebView(theURLString, width, height)
	set theConfiguration to current application's WKWebViewConfiguration's alloc()'s init()
	set theFetch to my fetchJSSourceString(theURLString)
	set theUserScript to current application's WKUserScript's alloc()'s initWithSource:theFetch injectionTime:(current application's WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
	set theUserContentController to current application's WKUserContentController's alloc()'s init()
	theUserContentController's addUserScript:theUserScript
	theConfiguration's setUserContentController:theUserContentController
	
	set webViewSize to current application's NSMakeRect(0, 0, width, height)
	set webView to current application's WKWebView's alloc()'s initWithFrame:webViewSize configuration:theConfiguration
	webView's setNavigationDelegate:me
	webView's setUIDelegate:me
	webView's setTranslatesAutoresizingMaskIntoConstraints:true
	
	set theURL to current application's |NSURL|'s URLWithString:theURLString
	set theRequest to current application's NSURLRequest's requestWithURL:theURL
	webView's loadRequest:theRequest
	return webView
end createWebView

-- styleMask: title,close, miniaturizable and resizable
on createWindowWithRect(x, y, width, height)
	set windowSize to current application's NSMakeRect(x, y, width, height)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer) + (current application's NSWindowStyleMaskMiniaturizable as integer) + (current application's NSWindowStyleMaskResizable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:yes
	return theWindow
end createWindowWithRect

on createWindowController(theWindow)
	set theWindowController to current application's NSWindowController's alloc()'s initWithWindow:theWindow
	return theWindowController
end createWindowController

on fetchJSSourceString(theURLString)
	set theURL to current application's |NSURL|'s URLWithString:theURLString
	set theSource to current application's NSString's stringWithContentsOfURL:theURL encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
	return theSource
end fetchJSSourceString