Re: SOAP Server library/framework for Objective C

2015-09-11 Thread Nick
Yes, there's that and also a csoap library (written in C), now figuring
what would be a better way - either implement the SOAP part on top of the
CocoaHTTPServer or wrap the CSoap in Objective-C

2015-09-11 7:07 GMT+03:00 Jens Alfke :

> Well, CocoaHTTPServer is a general purpose HTTP server library. Then you
> can hook up a handler, use NSXML to parse, and then interpret that "Simple"
> SOAP schema :)
>
> —Jens
>
> On Sep 10, 2015, at 5:46 PM, Nick  wrote:
>
> Hi Jens,
> Yes, unfortunately there's client software that expects my app to work as
> SOAP server...
> I would surely use something different if I could.
>
> This is weird though. There are tons of SOAP client libraries and
> frameworks, and apparently none server ones...
>
> Looks like I will have to implement a soap server myself.
>
> As an option I am considering using Delphi (it supports development OS X,
> and has great out of box support for WebServices), but this is a "last
> resort".
>
> 2015-09-11 3:34 GMT+03:00 Jens Alfke :
>
>>
>> On Sep 10, 2015, at 4:25 PM, Nick  wrote:
>>
>> Basically I would like to have other client apps "talk" to my Mac
>> application using SOAP.
>>
>>
>> Do you have an existing dependency that requires using SOAP? Because
>> otherwise I’d recommend something more modern and, well, simple, like
>> WebSockets. SOAP was trendy about ten years ago but it’s really complex and
>> over-designed, and it seems like everyone got tired of it and went to REST
>> and JSON instead.
>>
>> PocketSocket is a pretty good WebSocket library for Cocoa that provides
>> both client and server code. The original developers don’t seem to be
>> maintaining it anymore (last commit was 11 months ago) but I have a fork
>> that I’m developing heavily for a product I work on.
>> https://github.com/couchbasedeps/PocketSocket
>>
>> —Jens
>>
>
>
___

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: SOAP Server library/framework for Objective C

2015-09-11 Thread Maxthon Chan
Plug: I am writing a general-purpose FastCGI framework, CGIKit, for 
Objective-C, and couple this to any FastCGI-capable Web server (nginx, Apache 
with mod_fcgid even IIS) you get a complete Web stack. Also CGIKit is more 
likely than not to be able to be ported to Linux.

CGIKit: https://github.com/xcvista/CGIKit

> On Sep 11, 2015, at 16:38, Nick  wrote:
> 
> Yes, there's that and also a csoap library (written in C), now figuring
> what would be a better way - either implement the SOAP part on top of the
> CocoaHTTPServer or wrap the CSoap in Objective-C
> 
> 2015-09-11 7:07 GMT+03:00 Jens Alfke :
> 
>> Well, CocoaHTTPServer is a general purpose HTTP server library. Then you
>> can hook up a handler, use NSXML to parse, and then interpret that "Simple"
>> SOAP schema :)
>> 
>> —Jens
>> 
>> On Sep 10, 2015, at 5:46 PM, Nick  wrote:
>> 
>> Hi Jens,
>> Yes, unfortunately there's client software that expects my app to work as
>> SOAP server...
>> I would surely use something different if I could.
>> 
>> This is weird though. There are tons of SOAP client libraries and
>> frameworks, and apparently none server ones...
>> 
>> Looks like I will have to implement a soap server myself.
>> 
>> As an option I am considering using Delphi (it supports development OS X,
>> and has great out of box support for WebServices), but this is a "last
>> resort".
>> 
>> 2015-09-11 3:34 GMT+03:00 Jens Alfke :
>> 
>>> 
>>> On Sep 10, 2015, at 4:25 PM, Nick  wrote:
>>> 
>>> Basically I would like to have other client apps "talk" to my Mac
>>> application using SOAP.
>>> 
>>> 
>>> Do you have an existing dependency that requires using SOAP? Because
>>> otherwise I’d recommend something more modern and, well, simple, like
>>> WebSockets. SOAP was trendy about ten years ago but it’s really complex and
>>> over-designed, and it seems like everyone got tired of it and went to REST
>>> and JSON instead.
>>> 
>>> PocketSocket is a pretty good WebSocket library for Cocoa that provides
>>> both client and server code. The original developers don’t seem to be
>>> maintaining it anymore (last commit was 11 months ago) but I have a fork
>>> that I’m developing heavily for a product I work on.
>>> https://github.com/couchbasedeps/PocketSocket
>>> 
>>> —Jens
>>> 
>> 
>> 
> ___
> 
> 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/max%40maxchan.info
> 
> This email sent to m...@maxchan.info



