Passing Variables Between Windows and Populating Textfields

Hi Guys,

Was wondering if anyone can point me in the right direction with this please?
Ive been searching everywhere online to find the answer for about 3 days now with no luck.
I have experience with Applescript but not so much XCode linking in with Cocoa etc.

To give you a bit of history I have created this and working in Applescript using Pashua to create the dialog.
I want to migrate it to XCode for ease of building, debugging and to improve the look and feel of it.

What Do I want to Achieve:
I have 3 XIB files
When the app is launched it opens the Main Menu.
When a button is pressed it opens a dialog like box where a user can enter a number.
When they hit OK the number is then transferred to Window 3 and populates the textfield.
Then data is pulled out of a SQL DB based on the users number entry.

What am I struggling with:
I cannot get a setup section running at the start to pull down data from the SQL and to setup the variables (Issue 1 in the code)
Im having a hard time populating the Printer Info Window (Issue 2 in the Code)

I have the textfields and buttons all delegrated properly
Many Thanks for any help in advanced.


script AppDelegate
	property parent : class "NSObject"

on applicationWillFinishLaunching_(aNotification)
    -- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_

    --Main Menu Panel
        property MM_InternalEmail : missing value
        property MM_SiteName : missing value

    --Printer Info Panel Properties
        property PI_PrinterCode : missing value
        property PI_PrinterName : missing value
        property PI_PrinterSite : missing value
        property PI_FtpEmail : missing value
        property PI_FtpPassword : missing value

    --Printer Code Panel Properties
        property PC_PrinterCode : missing value

    --Windows
        property MainWindow : missing value
        property PrinterInfoWindow : missing value
        property PrinterCodeWindow : missing value

-- Issue 1
--Cannot get this to run on startup--
    -- Setup Enviroment
        set user to short user name of (system info)
        set currentDate to current date

    -- Setup Databases
        set head to "sqlite3 ~/desktop/data.db " & quote
        set databaseFilePath to (path to desktop as string) & "Log " & month of (current date) & " " & year of (current date) & ".txt"
        set {headlocal, pullData, thisFolder, siteName, localPass, internalMail} to my databaseSetup()
        log siteName
    
    -- Populate Main Menu
        MM_SiteName's setStringValue:siteName
        MM_InternalEmail's setStringValue:internalMail
  -- end of startup run
  
    on printerInfoButton_(Sender)
        -- Runs when the Printer Info button is pressed and opens the Enter Code Window
        current application's class "NSBundle"'s loadNibNamed_owner_("PrinterCodeEnter",sender)
    end printerInfoButton_

    on printerCodeOkButton_(Sender)
        -- Runs when the OK button is hit on the enter printer code window
        set printerCodeValue to PC_PrinterCode's stringValue() as text
        display dialog printerCodeValue - Works up to here
        tell PrinterCodeWindow to orderOut_(PrinterCodeWindow) -- Closes the Code window down
        current application's class "NSBundle"'s loadNibNamed_owner_("PrintInfoMenu",Sender) -- opens the info panel
--Issue 2
        PI_PrinterName's setStringValue:printerCodeValue -- Doesnt work
        --Error code: [AppDelegate printerCodeOkButton:]: missing value doesn't understand the "setStringValue_" message. (error -1708)
    end printerCodeOkButton_

end script


Model: Macbook Pro
AppleScript: Xcode 8.2.1
Browser: Firefox 50.0
Operating System: Mac OS X (10.10)

Hi paralysis

firstly you have not stated what version of OSX or Xcode you using.
This does matter if some one is going to help you.
I noticed your using the older AppleScriptObjC syntax, Like This below.


-- Older Syntax
on applicationWillFinishLaunching_(aNotification)

-- Newer Syntax
on applicationWillFinishLaunching:aNotification

This is not a problem, but does indicate an older version of OSX and Xcode.

Secondly on later OSX Xcode versions, you need to add the use scripting additions code at the top your script like this.


script AppDelegate

   use scripting additions

   property parent : class "NSObject"

This might be the reason your(current date) and (system info) code is not working.

lastly the line of code with the error message tells you exactly what the problem is.


PI_PrinterName's setStringValue:printerCodeValue -- Doesnt work
--Error code: [AppDelegate printerCodeOkButton:]: missing value doesn't understand the "setStringValue_" message. (error -1708)

It seems that PL_PrinterName has a value of “missing value”, so it cant accept messages.
I’m guessing that PL_PrinterName is a NSTextField in one of your nib files, so check you have the property connected to the Text Field properly, as PL_PrinterName needs to be able to accept the “setStringValue:” message.

One last point, you seem to be making the NSButtons that click your two button methods, the owners of the nib files.
This is a bit unorthodox, normally you would make the AppDelegate or another script class the owner of nib files, that way the owners can handle any delegate methods.

Regards Mark

No code just “runs” – you need to put it in a handler that gets called by something. So put the code you want to run at startup in the applicationWillFinishLaunching: handler, or add a similar applicationDidFinishLaunching: handler for it.

You can, but there’s no requirement to do so. Xcode-based project use their own framework-loading mechanism.

Just as diplomatic as ever Shane.

