AppleScriptObjC Xcode app no doesn't work in Mojave

This app searches text file indexes of of file names on our servers and displays the results and an image preview where applicable. Exact file name is not needed, just a 3 character string within the file name. Any servers that are selected and not currently mounted are loaded. It’s worked perfectly until Mojave. It compiles with no errors, but on run it posts the following error in Xcode. The user interface just shows 0 files found even though there are definitely files. Any help on how to troubleshoot and resolve would be greatly appreciated.

*** -[AppDelegate loadTable:]: Can’t get version of class “NSObject”. (error -1728)

The index files are created with the following shell script and stored on a server.

find -s /Volumes/SeverName ! ( -ipath “/./" -prune -o -ipath ".app” -prune -o -ipath “/~snapshot/” -prune ) -type f -not -name “." -not -iname “thumbs.db” -not -iname ".exe” -not -iname “.dll" -not -iname ".cfg” -size +0 -print > “/Volumes/StorageServerName/Scripts & Apps/Support Files/artworkIndex.txt”

https://photos.google.com/search/_tra_/photo/AF1QipPfhknz-0uh7o3oDJOa0NNBlX28ELSMW_a6npdG

--
--  AppDelegate.applescript
--  fastFind
--
--  Created by mbebout on 7/30/14.
--  Copyright (c) 2014 ___HD Supply___. All rights reserved.
--

