Sunday, December 4, 2022

#1 2021-07-20 03:23:56 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 1090

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/334 … turn-value

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

Thanks


Node-RED makes it easy to automate IoT

Offline

 

#2 2021-07-20 03:42:28 am

db123
Member
Registered: 2020-12-07
Posts: 65

Re: performSelectorOnMainThread return value...

Applescript:


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.

Last edited by db123 (2021-07-20 03:58:35 am)

Offline

 

#3 2021-07-20 04:08:06 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 1090

Re: performSelectorOnMainThread return value...

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...

Applescript:

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

Last edited by Fredrik71 (2021-07-20 04:09:05 am)


Node-RED makes it easy to automate IoT

Offline

 

#4 2021-07-20 06:46:35 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 1090

Re: performSelectorOnMainThread return value...

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...


Node-RED makes it easy to automate IoT

Offline

 

#5 2021-07-20 08:07:14 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 1090

Re: performSelectorOnMainThread return value...

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

Here is the running script (applet)

Applescript:

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

Applescript:

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


Node-RED makes it easy to automate IoT

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)