Don’t assume everyone is as expert as you.

Yes paralysis’s code is a bit of a mess, sorry paralysis.
But people learn with teaching, not with telling, end tell.

@ paralysis, Shane is correct, you should be doing your property and variable initialising from within the AppDelegate methods, your technique is OK in Script Editor, but not ideal in an AppleScriptObjC Xcode project

Let me expand…

I mean no code just runs in the sense that, unlike a typical script outside Xcode, there is no concept of a run handler.

A suggestion: unless you have a large number of windows, it’s easier to put them all in MainMenu.xib. It’s not the recommended way for Objective-C/Swift code, but it really does simplify things in typical ASObjC projects.

Hi Guys,

Apologies for the delay in message - I was away for the weekend.
Thanks everyone for the help! Theres a lot to read through haha

Apologies, I did have my XCode and OSX version in my message.
It was displayed at the bottom which I think is an auto thing from MacScripter.
I could have put it at the top manually I suppose.

This is correct, I have declared PI_PrinterName as a property at the top as ‘missing value’ (I was trying to follow some guides on this site and thats what the guide said to do) - Prob not fully applicable for what im trying to achieve

I’ll be honest Mark, and excuse my ignorance - Im not 100% certain what you mean or how I would go about that.
I understand Applescript as its own system but ive never really used XCode/Cocoa before so apologies for not understanding fully.

OK, so basically nothing can be outside a Handler if I want it to run.
Sorry im just still in the habit if Applescript running from top to bottom.
So with the applicationWillFinishLaunching - how does the script know to run that?
Is it based on the Handler name, as in its pre built into the code to run or so I need to specify somewhere to call that Handler?

Yeah I did think about that and did try originally to build them all in one NIB file, I couldnt figure out how to navigate between the windows. I dont think that this code was applicable for navigating between windows in the same NIB.
When I tried to assign a property to the separate windows it would of course assign the same property to all of them.

Thanks again guys.
I do appreciate all of your time.

It takes a bit of getting used to. In fact, in a normal script, any code outside any other handler is in an implied run handler anyway, so it’s not completely different.

You’ll see its name is AppDelegate. That means it’s the delegate object for the application, and there are a range of methods that the application will call on its delegate if it implements them; this is one of those. You can see them all by looking up NSApplicationDelegate.

Make seperate outlets for each window, turn off Visible at Launch for them, and then use makeKeyAndOrderFront: and orderOut: to show and hide them.

Excellent, Thank you.

I think my connections must have been off a little as I launched a new project and copied the settings from that to my mainwindow. I was then able to populate the text fields with the code I already had :slight_smile:

I took your advice with merging all of the panels into one it it does make it easier and makes more sense.

I just need to go through my code now as ive noticed that some parts of applescript dont work through XCode straight away - I did read somewhere online that you need to convert the class type so that objC understands it? Is that right?

Another question if you dont mind?
Ive got/had a local.db that would pull local settings specific to the app
For example, password, email address etc - This is to allow different settings for different users.
Is there a way I can store these variables permanently within the code as a property and allow the user to modify the property when the click save on the settngs? So when the app is launched again it brings up thier details for example?

Apart from that I think im there with everything.
Its just really understand how to really convert applescript (thats currently working in Script Editir) to XCode so that it can understand it.

Thanks agian

That’s a job for NSUserDefaults, which will save them in the app’s preferences file. You access it like this:

set defaults to current application's NSUserDefaults's standardUserDefaults()

You should set default values via a record/dictionary like this:

defaults's registerDefaults:defaultValuesRecord

And then you access them via a range of accessors, but mostly:

defaults's setObject:newValue forKey:"SomeKey"
set theValue to defaults's objectForKey:"SomeKey"

There are other accessors for different class types.

Perfect! Thanks Shane!
Im well away now! haha

Last question I promise lol - Just to save me opening up a new tab.
Ive created a PDF View section to show a preview of a PDF of course.

I have the viewer working and showing page 1.
I just can figure out how to display page 2 instead

        
pdfPreview's setDocument_(current application's class "PDFDocument"'s alloc's initWithURL_(current application's class "NSURL"'s fileURLWithPath_(posixPdfUpload))) -- Works fine
pdfPreview's setPDFPage_(2) --This is what ive tried

Is there anywhere online that shows what option commands are for XCode Applescript.
this link is for the PDFView class but I dont know how or if I can transpose that to applescript
https://developer.apple.com/reference/quartz/pdfview

Thanks again

The setPDFPage: method takes a PDFPage, not a number:

set pdfDoc to current application's PDFDocument's alloc()'s initWithURL:(current application's |NSURL|'s fileURLWithPath:posixPdfUpload)
pdfPreview's setDocument:pdfDoc
set thePage to pdfDoc's pageAtIndex:1 -- zero-based
pdfPreview's setPDFPage:thePage

I’m not sure why you’re using the underscored syntax rather than interleaved (colon-based) syntax. In any event, you’ll save your self a lot of pain in the long run if you use an external editor so you can check that your code compiles.

That’s all there is.

Again, thats great!
Thanks ever so much for your help.

I will leave you alone now haha!
Its been very educational.
Thanks again