script AppDelegate
    property parent : class "NSObject"
    
    -- IBOutlets
    property |window| : missing value
    property NSBrowser : class "NSBrowser"
    property NSSearchField : class "NSSearchField"
    property NSImageWell : class "NSImageWell"
    property NSArray : class "NSArray"
    property theArrayController : missing value
    property searchTerm : ""
    property searchBox : ""
    property recentSearches : {}
    property checkArt : true
    property checkArtBackup : false
    property checkCatProd : false
    property checkDept : false
    property checkPublic : false
    property checkAtions : false
    property checkTransfer : false
    property checkWeb : false
    property searchAll : false
    property findEPS : false
    property findJPG : false
    property findTIF : false
    property findAI : false
    property findINDD : false
    property findPSD : false
    property findDOC : false
    property findPDF : false
    property findXLS : false
    property imageView : missing value
    property pathControl : missing value
    property filesFoundMessage : ""
    property theData : {}
    property theResults : {}
    property emptyList : {}
    property theFiles : missing value
    property theTable : missing value
    property isIdle : true -- bound property
    property shouldStop : false
    property sp : ASCII character 32 -- space
    property c : ASCII character 58 -- colon
    property r : ASCII character 13 -- return
    property q : ASCII character 34 -- quote
    property fs : ASCII character 47 -- forward slash /
    property artDrive : "artwork$" as string
    property depDrive : "department$" as string
    property pDrive : "public$" as string
    property pubDrive : "publications$" as string
    property tDrive : "transfer$" as string
    property webDrive : "webwork$" as string
    property artbackupDrive : "cifs://server-path-redacted/Artwork_Backup" as string
    property catProdDrive : "cifs://server-path-redacted/catalogproduction" as string
    property newerVersionMessage : ""
    
    
    -- required
    on applicationWillFinishLaunching_(aNotification)
        my checkVersion()
    end applicationWillFinishLaunching_
    
    on applicationShouldTerminate:sender
        -- Insert code here to do any housekeeping before your application quits
        return current application's NSTerminateNow
    end applicationShouldTerminate:
    
    on applicationShouldTerminateAfterLastWindowClosed:sender
        return True
    end applicationShouldTerminateAfterLastWindowClosed:
    
    on quitApp:sender
        current application's NSApp's terminate:me
    end quitApp:
    
    on clickNew:sender
        |window|'s makeKeyAndOrderFront:me
    end clickNew:
    
    on cancelPressed:sender
        set my shouldStop to true
    end cancelPressed:
    
    on openappFolder_(sender)
        set appPath to "/Volumes/department$/Scripts & Apps/Finder/" as string
        set openScript to "open " & Quoted form of appPath as string
        log openScript
        do shell script openScript
    end opensFolder_
    
    -- get checkbox value
    on clickedBox_(sender)
        checkArt as boolean
        checkArtBackup as boolean
        checkDept as boolean
        checkPublic as boolean
        checkAtions as boolean
        checkTransfer as boolean
        checkWeb as boolean
        checkCatProd as boolean
        searchAll as boolean
    end clickedBox_
    
    on checkVersion()
        set thisVersion to current application's version
        set serverAppPath to "/Volumes/Department$/Scripts & Apps/Finder/fastFind.app"
        set serverApp to application serverAppPath
        set serverVersion to version of serverApp
        if thisVersion < serverVersion then
            set my newerVersionMessage to "A newer version of fastFind is available."
        end if
        |window|'s displayIfNeeded()
    end checkVersion
    
    on loadTable:sender
        set shouldStop to false
        set my isIdle to false -- app is no longer idle
        -- clear preview
        imageView's setImage_(missing value)
        
        |window|'s displayIfNeeded()
        set searchTerm to searchBox as string
        copy searchTerm to origSearchTerm
        set termList to {}
        set AppleScript's text item delimiters to " "
        set termList to text items of origSearchTerm
        set AppleScript's text item delimiters to ""
        -- set origSearchTerm to my replaceText(origSearchTerm, " ", " & ")
        set grepTerm to my replaceText(searchTerm, " ", "*[[:alnum:][:punct:][:space:]]*")
        
        my mountDrives(depDrive)
        my checkVersion()
        tell theTable to setDoubleAction:"openFiles:"
        set my filesFoundMessage to (0 as string) & sp & "files found"
        set tempList to {}
        theArrayController's removeObjects:(theArrayController's arrangedObjects())
        theArrayController's addObjects:tempList
        
        
        set artIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/artworkIndex.txt\"" as string
        set artbackupIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/artworkBackupIndex.txt\"" as string
        set catProdIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/catalogproductionIndex.txt\"" as string
        set deptIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/departmentIndex.txt\"" as string
        set publicIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/publicIndex.txt\"" as string
        set ationsIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/publicationsIndex.txt\"" as string
        set transferIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/transferIndex.txt\"" as string
        set webIndex to "\"/Volumes/department$/Scripts & Apps/Support Files/webworkIndex.txt\"" as string


        set theIndices to ""
        
        -- set the servers to check, mount any missing servers
        -- ********(errors out on second run if you try to use a handler for this section, it breaks the index search list)********
        if checkArt or searchAll then
            set theIndices to artIndex  as string
            my mountDrives(artDrive)
        end if
        
        if checkArtBackup or searchAll then
            set theIndices to theIndices & sp & artbackupIndex as string
            my mountDrives(artbackupDrive)
        end if
        
        if checkCatProd or searchAll then
            set theIndices to theIndices & sp & catProdIndex as string
            my mountDrives(catProdDrive)
        end if
        
        if checkDept or searchAll then
            set theIndices to theIndices & sp & deptIndex as string
            my mountDrives(depDrive)
        end if
        if checkPublic or searchAll then
            set theIndices to theIndices & sp & publicIndex as string
            my mountDrives(pDrive)
        end if
        if checkAtions or searchAll then
            set theIndices to theIndices & sp & ationsIndex as string
            my mountDrives(pubDrive)
        end if
        if checkTransfer or searchAll then
            set theIndices to theIndices & sp & transferIndex as string
            my mountDrives(tDrive)
        end if
        
        if checkWeb or searchAll then
            set theIndices to theIndices & sp & webIndex as string
            my mountDrives(webDrive)
        end if
        
        
        if theIndices = "" then
            display alert "You need to pick at least one server to search!"
            return
        end if
        
        -- set the files types if selected
        set fileTypes to {}
        if findAI then
            set end of fileTypes to "ai" as string
        end if
        if findDOC then
            set end of fileTypes to "doc" as string
            set end of fileTypes to "docx" as string
            set end of fileTypes to "dot" as string
            set end of fileTypes to "dotx" as string
            set end of fileTypes to "dotm" as string
            set end of fileTypes to "docm" as string
        end if
        if findEPS then
            set end of fileTypes to "eps" as string
        end if
        if findINDD then
            set end of fileTypes to "indd" as string
        end if
        if findJPG then
            set end of fileTypes to "jpg" as string
        end if
        if findPDF then
            set end of fileTypes to "pdf" as string
        end if
        if findPSD then
            set end of fileTypes to "psd" as string
        end if
        if findTIF then
            set end of fileTypes to "tif" as string
        end if
        if findXLS then
            set end of fileTypes to "xls" as string
            set end of fileTypes to "xlsx" as string
            set end of fileTypes to "xltx" as string
            set end of fileTypes to "xlt" as string
            set end of fileTypes to "xlsm" as string
            set end of fileTypes to "xltm" as string
        end if
        
        --   log fileTypes
        if (grepTerm = missing value) or (count of characters of grepTerm < 3) then
            display alert "Please enter at least 3 letters or numbers for which to search."
            return
        end if
        --     global/regular expression/print, case insensitive, don't include the filename, search term, files to search
        -- this line works       set theShell to  "grep -i --no-filename " & q & grepTerm & q & space & theIndices as string
        --    set theShell to  "grep -i --no-filename " & (quoted form of grepTerm) & space & theIndices as string
        
        if (fileTypes = {}) then
            set theShell to  "grep -i --no-filename " & (quoted form of grepTerm) & space & theIndices as string
            else
            set finalGrep to ""
            if ((count of fileTypes) = 1) then
                set finalGrep to  "\\." & (item 1 of fileTypes as string) as string
                set finalGrep to quoted form of finalGrep
                set theShell to  "grep -E -i --no-filename " & (quoted form of grepTerm) & space & theIndices & " | grep -E -i --no-filename " &  finalGrep as string
                else
                if (count of fileTypes > 1) then
                    set initGrep to ""
                    repeat with i in fileTypes
                        set initGrep to (initGrep & "\\." & i & "|") as string
                    end repeat
                    set initGrep to (characters 1 thru -2 of initGrep) as string
                    set theShell to  "grep -E -i --no-filename " & (quoted form of initGrep) & space & theIndices & " | grep -E -i --no-filename " &  grepTerm as string
                end if
            end if
        end if
        
        
        --      log theShell
        try
            set initList to do shell script theShell without altering line endings
            --   log theList
            
            on error
            display alert "No files found or there was an issue with your search terms."
            set my filesFoundMessage to (0 as string) & sp & "files found"
            |window|'s displayIfNeeded()
            return
        end try
        
        script foo
        property theList : initList
        property finalList : {}
    end script
    
    if (foo's theList) ≠ "" then
        -- exclude hits that only match path not file name
        set aCount to (count of paragraphs of foo's theList) as integer
        set AppleScript's text item delimiters to ""
        set saveTID to AppleScript's text item delimiters
        set AppleScript's text item delimiters to {"/"}
        --       if (fileTypes = {}) then
        repeat with i from 1 to aCount
            doEventFetch()
            if shouldStop is true then exit repeat
            ignoring case, white space and punctuation
                if (last text item of paragraph i of (foo's theList) as string) contains (text items of termList) then
                    --         log paragraph i of theList
                    set theInfo to (info for (paragraph i of (foo's theList) as string))
                    set theSize to size of theInfo
                    set modDate to modification date of theInfo
                    set modDate to my makeNSDateFrom:modDate
                    set theKind to kind of theInfo
                    set end of (foo's finalList) to {fileName:(last text item of paragraph i of (foo's theList) as string), fileSize:theSize, fileDate:modDate, fileKind:theKind, filePath:paragraph i of (foo's theList)}
                    set theCount to (count of items of (foo's finalList))
                    set my filesFoundMessage to (theCount as string) & sp & "files found"
                    theArrayController's removeObjects:(theArrayController's arrangedObjects())
                    theArrayController's addObjects:(foo's finalList)
                    |window|'s displayIfNeeded()
                end if
            end ignoring
        end repeat
        set AppleScript's text item delimiters to saveTID
        end if
end loadTable:


on showPreview:sender
    set thisList to theArrayController's selectedObjects() as list
    set thePath to (filePath of item 1 of thisList)
    set theURL to  posix path of thePath
    set newImage to current application's NSImage's alloc()'s initWithContentsOfFile:theURL
    imageView's setImage_(newImage)
    |window|'s displayIfNeeded()
end showPreview:


on openFiles:sender
    set theFiles to theArrayController's selectedObjects() as list
    set fileCount to count of theFiles
    repeat with i from 1 to count of theFiles
        set j to (filePath of item i of theFiles)
        tell application "Finder"
            open (j as text) as POSIX file
        end tell
    end repeat
end openFiles:

on openFolder:sender
    set theFiles to theArrayController's selectedObjects() as list
    set fileCount to count of theFiles
    set AppleScript's text item delimiters to {"/"}
    repeat with i from 1 to count of theFiles
        set j to (filePath of item i of theFiles)
        set theFolder to text items 3 thru -2 of j as string
        set theFolder to my replaceText(theFolder, "/", ":")
        set theFolder to theFolder & ":"
        tell application "Finder"
            activate
            set theOne to (POSIX file j as text)
            reveal theOne
        end tell
    end repeat
    set AppleScript's text item delimiters to {""}
end openFolder:

on mountDrives(theDrive)
    set theDrives to list disks
    if theDrives does not contain theDrive then
        if (theDrive is not artbackupDrive) and (theDrive is not catProdDrive) and (theDrive is not artDrive) and (theDrive is not depDrive) and (theDrive is not pubDrive) then
            mount volume ("cifs://cscfiles01.hsi.hughessupply.com/" & theDrive) as string
        else if theDrive is artbackupDrive then
        mount volume ("cifs://server-path-redacted/Artwork_Backup") as string
        else
        mount volume ("cifs://server-path-redacted/" & theDrive) as string
        end if
    end if
end mountDrives

on sortAlpha(thisList)
    set AppleScript's text item delimiters to {ASCII character 10}
    set listString to thisList as string
    set newString to do shell script "echo " & quoted form of listString & " | sort -f"
    set newList to (paragraphs of newString)
    set AppleScript's text item delimiters to ""
    return newList
end sortAlpha

on replaceText(theText, searchString, replacementString)
    set cTID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to the searchString
    set the textList to every text item of theText
    set AppleScript's text item delimiters to the replacementString
    set theText to the textList as string
    set AppleScript's text item delimiters to cTID
    set theText to  theText  as string
    return theText
end replaceText


on makeNSDateFrom:theASDate
    -- get components of date
    set {theYear, theMonth, theDay, theSeconds} to theASDate's {year, month, day, time}
    if theYear < 0 then
        set theYear to -theYear
        set theEra to 0
        else
        set theEra to 1
    end if
    -- make new instance of NSDateComponents and set its properties
    set theComponents to current application's NSDateComponents's new()
    theComponents's setEra:theEra
    theComponents's setYear:theYear
    theComponents's setMonth:(theMonth as integer)
    theComponents's setDay:theDay
    theComponents's setSecond:theSeconds
    -- tell NSCalendar to build a date from the provided components
    set theNSDate to current application's NSCalendar's currentCalendar()'s dateFromComponents:theComponents
    (*
     In OS X 10.9, you do not need to make a new instance of NSDateComponents, instead using:
     set theCalendar to current application's NSCalendar's currentCalendar()
     set theNSDate to theCalendar's dateWithEra:theEra |year|:theYear |month|:(theMonth as integer) ¬
     |day|:theDay hour:0 minute:0 |second|:theSeconds nanosecond:0
     *)
    return theNSDate
end makeNSDateFrom:


on shortDate(theDate)
    set cTID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ""
    set mm to month of theDate as integer
    if mm < 10 then set mm to 0 & mm as string
    set dd to day of theDate as integer
    if dd < 10 then set dd to (0 & dd) as string
    set yy to year of theDate as string
    set yy to (characters 3 thru 4 of yy) as string
    set newDate to mm &  "/" & dd & "/" & yy as string
    set AppleScript's text item delimiters to cTID
    return newDate
end shortDate

on doEventFetch()
    repeat
        set theEvent to current application's NSApp's nextEventMatchingMask:(current application's NSUIntegerMax) untilDate:(missing value) inMode:(current application's NSEventTrackingRunLoopMode) dequeue:true
        if theEvent is missing value then
            exit repeat
            else
            tell current application's NSApp to sendEvent:theEvent
        end if
    end repeat
end doEventFetch


end script

Browser: Safari 537.36
Operating System: macOS 10.14

The only place I see you getting version is here:

set serverAppPath to "/Volumes/Department$/Scripts & Apps/Finder/fastFind.app"
set serverApp to application serverAppPath
set serverVersion to version of serverApp

I’m suprised that ever worked – building an AS target using the application keyword normally requires an HFS path, not a POSIX path.

Thank you - fixed that and the new error is

fastFind[74758:2816836] *** -[AppDelegate loadTable:]: unable to set argument 2 - the AppleScript value <NSAppleEventDescriptor: 'obj '{ ‘form’:‘usrp’, ‘want’:‘prop’, ‘seld’:‘utxt’(“NSUIntegerMax”), ‘from’:null() }> could not be coerced to type Q. (error -10000)

It’s still returning 0 files when I run it.

I’m not sure why you’re using NSUIntegerMax – you should be using NSAnyEventMask or NSEventMaskAny. Whatever, the problem is that in this case they are all outside AppleScript’s numerical range.

Define a property for NSEventMaskAny like this:

property NSEventMaskAny : 0

The value doesn’t matter. Add this to you applicationWillFinishLaunching: handler:

 set my NSEventMaskAny to current application's NSDecimalNumber's decimalNumberWithString:"18446744073709551615"

Then replace (current application’s NSUIntegerMax) with NSEventMaskAny.

That was it!! Thank you so much for all your help Shane