Re: Creating NSTableView programmatically

2017-12-20 Thread Quincey Morris
On Dec 20, 2017, at 18:55 , Rob Petrovec  wrote:
> 
> Not for nothin', but I don’t think bindings have died.

So, let me respond jointly to all of the comments similar to this.

Of course bindings haven’t “died”, in the sense that no one *uses* them any 
more. My point was that bindings, as a conceptual software design paradigm or 
implementation framework for the general presentation or handling of data, 
don’t have much significance any more. We don’t sit down and *design* bindings 
for our apps, typically. We just bind things together when their values need to 
track each other. This should be understood as a simplification, not a denial 
that some people still get into them more deeply.

Consider also that there have been no functional improvements made to bindings 
since 10.5 (at least, I can’t think of even one), and that bindings were *not* 
taken over to iOS in 2008.

Of course, this is no rejection of KVO, which remains essential and creatively 
productive, despite being mechanically outdated.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Creating NSTableView programmatically

2017-12-20 Thread Rob Petrovec
Not for nothin', but I don’t think bindings have died. They are still supported 
and used all over the OS.  I use them all the time in my code too.  They are 
very useful.  Bindings are built onto of KVO, which is a fundamental technology.

—Rob


> On Dec 20, 2017, at 3:40 PM, Richard Charles  wrote:
> 
> 
>> On Dec 20, 2017, at 3:23 AM, Quincey Morris 
>>  wrote:
>> 
>> In effect, the whole thing with bindings died at 10.5, except for the part 
>> where they were used within IB to hook up specific controls to specific 
>> properties. That part is really all we use today.
> 
> It does seem like bindings died but I have found them very useful.
> 
> https://stackoverflow.com/questions/1169097/can-you-manually-implement-cocoa-bindings
> 
> https://www.tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/
> 
>> On Dec 20, 2017, at 3:07 PM, Charles Srstka  wrote:
>> 
>> I doubt I would have gone to the trouble of making it do that if I’d had to 
>> write the glue code manually.
> 
> For me it was a trade off. Do I invest time in learning bindings or become 
> really good at writing glue code. I suppose it would have worked either way 
> but for some reason I choose bindings.
> 
> --Richard Charles
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/petrock%40mac.com
> 
> This email sent to petr...@mac.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Creating NSTableView programmatically

2017-12-20 Thread Richard Charles

> On Dec 20, 2017, at 3:23 AM, Quincey Morris 
>  wrote:
> 
> In effect, the whole thing with bindings died at 10.5, except for the part 
> where they were used within IB to hook up specific controls to specific 
> properties. That part is really all we use today.

It does seem like bindings died but I have found them very useful.

https://stackoverflow.com/questions/1169097/can-you-manually-implement-cocoa-bindings

https://www.tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/

> On Dec 20, 2017, at 3:07 PM, Charles Srstka  wrote:
> 
> I doubt I would have gone to the trouble of making it do that if I’d had to 
> write the glue code manually.

For me it was a trade off. Do I invest time in learning bindings or become 
really good at writing glue code. I suppose it would have worked either way but 
for some reason I choose bindings.

--Richard Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Creating NSTableView programmatically

2017-12-20 Thread Charles Srstka
> On Dec 20, 2017, at 4:23 AM, Quincey Morris 
>  wrote:
> 
>> The original code used all the same three array controllers, with the exact 
>> same subclassing of the target's one.
> 
> This is where I take the fifth. 
> 
> When bindings were introduced, back in 10.3 or 10.4, then refined in 10.5, it 
> looked very much like Apple was trying to sell a sort of data-manipulation 
> “language” constructed out of bindings and NS…Controller classes. While this 
> worked great for pushing glue code out of .m source files and into .nib files 
> (this predated .xib files), it’s was too general, too inscrutable and too 
> clumsy to have much wider appeal. In effect, the whole thing with bindings 
> died at 10.5, except for the part where they were used within IB to hook up 
> specific controls to specific properties. That part is really all we use 
> today.

That’s going a little far, isn’t it? I still find bindings/KVO useful for a lot 
of cases where I want to keep things synced. For example, in Pacifist I have a 
main outline view, and a search results table on the side (currently in a 
drawer, although that’s changing in the currently-under-development Swift 
rewrite). The selected item in the search results and in the main outline view 
should always be the same, and I do that by setting things up, via a system of 
computed properties and keyPathsForValuesAffecting methods, so that the 
table’s selectionIndexes and the outline’s selectionIndexPaths are both 
essentially backed by the same underlying property. The result is that not only 
does it update the selection in the outline view when you change the selection 
in the search results, as you’d expect, but it also manages to update the 
selection in the *search results* if you select an item in the main outline 
view that happens to also be a search result. A big deal? No, but it’s one of 
those little details that makes an old Mac geek like me smile. ;-) I doubt I 
would have gone to the trouble of making it do that if I’d had to write the 
glue code manually.