smime.p7s
Description: S/MIME cryptographic signature
___

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

Detecting second launch of the "LSUIElement=1"-application

2015-09-11 Thread Nick
Hello
Can I somehow detect that my application has been launched again, when it
is already running (it has an icon in NSStatusBar, but no icon in Dock)?

I need to display a specific window when this happens.

Thank you
Nick
___

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: Detecting second launch of the "LSUIElement=1"-application

2015-09-11 Thread Jens Alfke

> On Sep 11, 2015, at 1:12 PM, Nick  wrote:
> 
> Can I somehow detect that my application has been launched again, when it
> is already running (it has an icon in NSStatusBar, but no icon in Dock)?

The usual way is to implement the NSApplication delegate method 
-applicationShouldHandleReopen:hasVisibleWindows: … but I have no idea if that 
works in an LSUIElement app. It’s worth a try.

—Jens
___

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: Detecting second launch of the "LSUIElement=1"-application

2015-09-11 Thread Nick
Thanks Jens, it does work.
I should've looked at the delegate reference before asking.

2015-09-11 23:54 GMT+03:00 Jens Alfke :

>
> On Sep 11, 2015, at 1:12 PM, Nick  wrote:
>
> Can I somehow detect that my application has been launched again, when it
> is already running (it has an icon in NSStatusBar, but no icon in Dock)?
>
>
> The usual way is to implement the NSApplication delegate method
> -applicationShouldHandleReopen:hasVisibleWindows: … but I have no idea if
> that works in an LSUIElement app. It’s worth a try.
>
> —Jens
>
___

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: Basics of Cocoa Bindings

2015-09-11 Thread Quincey Morris
(ugh, reposted due to size moderation, again)

On Sep 11, 2015, at 13:40 , Alex Hall  wrote:

> What I've done so far is set things up, but not gotten the app to run. At 
> first, I was getting some odd errors, but I eventually realized that 
> populating my tweetsArray object in viewDidLoad was a bad idea, so now I do 
> that in the property declaration:
>   dynamic var tweetsArray:[Tweet]=[Tweet(text:"tweet 11"), 
> Tweet(text:"tweet 12”)]

You’ve *still* got a conceptual problem, but this one is about KVC, not 
bindings. KVC deals with properties which are values identified by *name* (key) 
within classes. There are scalar (one-to-one) properties — simple values — and 
collection (one-to-many) properties — multiple values which are isolated by 
(say) a numeric index.

In theory, there can be an “array” property, but that would be a scalar 
property whose single value happened to be a NSArray. Given the other details 
of KVC’s machinery, trying to use such an array property is a nightmare you 
don’t want to be stuck in. What you want, and what you really have, is an 
indexed collection of tweets, and you need to stop thinking of the property as 
an array — even though the backing store may have type [Tweet] and the KVC 
machinery accesses the collection via the NSArray class-cluster API — but not 
necessarily actual arrays (sometimes it uses proxy objects that refer to actual 
arrays, but that’s another discussion). Indeed, you should call your property 
“tweets”, not “tweetsArray”.

The internal magic of KVC is such that it provides a standardized mechanism of 
translating between property names (for a given class) and methods (of the 
class) the produce the actual values. Such methods are called accessors, and 
the method (naming) requirements depend on the kind of properties.

For scalar properties, there are two accessor methods: a getter and a setter 
(xxx and setXxx:, for a property named “xxx”). For indexed collection 
properties, there are about 8 different accessor methods, but you usually 
implement only a minimum required subset (of 2 accessors, one for inserting and 
one for removing). All the rest of the accessors default to standardized 
behavior and/or translate themselves into your custom accessors.

> As to my controller and bindings:
> 
> array controller:
> * content array: view controller.tweetsArray (which again, is dynamic); 
> controller key is empty

Correct, though as I said, you’re doing nothing but creating confusion by 
calling this “tweetsArray” rather than “tweets”, in your data model.

> * Content Array For Multiple Selection: View Controller.tweetsArray (though I 
> don't need this, as I've disable multiple selection in my table)

Don’t need. Leave it alone and let the binding provide default behavior.

> * Selection Indexes: controller to bind to is View Controller, but I don't 
> know what to put for a key path here. This is a property of the array 
> controller itself, not anything it needs to get anywhere else, so I don't 
> quite know why this field is here. Unless it's observing itself?

Don’t need, probably. If your view controller wants to have it’s own “mirror” 
of the selection that the array controller maintains, you can give it a 
suitable property, bind it here, and it will reflect the selection through the 
magic of bindings. There’s actually nothing interesting going on here, it’s 
just a piece of array controller convenience functionality.

> * Managed Object Context: same as Selection Indexes. I'm not quite sure what 
> to put for values here.

Don’t need. This is for Core Data, and absolutely nothing else.

> Table View:
> * Content: array controller.arrangedObjects

Correct.

> * Selection Indexes: Array Controller.selectionIndexes
> * Sort Descriptors: Array Controller.sortDescriptors

Don’t really need. IIRC table views establish these particular bindings by 
default, if you don’t. You only ever set these manually if you’re bindings 
targets are non-standard. But what you’ve done isn’t wrong.

> Cell text field: this one's odd, because I thought the controller was 
> supposed to be TableCellViewController, but that's not in the popup list of 
> available options.
> * Value: Array Controller.selection.displayText (recall that displayText is a 
> string property of the Tweet objects of which tweetsArray is full)

Nope. A table cell is a placeholder, since it obviously has to be different at 
every row. If you bind subviews to a particular target, all rows will show the 
same thing, and that’s not what you want.

Generally, you bind a subview’s value to TableViewCell (which *should* be in 
the popup), and use a model key of “objectValue.something”. In this case, it 
sounds like it should be “objectValue.displayText”.

There’s a completely separate piece of table view machinery that ensures the 
“objectValue”, for each table cell, contains a reference to the correct tweet 
for its row. This can itself be a binding, a default table behavior, or it can 

Looking for cocoa developer

2015-09-11 Thread den...@colorgradingcentral.com
We are looking for a passionate OS X software engineer 
to work on digital imaging products.

Particularly we are looking for someone with experience in
developing graphical user interfaces for digital imaging or 
video systems using Cocoa/Objective-C/C++/OpenGL.

If you or someone you know might be interested please
reply to:

j...@colorgradingcentral.com 

Cheers,
Denver Riddle
Color Grading Central
den...@colorgradingcentral.com
skype: denverkriddle


___

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: Basics of Cocoa Bindings

2015-09-11 Thread Quincey Morris
On Sep 11, 2015, at 15:49 , Alex Hall  wrote:
> 
> I followed all of that, and I see what you're saying. The binding to an array 
> is, to it, no different than binding to a boolean or a string, it's just a 
> single object. But how does a binding know what it's accessing? I figured it 
> was down to the type of object being bound to; bind to an array, and you've 
> got a 1-to-many, bind to, say, an integer, and you've got a 1-to-1. It sounds 
> like it's more in what methods the view controller (in my case) implements.

It’s all about context. Each UI element (KVC “client”) knows what kind of 
relationship it’s expecting. A text field needs a scalar value, so it expects a 
one-to-one relationship to be named by the property. A table view needs row 
data, so it expects an indexed one-to-many relationship.

When a client asks for information via KVC, the message that gets sent may or 
may not be specific to a particular kind of relationship. So you actually have 
to start breaking things down into cases.

For a text field that wants to retrieve a model value (a scalar), it uses the 
KVC method ‘valueForKey:’ (or possibly ‘valueForKeyPath:’, which is a 
convenience method in KVC that breaks a key path into individual keys, and 
invokes ‘valueForKey:’ sequentially). KVC figures out how to retrieve the 
value, and does things like transforming a numeric property value into a 
NSNumber object, since everything has to be an object for KVC.

For a table view that wants to retrieve (say) the tweet for row 20 of the 
table, it uses the KVC method … surprise! … ‘valueForKey:’, with “tweets” as 
the key. The object that KVC returns is — conceptually — an array *proxy* 
object. That is, it’s an Apple-provided object that responds to all of the 
NSArray behavior, but knows how to translate each NSArray method into an access 
to the real array that’s backing the property — or the various custom accessors 
that provide values, if  there’s no real array.

So the table view ends up with a NSArray-like object, and it can use 
‘objectAtIndex: 19’ to find the object in the 20th row. The reason there’s a 
proxy involved here is to allow the model class to avoid *constructing* an 
array to return (a potentially expensive operation), while letting the client 
use the full power of the full NSArray API. That’s why, if the table view wants 
to know the number of rows, it’s going to send a ‘count’ message rather than a 
‘countOfTweets’ method.

In short, KVC has leveraged the existing complexity of the NSArray class API to 
provide a rich choice of ways to access indexed one-to-many property values, 
without having to re-invent an entirely new set of analogous API methods.

Things are a little more complicated for changing values in the model instead 
of retrieving them. For scalars — that is, in contexts where the client needs a 
one-to-one property, the KVC method it calls is ‘setValue:forKey:’. This 
usually gets translated into a 'setXxx:’ method invocation, the accessor you 
expect. It’s worth noting that if this setter is the *only* way that the 
property way can be changed, then you get automatic KVO compliance for the  
property, which is a Good Thing™.

If a table view needs to modify (say) the tweet for row 20, it does *not* use 
‘setValue:forKey:’. Functionally, it *could* do that, and KVC would do the 
right thing, but that would require the table view to construct an entire array 
of tweets, which is horribly expensive. Instead, it would really like to use 
something like a proxy object, so that the elements that are unchanged don’t 
cost anything to keep unchanged. This is exactly what happens. The table view 
calls ‘mutableArrayValueForKey:’ to get what’s called a “mutable proxy”. As 
retrieved, it represents the current model values using the NSMutableArray API, 
so it allows the table view to use the ‘replaceObjectAtIndex:withObject:’ on 
the proxy to make just that simple update.

The other cool thing that the mutable proxy does is modify the data model in a 
KVO compliant way. It does this by translating the NSArray API method into a 
series of invocations of your custom accessor methods (such as the insert… and 
remove… methods). As with one-to-one properties, if you always modify a 
one-to-many property via the mutable proxy, then the property is automatically 
KVO compliant.

It should be clear, if you think about this, why you want to avoid using 
NSArray-valued one-to-one properties. KVC and its clients can’t tell the 
difference between this (the value is an object which happens to an NSArray 
subclass) and one-to-many properties (the values are the contents of the proxy 
objects, not the proxy objects themselves). Doing the wrong thing with the 
object as value vs. the object as temporary packaging is going to wreck your 
application logic pretty fast.

Now, for one-to-many properties, there’s another wrinkle. When getting values, 
since the proxy is read-only, if you have an actual array as backing store,

Re: Basics of Cocoa Bindings

2015-09-11 Thread Quincey Morris
(continued from part 1)

On Sep 11, 2015, at 15:49 , Alex Hall mailto:mehg...@icloud.com>> wrote:
> 
> Out of curiosity, why do I not need these but I *do* need insert and remove 
> methods for the property?

All standard UI elements use KVC to retrieve their values, or use bindings 
which uses KVC to retrieve its values.

(This, incidentally, is why bindings have a to and a from even though they’re 
bi-directional. They necessarily use KVC to access the model end of the link, 
but it’s not necessary that they use KVC for the UI element end.)

That means that all the data retrieval from an IB document follows a 
standardized KVC behavioral pattern that means all data goes through choke 
points ‘valueForKey:’, ‘setValue:forKey:’ and ‘mutableArrayValueForKey:’ (and a 
couple of others for properties modeled on NSSet API instead of NSArray). This 
consistency of behavior benefits everyone, and is the foundation of why IB can 
connect things with such generality.

However, in code, you’re not restricted to these KVC choke point methods. You 
can, instead, invoke accessors directly. Indeed, that’s exactly what you’re 
doing when you use property getters and setters. They’re a convenient shortcut 
instead of having to use the key-based KVC access methods all over your code, 
yet still be able to leverage KVC features such as KVO compliance. In other 
words, this is why KVC properties are the same thing as @property properties.

So, in code, you could invoke ‘countOfTweets’ directly, if you had defined that 
accessor (which you shouldn’t or don’t for other reasons). But code certainly 
can use the custom insert…, remove… and replace… accessors, with perfect KVO 
compliance, if that’s more concise that using the mutable proxy.

As I’ve suggested before, KVC/KVO is the interesting and subtle piece of 
technology. Bindings are actually kind of uninteresting, except as an example 
of how powerful KVC can be.

___

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: Basics of Cocoa Bindings

2015-09-11 Thread Alex Hall

> On Sep 11, 2015, at 21:04, Quincey Morris 
>  wrote:
> 
> On Sep 11, 2015, at 15:49 , Alex Hall  > wrote:
>> 
>> I followed all of that, and I see what you're saying. The binding to an 
>> array is, to it, no different than binding to a boolean or a string, it's 
>> just a single object. But how does a binding know what it's accessing? I 
>> figured it was down to the type of object being bound to; bind to an array, 
>> and you've got a 1-to-many, bind to, say, an integer, and you've got a 
>> 1-to-1. It sounds like it's more in what methods the view controller (in my 
>> case) implements.
> 
> It’s all about context. Each UI element (KVC “client”) knows what kind of 
> relationship it’s expecting. A text field needs a scalar value, so it expects 
> a one-to-one relationship to be named by the property. A table view needs row 
> data, so it expects an indexed one-to-many relationship.

Okay, the error I'm seeing (about [ViewController count]) is the table asking 
for how big it should be. That makes way more sense--I was under the impression 
that the array controller was asking on the table's behalf, that's why I 
expected it to use countOfTweets().

My question was more about the array controller knowing if it's hooked to an 
array or a scalar, but I get what you're saying now. I wonder, though, just 
what I've improperly configured that makes this not work? Specifically, 
shouldn't the array controller be helping the table get the count it needs, 
instead of the table sending that message directly to the view controller? 
Here's a zip file of my project as it stands now, in case it helps:
https://dl.dropboxusercontent.com/u/17005121/Bindings%20Test.zip
> 
> When a client asks for information via KVC, the message that gets sent may or 
> may not be specific to a particular kind of relationship. So you actually 
> have to start breaking things down into cases.
> 
> For a text field that wants to retrieve a model value (a scalar), it uses the 
> KVC method ‘valueForKey:’ (or possibly ‘valueForKeyPath:’, which is a 
> convenience method in KVC that breaks a key path into individual keys, and 
> invokes ‘valueForKey:’ sequentially). KVC figures out how to retrieve the 
> value, and does things like transforming a numeric property value into a 
> NSNumber object, since everything has to be an object for KVC.
> 
> For a table view that wants to retrieve (say) the tweet for row 20 of the 
> table, it uses the KVC method … surprise! … ‘valueForKey:’, with “tweets” as 
> the key. The object that KVC returns is — conceptually — an array *proxy* 
> object. That is, it’s an Apple-provided object that responds to all of the 
> NSArray behavior, but knows how to translate each NSArray method into an 
> access to the real array that’s backing the property — or the various custom 
> accessors that provide values, if  there’s no real array.
> 
> So the table view ends up with a NSArray-like object, and it can use 
> ‘objectAtIndex: 19’ to find the object in the 20th row. The reason there’s a 
> proxy involved here is to allow the model class to avoid *constructing* an 
> array to return (a potentially expensive operation), while letting the client 
> use the full power of the full NSArray API. That’s why, if the table view 
> wants to know the number of rows, it’s going to send a ‘count’ message rather 
> than a ‘countOfTweets’ method.
> 
> In short, KVC has leveraged the existing complexity of the NSArray class API 
> to provide a rich choice of ways to access indexed one-to-many property 
> values, without having to re-invent an entirely new set of analogous API 
> methods.
> 
> Things are a little more complicated for changing values in the model instead 
> of retrieving them. For scalars — that is, in contexts where the client needs 
> a one-to-one property, the KVC method it calls is ‘setValue:forKey:’. This 
> usually gets translated into a 'setXxx:’ method invocation, the accessor you 
> expect. It’s worth noting that if this setter is the *only* way that the 
> property way can be changed, then you get automatic KVO compliance for the  
> property, which is a Good Thing™.
> 
> If a table view needs to modify (say) the tweet for row 20, it does *not* use 
> ‘setValue:forKey:’. Functionally, it *could* do that, and KVC would do the 
> right thing, but that would require the table view to construct an entire 
> array of tweets, which is horribly expensive. Instead, it would really like 
> to use something like a proxy object, so that the elements that are unchanged 
> don’t cost anything to keep unchanged. This is exactly what happens. The 
> table view calls ‘mutableArrayValueForKey:’ to get what’s called a “mutable 
> proxy”. As retrieved, it represents the current model values using the 
> NSMutableArray API, so it allows the table view to use the 
> ‘replaceObjectAtIndex:withObject:’ on the proxy to make just that simple 
> update.
> 
> The other cool thing that the mutable proxy do

Re: Basics of Cocoa Bindings

2015-09-11 Thread Alex Hall
Minor update: in the zip file, in ViewController.swift, I hadn't changed the 
variable name in the for loop. It should be "tweets", not "tweetsArray". The 
project builds, and the error appears, either way. Actually, that it builds 
with a mistake like that seems a bit odd. Anyway, just something to watch if 
anyone decides to have a look at the file.
> On Sep 11, 2015, at 23:20, Alex Hall  wrote:
> 
> 
>> On Sep 11, 2015, at 21:04, Quincey Morris 
>>  wrote:
>> 
>> On Sep 11, 2015, at 15:49 , Alex Hall > > wrote:
>>> 
>>> I followed all of that, and I see what you're saying. The binding to an 
>>> array is, to it, no different than binding to a boolean or a string, it's 
>>> just a single object. But how does a binding know what it's accessing? I 
>>> figured it was down to the type of object being bound to; bind to an array, 
>>> and you've got a 1-to-many, bind to, say, an integer, and you've got a 
>>> 1-to-1. It sounds like it's more in what methods the view controller (in my 
>>> case) implements.
>> 
>> It’s all about context. Each UI element (KVC “client”) knows what kind of 
>> relationship it’s expecting. A text field needs a scalar value, so it 
>> expects a one-to-one relationship to be named by the property. A table view 
>> needs row data, so it expects an indexed one-to-many relationship.
> 
> Okay, the error I'm seeing (about [ViewController count]) is the table asking 
> for how big it should be. That makes way more sense--I was under the 
> impression that the array controller was asking on the table's behalf, that's 
> why I expected it to use countOfTweets().
> 
> My question was more about the array controller knowing if it's hooked to an 
> array or a scalar, but I get what you're saying now. I wonder, though, just 
> what I've improperly configured that makes this not work? Specifically, 
> shouldn't the array controller be helping the table get the count it needs, 
> instead of the table sending that message directly to the view controller? 
> Here's a zip file of my project as it stands now, in case it helps:
> https://dl.dropboxusercontent.com/u/17005121/Bindings%20Test.zip
>> 
>> When a client asks for information via KVC, the message that gets sent may 
>> or may not be specific to a particular kind of relationship. So you actually 
>> have to start breaking things down into cases.
>> 
>> For a text field that wants to retrieve a model value (a scalar), it uses 
>> the KVC method ‘valueForKey:’ (or possibly ‘valueForKeyPath:’, which is a 
>> convenience method in KVC that breaks a key path into individual keys, and 
>> invokes ‘valueForKey:’ sequentially). KVC figures out how to retrieve the 
>> value, and does things like transforming a numeric property value into a 
>> NSNumber object, since everything has to be an object for KVC.
>> 
>> For a table view that wants to retrieve (say) the tweet for row 20 of the 
>> table, it uses the KVC method … surprise! … ‘valueForKey:’, with “tweets” as 
>> the key. The object that KVC returns is — conceptually — an array *proxy* 
>> object. That is, it’s an Apple-provided object that responds to all of the 
>> NSArray behavior, but knows how to translate each NSArray method into an 
>> access to the real array that’s backing the property — or the various custom 
>> accessors that provide values, if  there’s no real array.
>> 
>> So the table view ends up with a NSArray-like object, and it can use 
>> ‘objectAtIndex: 19’ to find the object in the 20th row. The reason there’s a 
>> proxy involved here is to allow the model class to avoid *constructing* an 
>> array to return (a potentially expensive operation), while letting the 
>> client use the full power of the full NSArray API. That’s why, if the table 
>> view wants to know the number of rows, it’s going to send a ‘count’ message 
>> rather than a ‘countOfTweets’ method.
>> 
>> In short, KVC has leveraged the existing complexity of the NSArray class API 
>> to provide a rich choice of ways to access indexed one-to-many property 
>> values, without having to re-invent an entirely new set of analogous API 
>> methods.
>> 
>> Things are a little more complicated for changing values in the model 
>> instead of retrieving them. For scalars — that is, in contexts where the 
>> client needs a one-to-one property, the KVC method it calls is 
>> ‘setValue:forKey:’. This usually gets translated into a 'setXxx:’ method 
>> invocation, the accessor you expect. It’s worth noting that if this setter 
>> is the *only* way that the property way can be changed, then you get 
>> automatic KVO compliance for the  property, which is a Good Thing™.
>> 
>> If a table view needs to modify (say) the tweet for row 20, it does *not* 
>> use ‘setValue:forKey:’. Functionally, it *could* do that, and KVC would do 
>> the right thing, but that would require the table view to construct an 
>> entire array of tweets, which is horribly expensive. Instead, it would 
>> really like to use some

