ASOC & XCODE side bar

Hi, Im learning xcode/asoc
xcode 9.2, 10.12.6

I followed this post on stackoverflow
https://stackoverflow.com/questions/57384941/how-to-use-a-sidebar-with-applescript

I am getting this error
2019-08-31 15:23:58.063933-0500 Sidebar Test[38594] xxx3
2019-08-31 15:23:58.073116-0500 Sidebar Test[38594] *** -[AppDelegate tableViewSelectionDidChange:]: Can’t make «class ocid» id «data optr0000000000D189ADFF7F0000» into type Unicode text. (error -1700)

Thanks for the help!


script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
	property theWindow : missing value
	property arrayController : missing value
	property detailView : missing value
	
	on applicationWillFinishLaunching:aNotification
		-- Insert code here to initialize your application before any files are opened
		(* set up list of headers and lines for the side bar *)
		set sidebarList to {{title:"Header 1", isHeader:true}, {title:"Line 1", isHeader:false}, {title:"Header 2", isHeader:true}, {title:"Line 2", isHeader:false}, {title:"Line 3", isHeader:false}, {title:"Header 3", isHeader:true}, {title:"Line 4", isHeader:false}}
		arrayController's addObjects:sidebarList
	end applicationWillFinishLaunching:
	
	on applicationShouldTerminate:sender
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate:
	
	(* table view delegate emthods *)
	
	on tableView:tableView isGroupRow:row
		-- header rows are group rows
		set rowData to arrayController's arrangedObjects's objectAtIndex:row
		return rowData's isHeader
	end tableView:isGroupRow:
	
	on tableView:tableView shouldSelectRow:row
		-- don't want to select header rows
		set rowData to arrayController's arrangedObjects's objectAtIndex:row
		return not (rowData's isHeader)
	end tableView:shouldSelectRow:
	
	on tableView:tableView viewForTableColumn:column row:row
		-- header rows get a special look
		set aView to tableView's makeViewWithIdentifier:"tableItem" owner:me
		return aView
	end tableView:viewForTableColumn:row:
	
	on tableViewSelectionDidChange:aNotification
		(*
         This is method gets notified right after a selection is made. This is one of
         the places where you can change the detail view to show a the correct view for
         selected sidebar item. For demonstration purposes I'm just swapping out
         TextField views with the name of the sidebar item. Not to sophisticated,
         but it get the point across
         *)
		set tableView to aNotification's object
		set selectedRowIdx to (tableView's selectedRow) as integer
		set rowData to arrayController's arrangedObjects's objectAtIndex:selectedRowIdx
		set newLabel to current application's NSTextField's labelWithString:(rowData's title)
		set newLabel's translatesAutoresizingMaskIntoConstraints to false
        
		set detailSubviews to (detailView's subviews) as list
		if detailSubviews is not {} then
            log "xxx3"
			set oldLabel to item 1 of detailSubviews
            log "xx4 " 
			detailView's replaceSubview:oldLabel |with|:newLabel
		else
			detailView's addSubview:newLabel
		end if
		set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)
		set constraintY to newLabel's centerYAnchor's constraintEqualToAnchor:(detailView's centerYAnchor)
		constraintX's setActive:true
		constraintY's setActive:true
	end tableViewSelectionDidChange:
	
end script


I have also reviewed this post but could not follow.
https://macscripter.net/viewtopic.php?id=47017

I assume you were getting this error before you added the ‘log’ statements, and that it occurs right after you click on one of the sidebar items, correct?

The error means literally that xcode thinks you’re trying to convert an objective-c object (in this case, most likely a view) to a text string, but I can’t see where you might be doing that. Could you add a line right after the ‘log “xxx3”’ line that says “log detailSubviews” and see what output you get in Xcode’s console? should look like:

       if detailSubviews is not {} then
log "xxx3"
log detailSubviews
           set oldLabel to item 1 of detailSubviews
log "xx4 " 
           detailView's replaceSubview:oldLabel |with|:newLabel
       else
[...]

The new error message.
2019-09-01 15:40:47.859006-0500 Sidebar Test[91459] xxx3
2019-09-01 15:40:47.866507-0500 Sidebar Test[91459] *** -[AppDelegate tableViewSelectionDidChange:]: Can’t get subviews. (error -1728)

I think the detail view is setup exactly as described.
property detailView : missing value
Referencing outlet detailView - delegate for the array controller.

Thanks

This line is a little ambiguous:

There should be a separate (empty) view in the xib connected by a referencing outlet to the property ‘detailView’ in the appDelegate script (using the Delegate object on the left). Is that correct? I’m thinking it’s not connected right, because the 'subviews method should return (at worst) an empty NSArray if the view exists. The “can’t get subviews” makes me think that the property dtailView is unset at that point (still missing value, rather than a reference to a view).

I’ll also note that this error seems to come earlier in execution than the previous error (since we don’t see the ‘xxx3’ log item), even though we changed code that’s later. That’s a bit screwy, and makes me think you should clean and rebuild the project (menu: Project → Clean build folder). Might have some cobwebs gumming things up…

EDIT: sorry, you did get the ‘xxx3’ log. Are you sure you typed ‘detailSubviews’, and not ‘detail subviews’? Typos are an annoying fact of life.

It does appear to not be connected, but its not empty because it makes it into the if statement?
See the spelling as logged.

When I have the array controller selected
the connections inspector shows on
Referencing Outlets
array controller - Delegate
detailView - Delegate


So I removed detailView - Delegate from above.
added
with Detail View selected
connections inspector
Referencing Outlets
detailView - Delegate

Now it shows the first item clicked in the table fine…
but a second click on another item triggers an error

with **log detailSubviews enabled gives this error
2019-09-02 10:42:56.616243-0500 Sidebar Test[36215] (
“<NSTextField: 0x100432400>”


	on tableViewSelectionDidChange:aNotification
		(*
         This is method gets notified right after a selection is made. This is one of
         the places where you can change the detail view to show a the correct view for
         selected sidebar item. For demonstration purposes I'm just swapping out
         TextField views with the name of the sidebar item. Not to sophisticated,
         but it get the point across
         *)
        log "begin"
		set tableView to aNotification's object
		set selectedRowIdx to (tableView's selectedRow) as integer
		set rowData to arrayController's arrangedObjects's objectAtIndex:selectedRowIdx
		set newLabel to current application's NSTextField's labelWithString:(rowData's title)
		set newLabel's translatesAutoresizingMaskIntoConstraints to false    
		set detailSubviews to (detailView's subviews) as list
        log "XX2"
        log "detailView"
        log detailView
        log "XX3"
        
		if detailSubviews is not {} then
            log "xxx4"
            log "detailSubviews"
            --**log detailSubviews
            log "xxx5"
            log "oldLabel"
            set oldLabel to item 1 of detailSubviews as text

			detailView's replaceSubview:oldLabel |with|:newLabel
            log "xxx6"
            --log detailView's |class| ()
		else
			detailView's addSubview:newLabel
		end if
		
		set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)
		set constraintY to newLabel's centerYAnchor's constraintEqualToAnchor:(detailView's centerYAnchor)
		constraintX's setActive:true
		constraintY's setActive:true
	end tableViewSelectionDidChange:


The error
2019-09-02 10:36:12.568329-0500 Sidebar Test[35911] begin
2019-09-02 10:36:12.569843-0500 Sidebar Test[35911] XX2
2019-09-02 10:36:12.569919-0500 Sidebar Test[35911] detailView
2019-09-02 10:36:12.570022-0500 Sidebar Test[35911] <NSView: 0x608000120d20>
2019-09-02 10:36:12.570086-0500 Sidebar Test[35911] XX3
2019-09-02 10:36:15.932024-0500 Sidebar Test[35911] begin
2019-09-02 10:36:15.933153-0500 Sidebar Test[35911] XX2
2019-09-02 10:36:15.933222-0500 Sidebar Test[35911] detailView
2019-09-02 10:36:15.933292-0500 Sidebar Test[35911] <NSView: 0x608000120d20>
2019-09-02 10:36:15.933340-0500 Sidebar Test[35911] XX3
2019-09-02 10:36:15.933388-0500 Sidebar Test[35911] xxx4
2019-09-02 10:36:15.933433-0500 Sidebar Test[35911] detailSubviews
2019-09-02 10:36:15.933479-0500 Sidebar Test[35911] xxx5
2019-09-02 10:36:15.933524-0500 Sidebar Test[35911] oldLabel
2019-09-02 10:36:15.941657-0500 Sidebar Test[35911] *** -[AppDelegate tableViewSelectionDidChange:]: Can’t make «class ocid» id «data optr0000000000F2460001000000» into type text. (error -1700)

So I discovered I had changed as list to text during troubleshooting.
This line “set oldLabel to item 1 of detailSubviews as text”

now there is this error
2019-09-02 11:22:42.221201-0500 Sidebar Test[37870] *** -[AppDelegate tableViewSelectionDidChange:]: Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x60000067b900 “NSTextField:0x100683340.centerX”> and <NSLayoutXAxisAnchor:0x600000a6a3c0 “NSView:0x600000120aa0.centerX”> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That’s illegal. (error -10000)

I cleared then reset all to suggested constraints

Same result.

detailSubviews is a list of views. It cannot be coerced to text. Remove the coercion, it’s pointless anyway.

set oldLabel to item 1 of detailSubviews

This error is from this line:

       set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)

and it means that (for some reason we have yet to discover) the label we created (newLabel) has not been added as a subview of the view (detailView). The most likely explanation is that one of the three views involved (oldLabel, newLabel, or detailView) is nil. I’m suspecting it’s oldLabel, because the line where you set oldLabel has been giving you trouble (and if oldLabel is nil, the replaceSubview command won’t do anything). the code should look like this (with the log commands removed):

set newLabel to current application's NSTextField's labelWithString:(rowData's title)
set newLabel's translatesAutoresizingMaskIntoConstraints to false
set detailSubviews to (detailView's subviews) as list

if detailSubviews is not {} then
	set oldLabel to item 1 of detailSubviews
	detailView's replaceSubview:oldLabel |with|:newLabel
else
	detailView's addSubview:newLabel
end if

Note that in the ‘set oldLabel to…’ line I don’t try to do any coercions. ‘detailSubviews’ (at that point in the code) is an AppleScript list of objective-c view objects (objects that are the subviews of the ‘detailView’ view). We just want to pull out that first view object and replace it with our new object, without changing it in any other way.

It was the connection all along.
This code works!
Thanks!


script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
	property theWindow : missing value
	property arrayController : missing value
	property detailView : missing value
	
	on applicationWillFinishLaunching:aNotification
		-- Insert code here to initialize your application before any files are opened
		(* set up list of headers and lines for the side bar *)
		set sidebarList to {{title:"Header 1", isHeader:true}, {title:"Line 1", isHeader:false}, {title:"Header 2", isHeader:true}, {title:"Line 2", isHeader:false}, {title:"Line 3", isHeader:false}, {title:"Header 3", isHeader:true}, {title:"Line 4", isHeader:false}}
		arrayController's addObjects:sidebarList
	end applicationWillFinishLaunching:
	
	on applicationShouldTerminate:sender
		-- Insert code here to do any housekeeping before your application quits
		return current application's NSTerminateNow
	end applicationShouldTerminate:
	
	(* table view delegate emthods *)
	
	on tableView:tableView isGroupRow:row
		-- header rows are group rows
		set rowData to arrayController's arrangedObjects's objectAtIndex:row
		return rowData's isHeader
	end tableView:isGroupRow:
	
	on tableView:tableView shouldSelectRow:row
		-- don't want to select header rows
		set rowData to arrayController's arrangedObjects's objectAtIndex:row
		return not (rowData's isHeader)
	end tableView:shouldSelectRow:
	
	on tableView:tableView viewForTableColumn:column row:row
		-- header rows get a special look
		set aView to tableView's makeViewWithIdentifier:"tableItem" owner:me
		return aView
	end tableView:viewForTableColumn:row:
	
	on tableViewSelectionDidChange:aNotification
		(*
         This is method gets notified right after a selection is made. This is one of
         the places where you can change the detail view to show a the correct view for
         selected sidebar item. For demonstration purposes I'm just swapping out
         TextField views with the name of the sidebar item. Not to sophisticated,
         but it get the point across
         *)
		set tableView to aNotification's object
		set selectedRowIdx to (tableView's selectedRow) as integer
		set rowData to arrayController's arrangedObjects's objectAtIndex:selectedRowIdx
        set newLabel to current application's NSTextField's labelWithString:(rowData's title)
        set newLabel's translatesAutoresizingMaskIntoConstraints to false
        set detailSubviews to (detailView's subviews) as list
        
        if detailSubviews is not {} then
            set oldLabel to item 1 of detailSubviews
            detailView's replaceSubview:oldLabel |with|:newLabel
            else
            detailView's addSubview:newLabel
        end if
		
		set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)
		set constraintY to newLabel's centerYAnchor's constraintEqualToAnchor:(detailView's centerYAnchor)
		constraintX's setActive:true
		constraintY's setActive:true
	end tableViewSelectionDidChange:
	
end script