Charles
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Creating NSTableView programmatically

2017-12-20 Thread Richard Charles

> On Dec 20, 2017, at 2:23 AM, Eric Matecki  wrote:
> 
> My project is based on what I believe is an official sample from Apple,
> which Richard Charles posted as an attachment to his msg from 12/12/2017.

It looks like you have taken your project from Malcolm Crawford's “Combatants” 
sample code. If I remember correctly Malcolm did work for Apple and was a one 
of the public experts on Cocoa bindings at the time. This sample code however 
is of his own making and did not come from Apple. In this sample code he does 
subclass NSArrayController and overrides the behavior of arrangeObjects: to 
exclude the selection (much to my surprise). This is very advanced stuff you 
are delving into.

Malcolm's sample code that really helped me was "Graphics Bindings” which was 
aligned with a major project I was working on. On this project I actually ended 
up subclassing NSArrayController because I could see no way around it but as 
Quincey Morris has indicated it was a very painful process.

But before delving into programmatic Cocoa bindings I must have spent a year 
with Aaron Hillegass in Cocoa Programming for Mac OS X. If you have a C++ 
background, Aaron will take you by the hand and lead you along a correct path. 
My current major project is for macOS and requires interoperability with C++ so 
I have yet to jump on the Swift or iOS bandwagon. Note that Cocoa Programming 
by Hillegass uses the Swift language starting with the 5th Edition and up.

I actually use OS X v10.9 documentation every day. It is old style, accurate, 
extremely usable, searchable, compact, and works well inside a web browser. I 
absolutely detest the new style documentation and find it almost unusable. 
Anyway that is what I do for documentation.

Good luck with your project.

--Richard Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Pasteboards and NSSecureCoding

2017-12-20 Thread Jeremy Hughes
Thanks for your detailed comments!

Something I’ve realised through this is that you need to be really careful 
about upgrading your system on a development machine. Going from 10.12 to 10.13 
- and finding that pasteboard functions compile just fine but no longer work - 
is almost as big a jump as going from Swift 3 to Swift 4.

I don’t think there's a non-hacky way to upgrade to a new system while 
continuing to use the previous SDK, but there should be! What I’d like is 
something similar to Swift transitions: Xcode could issue warnings and make 
similar helpful suggestions.

Jeremy

--

> On 20 Dec 2017, at 05:03, Quincey Morris 
>  wrote:
> 
> On Dec 19, 2017, at 18:32 , Jeremy Hughes  wrote:
>> 
>>> On 20 Dec 2017, at 02:22, Jeremy Hughes  wrote:
>>> 
>>> What I don’t like about [NSArray.self] is that it’s an artefact of 
>>> bridging. I’m not actually using it in the encoder:
>>> 
>>> coder.encode(arrayOfInts, forKey: kArrayKey)
>> 
>> The declaration:
>> 
>> encode(_ object: Any?, forKey key: String)
>> 
>> seems to indicate that it encodes any object
> 
> Yeah, you’re right, it’s secure on the decoding side only. 
> 
> This “encode” method is @objc, as I think you already noted, which AFAIK 
> means that if the value is an array, it’s going to be automatically bridged 
> to a NSArray. I would also expect it to become NSArray*, but I 
> can’t remember the rules, so I won’t go out on that limb. I also haven’t 
> looked at secure decoding recently, so I don’t know why or if the absence of 
> the element type matters when you’re securely decoding. It used to.
> 
> Note that the first parameter (“Any?”) doesn’t have to be an object in Swift, 
> although an object reference is required for the Obj-C method underneath. If 
> it’s a non-object in Swift, it’s actually passed as an opaque object that 
> wraps the Swift value.
> 
> After a while, you start to feel you need a ouija board to figure this stuff 
> out. As an alternative, if you are in control of both encoding and decoding, 
> and don’t need Obj-C compatibility inside the archive, you might do better to 
> use encode/decodeEncodable instead of encode/decodeObject. That takes type 
> bridging out of the picture, and trill preserves Swift types.
> 
> The last piece of this is that you should use one of the “decodeTopLevel…” 
> methods to decode the root object of your archive, for example 
> “decodeTopLevelDecodable(_:forKey:)”. This enables the relatively new — only 
> 5 years old! — failable decoding mechanism, where an error is thrown at the 
> top level if any of the decoding fails anywhere in the archive, 
> distinguishing failure from an init?(coder:) method that merely returns nil 
> to signify an optional value that isn’t present. (You use “failWithError” to 
> supply an error if you need to fail the decoding.)
> 
> Putting all that together, you can use NSKeyedArchiver/Unarchiver to encode 
> and decode more or less completely in the Swift domain (Codable), with proper 
> error handling and no obscure messing around with the types.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Creating NSTableView programmatically