Re: Basics of Cocoa Bindings

2015-09-11 Thread Quincey Morris
On Sep 11, 2015, at 20:20 , Alex Hall  wrote:
> 
> Okay, the error I'm seeing (about [ViewController count]) is the table asking 
> for how big it should be.

Actually, that’s not it, though you can be excused for thinking so.

What’s wrong is that you tried to add way too many bindings, in particular to 
the array controller. The only binding needed is the content binding. The 
managedObjectContext binding must NOT be used, because this is not a Core Data 
data model (but it probably makes no difference because it’s referencing nil 
and so I expect the array controller just ignores it). The selectionIndexes and 
sortDescriptors CANNOT be used in the project as it stands, because your view 
controller does not have any corresponding properties to bind to. The ‘count’ 
here is asking for the models’ opinion of the number of selected rows, or the 
number of sort descriptors. It’s not easy to tell which. In order to use these 
bindings, the view controller would have to have properties with names that 
match the model keys. Remember that the model key is just a string. It can’t 
cause any properties or methods to exist — you have to do that part.

After fixing that, your app crashes with a different error, which is a kind of 
success because things got a lot further!

The later crash was because you bound the wrong thing (that is, the wrong 
“from” object) when trying to get hold of displayText. In the IB object 
hierarchy, you bound the thing called “Text Cell”, which is actually a 
prototype NSCell used for the column header. Normally you just treat is as part 
of IB’s implementation details and don’t modify it directly.

