Re: Creating NSTableView programmatically
On Dec 20, 2017, at 18:55 , Rob Petrovecwrote: > > 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
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 Charleswrote: > > >> 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
> 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
> 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
> On Dec 20, 2017, at 2:23 AM, Eric Mateckiwrote: > > 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
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
On Dec 20, 2017, at 01:23 , Eric Mateckiwrote: > > 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
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