2017-12-20 Thread Quincey Morris
On Dec 20, 2017, at 01:23 , Eric Matecki  wrote:
> 
> The sole purpose of my project is to learn how bindings works, it has no 
> practical application per se.

Bindings exist to support the use of NIB-based UI behavior. All bindings work 
the same way, in the sense that they tie together the values of properties in 
each of two objects, so that a change in one appears as a change in the other, 
in either direction. This sort of equivalent to mutual KVO-observation with 
mutual updating, except that only the property in the target object (the one 
bound *to*) is actually a property in the KVC sense. The “property” in the 
source object (the one bound *from*) is a notional identifier that may or may 
not correspond to a true property of the object.

For example, when binding the content of a NSTextView, you bind the “value” 
binding to a NSString property of some other object. There is no “value” 
property, the binding name is meaningful only as a binding name. That means 
that all of the binding names have to be documented somewhere, and that happens 
to be the Cocoa Bindings Reference document, which is a long list of classes 
and the bindings that have been defined to exist in each.

That tells you what any given binding is for (provided you can understand what 
the documentation says, which is more of a problem than it ought to be), but it 
doesn’t tell you when you should use the binding. That you kinda figure out by 
trial and error. You can figure out when you need to use the NSTextView “value” 
binding, for example, and you can probably figure out the font and point size 
bindings, but go look at the bindings for NSPopUpButton and you’re gonna be 
scratching your head.

> I wonder how IB manages conflicts when merging your code back to the main 
> branch

Ever since version  of Xcode, IB manages this by using a XIB 
file as the source code of a compiled NIB file, and a XIB file is text in some 
kind of XML format. That means it can be diff’ed and merged, hence managed via 
source control. You can see this yourself by switching the assistant editor to 
show the version history, and the main view will switch from a graphic canvas 
to a long, long text description.

> The original code used all the same three array controllers, with the exact 
> same subclassing of the target's one.

This is where I take the fifth. 

When bindings were introduced, back in 10.3 or 10.4, then refined in 10.5, it 
looked very much like Apple was trying to sell a sort of data-manipulation 
“language” constructed out of bindings and NS…Controller classes. While this 
worked great for pushing glue code out of .m source files and into .nib files 
(this predated .xib files), it’s was too general, too inscrutable and too 
clumsy to have much wider appeal. In effect, the whole thing with bindings died 
at 10.5, except for the part where they were used within IB to hook up specific 
controls to specific properties. That part is really all we use today.

This particular sample app comes from about the 10.4 era, ideologically if not 
actually. It illustrates how to do things no one really wanted to do after 
about 2005. Your current project is archeology, not development.

> In the sample I have, I can't find any binding involving "selectionIndexes", 
> neither in the code nor in the NIB.
> It still works without them.
> Or, more precisely, without them being *explicitly* bound somewhere, and 
> that's the kind of magic I hate.


Well, it’s not quite magic, but nearly. This *isn’t* documented anywhere, or 
(if it was) it was documented in an old version of the Table View Programming 
Guide that no longer exists.

In a NSCell-based table view (the only kind at the time this sample app was 
written), when you bind table columns to a property of an array controller, 
something (the table view? the NIB-loading mechanism? IDK exactly) notices that 
the table view is missing its “content” binding and binds it to the array 
controller. Then it also binds the “selectionIndexes” binding. Most people 
don’t explicitly know that, because it just works and so they don’t have to 
think about it. It’s only when something is arranged differently (like using a 
table view without an array controller, or … what you’re doing) that anyone 
notices.

This is one reason why we generally use XIB/NIB files instead of code — it 
allows us to let IB to worry about the magic, so we don’t have to. (FWIW, stuff 
like this is one reason why IB is huge, slow and buggy. Every tiny detail of 
every old NIB behavior in every macOS version has to be religiously preserved 
in IB.)

>   @property(readonly, copy) NSIndexSet *selectionIndexes;

> So I can change a readonly property thru bindings ?

It’s … um … not readonly. But the setter method looks like this:

> - (BOOL)setSelectionIndexes:(NSIndexSet *)indexes;

which is to say, it’s not exactly a setter because it returns a value. If, 
however, you squint and ignore the return value, it 

Re: Creating NSTableView programmatically

2017-12-20 Thread Eric Matecki

Hi,

Richard, I also reply to your msg here to avoid too much redundancy.
Thanks for your efforts.

My project is based on what I believe is an official sample from Apple,
which Richard Charles posted as an attachment to his msg from 12/12/2017.
The sole purpose of my project is to learn how bindings works, it has no 
practical application per se.
I just converted it from NIB based to code generated UI, as I'll have to create 
GUIs procedurally in the near future.
NIBs are all well if your app is something very static, but I can't see how it 
can handle very dynamic stuff,
with data structures you don't event know at the time you write your code.
It may be possible, because...
yes, I'm a beginner with Cocoa/obj-c, that's why I want to learn the 
'best'/'modern' way to use it,
as a lot of the available documentation (the ones I found) is outdated...

But sooner or later you'll have to port your software to another OS, no more 
NIBs.
At least code, while cumbersome, states everything that happens. No magic 
happening behind the scene.
Also code is much easier to version/fix conflicts.
I wonder how IB manages conflicts when merging your code back to the main branch (I didn't try it, I'm not yet that advanced with 
my exploration of Cocoa app writing... may Apple came out with some clever trick...)



When I select a row in a NSTableView, that selection doesn't "make it" all the 
way to update the controller...


I masochistically downloaded your project, and I think it’s a perfect example 
of why not to do this. There is so much glue code
that it's impossible to tell whether your code is any more than locally correct 
(that is, beyond whether each line of code does
what it purports to do). But all that aside…

— I think it’s a tragic mistake to subclass a NSArrayController. The class is a 
largely inscrutable black box of glue code, and
any code that you add is thrown into the black hole. (I admit this is only an 
opinion. Others may love this kind of self-inflicted
pain.)

— I think it’s *probably* a mistake to use NSArrayControllers *at all* in this 
project, where you’re trying to implement a
specific UI. A NSArrayController is a generalized collection of behaviors 
intended to be used to support a large generality of UI
designs in a NIB file. That level of generality isn’t necessary when you’re 
writing UI code directly, without using NIBs. It’s the
equivalent of using a dictionary with string keys to represent properties, 
instead of declaring the actual properties you want.

The original code used all the same three array controllers, with the exact 
same subclassing of the target's one.


— Your actual problem is that selection doesn’t work because you didn’t connect 
up the right pieces to make it work. For example,
I fixed it for the first table by adding one line of code in the “buildGUI” 
method:


[combatantsTable bind: @"content"  toObject: self.combatantsController  withKeyPath: 
@"arrangedObjects"  options: 0]; //
existing code
[combatantsTable bind: @"selectionIndexes" toObject: self.combatantsController 
withKeyPath: @"selectionIndexes" options: 0]; //
added code

So, where is this documented ?
Finding documentation is the biggest problem I face.
Reference docs are easy to find, but
(https://developer.apple.com/documentation/appkit/nsarraycontroller/1529908-selectionindexes?language=objc)

selectionIndexes
An index set containing the indexes of the receiver’s currently 
selected objects in the content array
Declaration
@property(readonly, copy) NSIndexSet *selectionIndexes;
Discussion
This property is observable using key-value observing.
"""
is of limited use... and it explicitly states KV-observable, not KV-coding 
compliant...

In the sample I have, I can't find any binding involving "selectionIndexes", 
neither in the code nor in the NIB.
It still works without them.
Or, more precisely, without them being *explicitly* bound somewhere, and that's 
the kind of magic I hate.
How should someone convert this to another API ?

So I can change a readonly property thru bindings ?
Whats the use of readonly if it's so easy to change ?
I guess this is just some more obj-c mystery that I'll eventually figure out...

Anyway, it works, so I'm somewhat happy...
Somewhat, because my goal was to understand how bindings work...
While it is logical to bind the selectionIndexes, I don't understand why it is 
readonly...
This readonly-ness is probably why I didn't even consider binding something to 
it,
it was just a 'source' of information in my mind, not a 'destination'.


IOW, the array controller doesn’t know what the current selection is unless you 
tell it. I didn’t try to fix any of the other
tables, but presumably they have the same problem.

Yes, they also work now.

>> printf("Targets::ArrangeObject()\n”);
> This smells like C++ which is okay but kind of looks like you need more 
practice with Objective-C.
Yes, I'm coming from a C++ background.
But in this precise