There’s a sub-hierarchy of 3 other things, called “Table Cell View” (which is a 
NSTableCellView, and it’s the prototype of the top level view for each cell), 
"Table View Cell” (which is your text field), and “Table View Cell” (yes, the 
same name, which is the NSCell that the NSTextField machinery uses and you 
similarly ignore in IB, in most cases).

So after deleting the incorrect “Text Cell” binding, your project runs, 
although the rows don’t show anything because the text field isn’t actually 
(wasn’t ever) bound to anything.

To complete this example — to get the text from Tweet.displayText to be shown 
in the table — you have to hook up the the text field (the one called “Table 
Cell View”, but not the NSCell of that name) via binding or whatever so that it 
resolves its value through the Table Cell View’s objectValue. That’s the 
“advanced” part, and I don’t remember exactly what to do because I never use 
table view content bindings any more. If you carefully follow through the 
example of table content bindings the table view programming guide, you should 
be able to figure this out, but you’re on your own. I don’t feel obliged to 
make your self-inflicted pain my self-inflicted pain. :)

> That makes way more sense--I was under the impression that the array 
> controller was asking on the table's behalf, that's why I expected it to use 
> countOfTweets().

As it turned out, the array controller wasn’t asking about the tweets at all. 
But if it was, it would use “count" because it’s an *array* controller, and the 
standard behavior that returns the count is “count”. Note that the table view 
doesn’t even know the name of the relevant property, because it’s hidden on the 
“other” side of the array controller, not to mention buried inside a binding. 
It’s “count” all the way down the line.

___

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: Basics of Cocoa Bindings

2015-09-11 Thread Quincey Morris
On Sep 11, 2015, at 21:05 , Quincey Morris 
 wrote:
> 
> There’s a sub-hierarchy of 3 other things, called “Table Cell View” […], 
> "Table View Cell” […] and “Table View Cell” […].

On reflection, I feel obliged to emphasize — for anyone who enjoys the 
painfully funny — the perverseness of this little piece of IB idiocy. The word 
“cell” is being used in 2 different senses here, and the object that’s most 
important to configure — the middle one — is not either kind of cell, but a 
text field. But it’s weirder than that. All three names are UI labels, which 
means they serve no function in your app. They’re all arbitrary, and have no 
purpose but to clarify to you which object is which.

If there’s not enough fun in that, try adding a second column to the table. 
(Spoiler: yes, it uses all the same names again in the new column.)

You can’t make this stuff up.



___

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