How do I get data out of NSRuleEditor?

2016-06-26 Thread Jim Thomason
I've been desperately trying to use NSRuleEditor for a while now, since it
presents exactly the type of interface I want to show to the users.

But I can't figure out how to properly get data out of it. I can configure
all of the delegate methods to build the interface, but then what?

The data I'm presenting doesn't fit into a predicate, so I'm unable to use
NSPredicateEditor.

The best I've come up with is to bind the RuleEditor's rows to something,
and then iterate through each row, finding the criteria, and then parsing
to look for the displayValue to build up some sort of other structure that
I can actually use elsewhere.

That just seems...yucky to me. Since I'd need to reverse the displayValue
into the real value in some manner, and most things that I've seen about
localized strings is that you really shouldn't go the other way. But maybe
I'm overthinking it and that is acceptable?

Or is there some other alternative method? If I just had a list of the
selected values of the criteria for a given row, along with all subrows
associated (and their selected values and so on), I'd be in business.

Any suggestions?

-Jim.
___

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: Two Array Controllers, loading from CoreData, without a contentArray...

2015-09-22 Thread Jim Thomason
> Array Controllers etc. can be configured to monitor their context for
changes and automatically re-fetch when needed. So they should keep in sync
that way without any extra work.
>

It can? How?

I'm only aware of the prepares content flag, but that'll only load the data
into the controller when it awakes out of the nib, as opposed to reflecting
changes made in another controller.

-Jim..
___

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: Two Array Controllers, loading from CoreData, without a contentArray...

2015-09-22 Thread Jim Thomason
My request was specifically about keeping two NSArrayControllers in sync
that are -not- bound to a content array.

The case I was tooling around with was for a root level object that just
fetches all of its data automatically and bypasses any contentArray binding.

Hypothetically, you could have whatever object is vending out the
contentArray check its value and see if it's nil. If it is, then fetch the
entities from the context using the specified fetch predicate. The
annoyance with this is that it'd require a link from the model object back
to the array controller, to learn which entities to fetch and with what
predicate.

I think I'd rather post the notification to the other array controller to
keep it all loosely coupled, if I had to choose between the two techniques.

-Jim...


On Tue, Sep 22, 2015 at 5:28 PM, Richard Charles <rcharles...@gmail.com>
wrote:

>
> > On Sep 22, 2015, at 7:40 AM, Jim Thomason <j...@jimandkoka.com> wrote:
> >
> > The question is simple - is there a reasonable way to create two
> > NSArrayControllers, have them bound to an entity through CoreData, and
> keep
> > them in sync?
>
> One way would be to bind the two array controllers to the same content
> array. The content array can be an array of managed objects. You may need a
> custom binding. Subclass and override -[NSArrayController remove:] to
> remove the selection from the managed object context. You may need to add
> objects to the managed object context through some other means as the array
> controller may not operate in entity mode without the content bound to a
> managed object context.
>
> This may help when trying to programmatically initialize the controller.
>
> http://stackoverflow.com/questions/1860805/nsarraycontroller-initialization
>
> Another neat thing you can do with NSArrayController is chain two of them
> together.
>
> http://www.informit.com/articles/article.aspx?p=1397563=4
>
> It is amazing how versatile NSArrayController can be but you may need to
> work with it and try some experimenting.
>
> --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

Two Array Controllers, loading from CoreData, without a contentArray...

2015-09-22 Thread Jim Thomason
First, to be clear, I'm not actually trying to do this. I'm just curious
how it could be done. I cooked it up while working on other things.

The question is simple - is there a reasonable way to create two
NSArrayControllers, have them bound to an entity through CoreData, and keep
them in sync?

So there's ControllerA, which populates TableA; and ControllerB, which
populates TableB. Neither of them have an explicit bound contentArray, they
just load up all of their associated entities straight from the
managedObjectContext.

I'd like to be able to add an object into ControllerA, and have it
automatically show up in ControllerB. I haven't figured out a way to do it.

If they were both bound to the same contentArray, it's no problem - the
content automatically shows up. But if it's loaded via the fetch request,
then some other mechanism needs to come into play.

Subclassing them both and having A post a notification so that B re-fetches
its content is the best solution I've got, but I figured I'd ask around and
see if anybody else had a more clever approach.

-Jim...
___

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

Should all CoreData relationships be optional in swift?

2015-09-15 Thread Jim Thomason
I'm doing some porting/updating work and came across an issue.

I have two objects - which we'll call Foo and FooType.

Every Foo must have a FooType, and every FooType is associated with
multiple Foos.

The FooType also has an image associated with it, and the Foo uses that
image exclusively.

So I added this:

class Foo {
   ...
   var image : NSImage { get { return self.type.image } }

}

The problem is, this image value is used to populate a cell in a Source
Control List. When I add a new Foo, it's immediately added to the table.
And it pops up in there before a FooType is associated with it.

That in turn means that the image getter tries to go through self.type,
which isn't defined yet.

How do I fix this? I can't do self.type?.image or if let t = self.type,
because the type is declared as non-optional and I can't unwrap an optional
value.

Presumably, I can just make the type optional, but it's not -really-
optional, since all Foos _must_ have a type before they're saved. It's a
mandatory relationship.

Generalizing wildly, I can see this issue popping up with any relationship
- if you have a derived property that relies upon a relationship that may
not have been set yet, you'd fail with an error. So should all
relationships just be made optional to get around this? That seems like the
wrong approach.

Any suggestions?

-Jim
___

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

View based table binding to alternate object?

2015-08-11 Thread Jim Thomason
This example is a little contrived, because I'm struggling with how to
phrase it properly. The answer to the question might be as simple as You
can't do that,, and I'm cool if it is, I just want to confirm I'm not
doing something stupid.

I have an array controller of mutable dictionaries. It has two keys - A
and B.

I have a view based table -
I bound the table's Table Content - Array Controller arrangedObjects
Table Cell View.Table View Cell. value is bound - Table CellView
objectValue.A.
Table Cell View.Table View Cell. value is bound - Table CellView
objectValue.B.

This all works just fine. I then tried to rebind my B column to an
arbitrary external object with a constant parameter. Assume that this is a
class, instantiated within IB, that just has a single method, conveniently
also called B, which returns a single value - B. It's wrapped up in an
Object Controller.

I rebound my second column:
Table Cell View.Table View Cell. value is bound -
staticObjectController.selection.B.

This does not work. I receive no errors (other than Xcode not being able to
resolve the key path), and the table just displays the default text
repeated.

If I try this with a cell based table, it works -
bind Table 2.ColumnA.value - arraycontroller.arrangedObjects.A
bind Table 2.columnB.value - staticObjectController.selection.B

Repeats B as expected in columnB.

It only seems to be in a view based table that it doesn't work.

Do I have to cells in a view based table to the cell view/objectValue path?
Is there some other obvious gotcha I'm missing? Should this just not be
done? What gives?

I can provide a sample project if this isn't clear.

Thanks,

-Jim...
___

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

Validating against multiple updated Coredata objects

2014-10-15 Thread Jim Thomason
Hi,

In my user interface, I can have the user edit a field on an object, and
behind the scenes this will trigger a cascade of other changes to other
objects. As a result, I don't just need to validate the value the user
typed in, I also need to validate all of the other changes that that single
edit will make to all of the related objects.

And I cannot come up with a good way to do it.

Let's say I have an Employee object (with a name attribute, a title, a
salary, and a related department), and a Department object (also with a
name, and a list of related employees).

In the interface, I add in a new user, Jenkins, say he's a Developer,
who makes $100k, and add him into the IT department. This passes all the
constraints on the Employee object (all fields are filled in), so it checks
out there.

But the Department object can have any number of ludicrous other
constraints involved. Maybe IT only wants to hire a single person named
Jenkins and it fails. Maybe IT has too many developers already and it
fails. Maybe by adding a new employee, the Department object automatically
totals up all salaries and sees that they're over the budget and fails.
Maybe the Department hands off that salary total (which is not something
the user typed in or even has any knowledge of!) to a parent Company
object, which rejects it because even though the Department is still within
what it was given as a salary constraint, the company as a whole would not
be. And on and on and on.

Is there a clever way to capture and report errors of this type back to the
user?

I considered stuffing all of the cascading salary logic into a
validateSalary:error: method, for example, but then I'd do all the
calculations for the related objects once when I validate, and then do them
again when I actually set the Salary after all the checks succeed.  If
these operations are expensive, then I'd rather not do them multiple times.
AFAIK, I'd have no good location to cache the calculated values created
during the validate routine, short of just stuffing them into some global
variable somewhere.

I tried using validateForUpdate: on the individual objects, but that isn't
invoked until the document is saved, which is potentially long after
changes were made. I can manually call it against all updated objects in
the context, I guess, though this is also a potentially wasteful operation.
As a side note, I've never been able to successfully directly call this
method and have an error object available for me - they're always nulls,
and hence I can't report anything back.

I've also considered using a customValidateSalary method, called at the end
of setSalary, which does validation on known related objects. But that
breaks down if, for example, the Employee only knows to validate the
Department object and never checks to see if the Company object tossed an
error, because it wasn't even aware of it. To catch all modifications to
all objects, I'm basically back to iterating over all updatedObjects again.

Regardless, at the end of it all, after all the validations against all
objects are performed, if any failed then I could undo the last action to
restore to prior state and alert the user, but I lack the context of
re-highlighting the field the way the standard validateSalary:error:
CoreData methods would work. That's not as user friendly.

I could also rewire all the setters to toss exceptions if an invalid input
falls into them, wrap everything in try/catch blocks, and let them bubble
up only to be captured at the highest level and finally displayed. I still
lose context of which input field the user was typing into, though. Maybe
capture the first responder and re-use that? I dunno.

Does anyone have any suggestions about how to deal with cascading
validation in this manner? It feels like I've got the OO equivalent of a
stack of GOTO blocks to unwind this mess. Any suggestions welcome.

-Jim
___

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: Good way to have default relationship to override nil?

2014-08-21 Thread Jim Thomason
Nope. The inverse is proxyFor. proxy points one way, proxyFor is the
reciprocal.

I'll see if I can boil it down to a small test case and post that.

-Jim...


On Wed, Aug 20, 2014 at 11:47 PM, Jerry Krinock je...@ieee.org wrote:

 I understand the typos, Jim.

 So, what is the Inverse Relationship of the ‘proxy’ relationship?  I’m
 guessing it might by “No inverse”?


 ___

 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/jim%40jimandkoka.com

 This email sent to j...@jimandkoka.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

Good way to have default relationship to override nil?

2014-08-20 Thread Jim Thomason
I have a set of relationships:

Foo.proxy  Foo.proxyFor

1-1 mapping. The way that the data is structured, a Foo object may be a
proxy for another one. However, the proxy is not required, in which case
the original Foo object should be returned.

I'd tried to set this up by creating a custom getter that returns self if
the relationship is nil.

-(Foo*) proxy {


[self willAccessValueForKey:@proxy];

Foo* prx = [self primitiveValueForKey:@proxy];

[self didAccessValueForKey:@proxy];


return prx != nil

? prx

: self;


}


In terms of accessing it, this works fine. However, whenever I try to set a
new proxy:


[someFooObj setProxy : otherFooObj];


All hell breaks loose. It sets off a cascade that roughly seems to do the
following (possibly redundantly for a few of these calls):


[someFooObj setProxy: otherFooObj];

[someFooObj setProxy: nil];

[someFooObj setProxy: someFooObj];


After a lot of hunting, I discovered that it was the KVO notes which were
fired by setProxy - once didChangeValueForKey:@proxy hit, then it set off
a chain reaction of additional setProxy calls, with nil and self.


I finally fixed this by -not- overriding the CoreData setter, and instead
creating a new one:


-(Foo*) defaultProxy {

  return [self proxy] != nil

? [self proxy]

: self;

}


And then replaced all calls to


[someFooObj proxy]


with


[someFooObj defaultProxy];


After that it all magically works. I can do it this way, but it just feels
a little clunky to have to have a separately named method that is not the
actual property name.


So I have two questions:


1) First off, why does this actually break so badly? I'm never actually
calling setProxy: directly, it's just somehow indirectly called over and
over from within the didChangeValueForKey: notification inside of it.


2) Is there a better way I could model this so as not to need a custom
separately named method? I'm pretty early in my dev cycle, so it's really
easy to refactor this to something else, I'm just stumped for ideas.


Many thanks,


-Jim
___

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: Good way to have default relationship to override nil?

2014-08-20 Thread Jim Thomason

  I have a set of relationships:
 
  Foo.proxy  Foo.proxyFor

 That’s a head-scratcher, Jim.  A relationship is not between properties.
 A relationship is between objects,

 Foo —— Bar

 In some cases, probably yours, the objects may be of the same type…

 Foo — Foo


I apologize, I was merely not being clear -

Yes, the relationship is between two Foo objects, with the relevant
properties being proxy and proxyFor.



 Now on to the real issue…

  [someFooObj setProxy:otherFooObj] ;
 
  All hell breaks loose
 
  I finally fixed this by -not- overriding the Core Data setter

 You didn’t post your override of -setProxy:.  Post that override, and
 maybe someone can answer your questions.


That was a typo (Man, I'm being horribly unclear today...). I meant that I
fixed it by -not- overriding the CoreData getter.

That is, I didn't use the -(Foo*) proxy; method I posted originally, and
instead changed it to using -(Foo*) defaultProxy, and left the proxy getter
as @dynamic.

I have the same issue whether I use a custom setProxy:(Foo*) method or the
default @dynamic'ally generated one - the didChangeValueForKey:@proxy
note causes that cascade of setting to nil, and then to self.

Only by moving that functionality out of the proxy getter and into the new
defaultProxy getter did I resolve it.

(technically, I could also resolve it by overriding setProxy: and not
calling willChangeValueForKey:/didChangeValueForKey:, but of course, that's
not the right solution)

-Jim.
___

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

NSRuleEditor help?

2013-01-15 Thread Jim Thomason
Is there a good tutorial or set of examples out there for NSRuleEditor? I'm
quite interested in using the class, but the lack of documentation is
definitely a hindrance. I found a couple of light examples that I'm trying
to work through and reverse engineer the rest of the functionality, but
it's slow going. Better docs beyond just the class reference would be
helpful.

For example ( as a specific concrete question), what is the rowType
supposed to signify? I know I can choose NSRuleEditorRowTypeSimple
or NSRuleEditorRowTypeCompound, but what's the difference?

The docs imply that only a Compound row can have child rows, but that
doesn't seem to be the case in my testing. Unless the row type is
automagically changing behind the scenes when I add a subrow?

Anyway, if there's a good tutorial on the class, I'd love to be pointed
towards it. I've just had no luck and I really want to make use of it.

Many thanks,

-Jim...
___

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


Service with NSURLConnection

2013-01-11 Thread Jim Thomason
Gang,

In my fighting with services, I'm trying a different approach and hence
have a different question - is there a way that I could craft a service
that reads in selected text, uses that to open and perform a web
connection, and then returns that data back to the calling app?

The trivially silly example I have would be a service that looks up the
definition of a word and pastes the definition in place. So I might select
the word apple and invoke my service, and it goes off and searches the
web or my central server or something and pastes back into place An
awesome computer company and/or fruit. No, I don't know why anyone would
want such a service, this is just to illustrate the concept.

The issue is that my -doWebStuff:userData:error: method seems to only let
me write to the pasteboard during the invocation of that method, and once
it completes I'm done. NSURLConnection is all delegate based, so I wouldn't
have the results of my lookup until the secondary thread completes and my
delegate realizes its done loading the data. By that point, the doWebStuff
method is long since completed and I'm stuck w/o results.

I can see a few different hypothetical ways to make this work:
(a) somehow block the main thread until the secondary threads come back.
I'm not sure this'd work since the delegate method would be invoked on the
main thread, which I'm currently blocking.

(b) Somehow update the pasteboard after the service method finished?

(c) Somehow defer my way out of the method to do something else, then hop
back in when I'm done? Something like the concept of a promise in
javascript. I'm grasping at straws here.

(d) Might NSOperationQueue be magical enough to allow something like this?


I'm stumped. For now, I think this just gets filed under Can't be done
since by everything I can tell I have to do all work in a service in that
single invocation of the single method in the single thread, and anything
that'd cause me to hop out of there kills the concept.

Does anybody have a method to do this? Or is it just not possible?

Many thanks,

-Jim.
___

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: Service with NSURLConnection

2013-01-11 Thread Jim Thomason
It's not my app, so it's all opaque to me. I'm trying to implement a
service that sits up in the service menu.

So the user could, for my contrived example, be in Pages, type in their
word, invoke my service, and get the definition automatically pasted into
Pages for them.

I don't have access to anything in whatever the invoking app is, so I can't
just have an object over there refresh. I wouldn't have an object to
invoke. I can fall back onto godawful hacks like programmatically sending a
cmd-P event and hoping it pastes in my data, or using applescript to select
the paste option from the edit menu, but that's the sort of nonsense I'm
really trying to get away from.

A standard service implementation already handles the I/O in the invoking
app pretty well - it gets the right selection and pastes the results back
into the right spot. But as best as I can tell, it requires that my service
be single threaded and only transmits the results of the pasteboard when
the sole service method completes.

Honestly? The best horrible horrible hack I can come up with now is to
layer it. So my service is just a very thin wrapper that does nothing but
invoke my secondary real app to do the URL loading for me, and stick it
onto the pasteboard. The service would invoke the wrapper, which would
launch the real app and block until it gets its response from there, then
unblock pop it onto the pasteboard when the secondary completes. I'm not
sure if I could even get this working properly.

Needing to use a thin wrapper to invoke the real app is pretty goofy, but I
think it would work. And it lets me use the rest of the services
implementation for my cutting and pasting without reverting to hacks like
trying to invoke copy and paste events. But I dunno, if I need to fall back
on something like that, I really felt like something went wrong.

Opinions on that double-app strategy would also be welcome, in addition to
any better ideas, which I desperately hope exist.


On Fri, Jan 11, 2013 at 11:08 AM, Alex Zavatone z...@mac.com wrote:

 Can you declare a callback that gets automatically called when the web
 request completes, then as a result of this new entry point issues a needs
 refresh to the GUI item you care about? That GUI item then grabs the data
 from the source it's tied to which you have just updated as part of the
 call back?

 Of course, this implies a proposed flow for a non error case.

 Do I understand this correctly?

 It seems like you want to make sure this happens off the main thread, so
 that the GUI can still be responsive, so you could issue a GCD block or use
 some of the great open source libs out that kind people have already put
 together to handle async net communication.


 On Jan 11, 2013, at 11:59 AM, Jim Thomason wrote:

  Gang,
 
  In my fighting with services, I'm trying a different approach and hence
  have a different question - is there a way that I could craft a service
  that reads in selected text, uses that to open and perform a web
  connection, and then returns that data back to the calling app?
 
  The trivially silly example I have would be a service that looks up the
  definition of a word and pastes the definition in place. So I might
 select
  the word apple and invoke my service, and it goes off and searches the
  web or my central server or something and pastes back into place An
  awesome computer company and/or fruit. No, I don't know why anyone would
  want such a service, this is just to illustrate the concept.
 
  The issue is that my -doWebStuff:userData:error: method seems to only let
  me write to the pasteboard during the invocation of that method, and once
  it completes I'm done. NSURLConnection is all delegate based, so I
 wouldn't
  have the results of my lookup until the secondary thread completes and my
  delegate realizes its done loading the data. By that point, the
 doWebStuff
  method is long since completed and I'm stuck w/o results.
 
  I can see a few different hypothetical ways to make this work:
  (a) somehow block the main thread until the secondary threads come back.
  I'm not sure this'd work since the delegate method would be invoked on
 the
  main thread, which I'm currently blocking.
 
  (b) Somehow update the pasteboard after the service method finished?
 
  (c) Somehow defer my way out of the method to do something else, then hop
  back in when I'm done? Something like the concept of a promise in
  javascript. I'm grasping at straws here.
 
  (d) Might NSOperationQueue be magical enough to allow something like
 this?
 
 
  I'm stumped. For now, I think this just gets filed under Can't be done
  since by everything I can tell I have to do all work in a service in that
  single invocation of the single method in the single thread, and anything
  that'd cause me to hop out of there kills the concept.
 
  Does anybody have a method to do this? Or is it just not possible?
 
  Many thanks,
 
  -Jim

Re: Service with NSURLConnection

2013-01-11 Thread Jim Thomason
Razafrazin. Okay, you all thwarted my example. :-)

For sake of argument, assume that the work has to be done in an external
thread, or I have to jump in and out of the main thread some how. I'm not
actually using URL connections like this in the actual app, I was just
hoping that it was a nice simple example use case to give. For the actual
code, I wouldn't be able to just do a synchronous request.

-Jim


On Fri, Jan 11, 2013 at 12:52 PM, Jens Alfke j...@mooseyard.com wrote:


 On Jan 11, 2013, at 8:59 AM, Jim Thomason j...@jimandkoka.com wrote:

 The issue is that my -doWebStuff:userData:error: method seems to only let
 me write to the pasteboard during the invocation of that method, and once
 it completes I'm done. NSURLConnection is all delegate based, so I wouldn't
 have the results of my lookup until the secondary thread completes and my
 delegate realizes its done loading the data.


 No, NSURLConnection supports synchronous calls — see the
 +sendSynchronousRequest: method.

 —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

help trouble shooting...maybe with resume?

2011-08-23 Thread Jim Thomason
Gang,

Unfortunately, this is a very vague question but I'm at a bit of a
loss and hoping someone could provide some general technique or
avenues to explore.

Apple recently rejected a new app of mine, with this explanation:

When saving a file, and reopening it by double-clicking the saved file
in the Finder, the app launches with 2-3 windows: One being the saved
file, and additional windows with no saved data. Mac OS X 10.7


I'm guessing it's due to Lion's resume window features somehow getting
confused. The app is document based, and it looks at the document
controller's recently opened documents upon launch. If it finds any,
it automatically opens the last document used. If the list is empty,
it automatically creates an untitled document. The snippet of code is
essentially unchanged from when I originally wrote it for a different
app way back on Tiger. This is called in the delegate from
applicationDidFinishLaunching:. applicationShouldOpenUntitledFile:
returns NO.

Here are my problems - first of all, I can't reproduce the blasted
bug. Everything seems to always behave fine to me, on 10.7.0 or
10.7.1. I've requested more info about how to reproduce the bug but
haven't heard back yet.

Regardless of whether they get back to me, does what I've described
sound like it could be the root of my issue? Is there some other
method for re-opening the last document (or creating a new one) I
should be using? Is there anything else I can look for or verify that
might be causing this behavior?

Naturally, it'd help if I could manifest the issue myself, but right
now I just don't even know where to begin looking for this one. :-(

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Multithreaded Coredata save in Lion

2011-08-01 Thread Jim Thomason
 -saveDocument: has never been expected to do its work immediately. Instead, 
 you want to call:

 -saveDocumentWithDelegate:didSaveSelector:contextInfo:

 Then, when the delegate is called, spawn off your new MOC.

That's exactly what I needed. A little rewiring of the app to use the
delegate method and hand in a few new flags regarding whether any
changes were saved and I'm back in business. Guess it was just dumb
luck that it consistently behaved the other way on the older OSes.

And, incidentally, I'd say that the auto-save is justified - it's at a
point where the user should have saved all changes anyway (Okay, my
data is stable. Now analyze it.), so it just saves it for them if
necessary instead of prompting to require it.

Thanks!

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Multithreaded Coredata save in Lion

2011-07-31 Thread Jim Thomason
Gang,

I've encountered an odd bug/issue/feature(?) in Lion and want to know
if there's a workaround available.

I have a multithreaded CoreData application. It does a lot of
calculations on the context, so it spawns off a separate thread and
creates a new ManagedObjectContext to do its work. AFAIK, I'm
following proper Best Practices for multi-threaded core data access.
This all works fine.

The issue is, at the start of my thread, I call saveDocument: on the
main context, in the main thread via this:

[self performSelectorOnMainThread:@selector(saveDocument:)
withObject:nil waitUntilDone:YES];

I didn't want to worry about jumping through the hoops of merging the
contexts, so I just ensure the main context is clean and saved. It
invokes saveDocument, then checks to see if the context still has
changes, and if it does it bombs out and refuses to continue, assuming
that the save failed for some reason.

This works fine under Snow Leopard (and Leopard, and it used to work
under Tiger as well, though I no longer support that OS). But under
Lion, it fails since it doesn't actually wait until the save is
complete. It looks like pre-Lion, saveDocument: would directly invoke
the writeToURL:... method, whereas in Lion it's deferring it until the
next invocation of the run loop.

So under Snow Leopard, I'd see this behavior:

SECOND THREAD: perform saveDocument on Main, wait until done
MAIN THREAD: call saveDocument
MAIN THREAD: call writeToURL:...
SECOND THREAD: done waiting for main to complete, carry on.

But now on Lion, I see this:

SECOND THREAD: perform saveDocument on Main, wait until done
MAIN THREAD: call saveDocument
SECOND THREAD: done waiting for main to complete, carry on. Sees that
the main MOC still has changes, fails out.
MAIN THREAD: call writeToURL:...

So Lion waits for saveDocument: to finish, but then writeToURL:... is
called later. I have a simple test case to verify:

http://www.prototypesite.net/threadedsavetest.zip

If you run it on Lion, writeToURL is called after the second thread is
done waiting. If you run it on Snow Leopard, it's done before.

Is this a bug or a feature? If it's a feature and expected to behave
this way, then what's the proper way for me to get this behavior now,
in a way that's backwards compatible on Snow Leopard and Leopard?

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: How to extract files from zip archive?

2011-05-30 Thread Jim Thomason
On Mon, May 30, 2011 at 10:45 AM, Vyacheslav Karamov
ubuntul...@yandex.ru wrote:
 Hi All!
 ...
   [task setLaunchPath:@/usr/bin/unzip];
   NSArray * args = [NSArray arrayWithObjects:@-a , listsPath, @ -d ,
 sharedPath, nil];

In addition to what others have said regarding spaces and such, when I
was looking around for this, most of the posts at various sources
suggested using ditto as opposed to unzip. Someone can correct me if
I'm wrong, but AFAIK unzip doesn't support resource forks (though you
can unzip 'em to a separate file), and there may be other metadata it
ignores/goofs up/forgets/etc.

Launching ditto to do this is easy:

[task setLaunchPath:@/usr/bin/ditto];
[task setArguments: [NSArray arrayWithObjects:@-x, @-k,
zipFilePath, someTargetDirectory, nil] ];

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: how can I copy from another app?

2011-05-05 Thread Jim Thomason
I was finally able to get it to work.

As others have pointed out, and rightfully so, there be dragons here.

The following all constitutes godawful hacks and abuse of the system.
I'm gonna file a feature request that services should be configurable
with variable input/output so I can chuck this whole mess.

Honestly? The end results are pretty slick, but it's done in a fragile
and brittle way. I'll leave it to other devs discretion if that's
worth the risk in their own apps. For myself, I'm able to make some
assumptions about how my users will interact with my app and where
I'll be copying from that'll allow it to work most of the time. Not
ideal but feasible.

The mess of an applescript that works is this:

tell application %@
  activate
  tell application System Events
tell application process %@
  set frontmost to true
  keystroke c using command down
  tell menu bar 1
tell menu bar item Edit
  tell menu Edit
click menu item Copy
  end tell
end tell
  end tell
  set fnar to the clipboard
end tell
  end tell
  set clip_data to (the clipboard) as text
end tell

Yes, that does issue a command-C and follow it by explicitly looking
for an Edit Menu and clicking on a copy command. I could only get it
to work consistently if I issued both. Bugger all if I know.

Further, I had to issue that from a delayed selector with at least a
0.1 second gap, preferably 0.2. Hacks on top of hacks on top of hacks.

So I've already run into hassles because I'm forcing my UI to pause
briefly here. But even worse is that applescript is just dog slow.
Admittedly, I'm running on a several years old 2.4ghz core2 duo, but a
0.6 second (on average) duration for the applescript to execute is
just ridiculous.

It added up to nearly a second pause before the app could do anything
usable, but it also had the side-effect of shifting focus out of my
app and into the calling application, so for that brief second
anything the user tried to do wouldn't go to me and would instead go
to the original app. Bad bad bad.

w/o any way to speed up the applescript (and the original clean(-ish)
script now a steaming mess), I shifted gears to a different approach
and directly simulated the pressing of command-C via a suggestion
found here:

http://stackoverflow.com/questions/2379867/simulating-key-press-events-in-mac-osx

(to spare looking it up, the standard qwerty keycodes for C and V are
8 and 9, respectively)

I still needed to add a 0.1 second delay after sending the fake
keystroke, presumably to give it time to reach the pasteboard, but
other than that it works swimmingly. The 0.1 second pause isn't
noticeable, since it happens before my app appears, and I (so far) am
not having any issues with it.

Of course, this approach opens up a whole different can of worms in
that in addition to being fragile in all the ways the applescript
approach was, it'll break very spectacularly with non-qwerty keyboards
since it's relying upon the raw keycode values, as opposed to just
sending the appropriate character.

I think I'm just gonna add a toggle to turn off the functionality if
the user has a non-qwerty keyboard, at least for now. Presumably, I
can have them explicitly map the keys or otherwise divine them myself,
but man what a nuisance.

Implement any of this at your own risk, and be sure to understand the
consequences of doing it. This is only gonna work with a very narrow
focus.

-Jim

 On 4 May 2011, at 22:46, Jim Thomason wrote:

 I know this has been asked a bajillion times before, yet here we are.

 So it turns out that my simple little applescript to copy in from
 another app was ineffective. Lots more digging around led me to create
 this:

 tell application Xcode
       activate
       tell application System Events
               tell application process Xcode
                       set frontmost to true
                       keystroke c using command down
               end tell
       end tell
       display dialog (the clipboard)
       set foo to path to frontmost application
       display dialog foo
 end tell

 which is currently hardwired to Xcode and has a couple of dialogs for
 debugging purposes. Yes, yes, I know that blissfully assuming that
 command-C performs a copy operation is less than ideal. Best option
 I've seen so far.

 Here's the annoying bit - this works just fine when run from the
 Script Editor. But when I run it within my app by firing it off via an
 NSAppleScript call, it fails and copies no text. I even tried saving
 it as a separate script and invoking it via osascript and had no luck.
 Again, that works just fine on the command line calling it directly,
 but not from within the app.

 I'm utterly stumped. Is there something simple I'm missing? An option
 to turn on?

 Is there some other approach I should try instead?

 -Jim
 ___

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

Request for beta testers/feedback for programmer utility [please reply off-list]

2011-05-04 Thread Jim Thomason
All,

I've written a small-ish mostly background clipboard/macro type
utility and was wondering if anyone would be interested in helping me
beta test/provide feedback.

It's simply a way to store and insert frequently used snippets of text
in a very fast manner. I wanted something to pop in, give me the
snippets of text I need, then vanish so I can get back to work. I know
there are existing utilities for this, but they didn't quite meet my
needs.

I know that it's general purpose, but it's most glaringly obvious as a
programmer utility tool, so I figured I'd go to the source and see if
I could recruit some more programmers to take a look at it. It's great
for stubbing out code and inserting frequently used blocks of text.

I'm intentionally being a bit vague here because I don't want to
accidentally clutter up the list with lots of discussion traffic on my
specific thing. But if anyone'd be interested in taking a look and
helping me make sure it's properly fleshed out, looks useful, etc,
then please reply off list and I'll hook you up.

Thanks,

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


how can I copy from another app?

2011-05-04 Thread Jim Thomason
I know this has been asked a bajillion times before, yet here we are.

So it turns out that my simple little applescript to copy in from
another app was ineffective. Lots more digging around led me to create
this:

tell application Xcode
activate
tell application System Events
tell application process Xcode
set frontmost to true
keystroke c using command down
end tell
end tell
display dialog (the clipboard)
set foo to path to frontmost application
display dialog foo
end tell

which is currently hardwired to Xcode and has a couple of dialogs for
debugging purposes. Yes, yes, I know that blissfully assuming that
command-C performs a copy operation is less than ideal. Best option
I've seen so far.

Here's the annoying bit - this works just fine when run from the
Script Editor. But when I run it within my app by firing it off via an
NSAppleScript call, it fails and copies no text. I even tried saving
it as a separate script and invoking it via osascript and had no luck.
Again, that works just fine on the command line calling it directly,
but not from within the app.

I'm utterly stumped. Is there something simple I'm missing? An option
to turn on?

Is there some other approach I should try instead?

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: how can I copy from another app?

2011-05-04 Thread Jim Thomason
 and without knowing what others have said, I can surmise that their replies
 where no less perplexed with the question but Why?

This gloriously ugly hack isn't the correct why question - the
correct why question is why do I even need to do it?

I want to be able to copy the current selection from another app so I
can use it in mine w/o requiring the user to do the copy first
themselves. The standard hacks when slogging through the net about
this are to either use an Apple Script along these lines (some
advocate opening up the Edit Menu then selecting the Copy item, which
is comparably fragile), or packing up and sending in Apple Events to
emulate the keypress. As I understand it, those are fragile for
different reasons.

But other than resorting to hacks like this there is, AFAIK, no way to
get the selected text from any other arbitrary app. If you have a
better solution, I'd love to hear it.

Using the pasteboard isn't the right approach at all, since there's no
data on the pasteboard as of yet. I'd need to get it onto there before
it can be copied off.

And no, before it's suggested, using a service isn't appropriate in
this case for several reasons, mainly that I want to invoke my app
with some input (or no input), and then conditionally provide output.
I'd love to use a service instead, but AFAIK it won't bend to those
constraints.

So back to my original question and issue - this hack works great when
run from Script Editor, but when invoked via NSAppleScript. It will
-sometimes- work if I embed a standalone script into my app and shell
out to it.

Oddly enough, I discovered quite by accident that if I left both in
there (both invoking via NSAppleScript AND shelling out to the
external one), it'll always work. But that's a hack bordering on the
insane.

I assumed that it was somehow a timing issue and that by doing it
twice I was slowing things down enough for it not to trigger, but I
wasn't able to fix it by adding delays into my app anywhere. The two
calls is the only approach I've got functional right now.

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Service with optional input

2011-04-30 Thread Jim Thomason
I've been working on implementing a new service in my app. It's coming
along, but there's one thing I haven't been able to discern in the
docs -

Can I provide a service with optional input?

I want the user to be able to call the service with a text string
input, but it's also reasonable to call it w/o any input at all. Is
there a way I can implement that?

I tried setting it up as two separate services - one with input and
one without, but then I end up with two services showing up when any
text is selected. Not what I want.

Further, ideally I'd just like a single key combo to invoke it.

Any ideas about how I can implement it?

-Jim...
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


registerUndoWithTarget:selector:object: in or outside of group?

2011-02-24 Thread Jim Thomason
This is a braindead simple question, but I couldn't find a definitive reference.

Is it better to register an undo action inside or outside of a group?

i.e., is this preferred:

[someUndoManager beginUndoGrouping];
//do interesting things

//end group first
[someUndoManager endUndoGrouping];
//then register undo statement
[someUndoManager registerUndoWithTarget:self @selector(undoSomehow:)
object:magicalObject];

Or is this:

[someUndoManager beginUndoGrouping];
//do interesting things

//first register undo statement
[someUndoManager registerUndoWithTarget:self @selector(undoSomehow:)
object:magicalObject];
//then end group
[someUndoManager endUndoGrouping];


I'd always done it the former way, closing my group first and then
registering my undo target, and as far as I could tell it worked fine.
But in trying to debug an issue, I reached a point where I started
getting exceptions about registering my undo statement when no group
had been begun. So on a whim, I swapped it to the second method, and
that seems to have been the cure for what ailed me.

But now I'm trying to confirm if that is a correct fix, or if it's
just masking some other issue in my code (well, or both, I suppose).

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


CoreData migration opens ~ file by mistake

2011-02-22 Thread Jim Thomason
I'm finally trying to do my first CoreData migration using the new
style 10.5 built-in migration tools. I'd abandoned my ad-hoc Tiger one
a while back and finally needed to migrate.

I'm building on Snow Leopard, and bugs and glitches aside (such as the
workaround for migration for Leopard deployment built on Snow
Leopard), it's mostly working. But what it boils down to is when I
deploy it on Leopard, the migration is correctly performed, but then
the app insists upon re-opening the foo~.ext file (the backup with the
tilde) instead of the actual upgraded data file itself. The simple
solution is just to shut the doc w/o saving, then re-open it. All
problems solved when I do that, but I don't really want to ask my
users to do it.

It behaves just fine on Snow Leopard.

I found some old posts referencing the issue, such as:
http://lists.apple.com/archives/cocoa-dev/2009/Nov/msg01431.html

But no functional solutions. I tried implementing mmalc's custom
NSDocumentController subclass, but the issue persisted. So I dropped
it out and left just the standard modification to
configurePersistentStoreCoordinatorForURL: to turn on
forKey:NSMigratePersistentStoresAutomaticallyOption.

Sometimes the ~ pops up in the title bar, sometimes it doesn't. The
doc is never actually save-able.

Did anyone ever discover a viable solution?

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


NSCalendar dateByAddingComponents: yields inconsistent results

2011-02-19 Thread Jim Thomason
I'm utterly stumped.

I haven't managed to boil this down to a succinct test case yet. It
only intermittently appears, basically, after I end up doing a lot
of date calculations on a separate thread. For some nebulous value of
a lot.

The gyst is this - on occasion, NSCalendar's
dateByAddingComponents:toDate:options: is returning a nonsense value.
With the sample data I'm working with, I'm just creating a date
component with day value of 1 and everything else explicitly
initialized to zero.

For whatever it's worth, here's the method I'm using:

-(NSDate*) dateByAddingYears:(NSInteger) years months:(NSInteger)
months days:(NSInteger) days toDate:(NSDate*) date {
  NSDateComponents* delta = [NSDateComponents
deltaDateComponentWithYears:years months:months days:days];

  NSDate* rv = [[self gmtCalendar] dateByAddingComponents:delta
toDate:date options:0];

  if ([date compare:rv] == NSOrderedDescending  years == 0  months
== 0  days == 1) {
NSLog(@TOTAL FAILURE); //breakpoint here
  }


  return rv;
}

Sometimes (not even close to always, or even often), I bomb into the
total failure log statement and stop at the breakpoint.

At that point, inspection in the debugger yields nonsense results:
(gdb) print-object date
2013-10-23 00:00:00 +
(gdb) print-object rv
4713-02-19 00:00:00 +
(gdb) print (int) years
$4 = 0
(gdb) print (int) months
$5 = 0
(gdb) print (int) days
$6 = 1
(gdb) print (int) [delta year]
$7 = 0
(gdb) print (int) [delta month]
$8 = 0
(gdb) print (int) [delta day]
$9 = 1
(gdb) print-object [[self gmtCalendar] dateByAddingComponents:delta
toDate:date options:0]
2013-10-24 00:00:00 +

the return value (rv) is inconsistent - in this case it happens to
show up in the year 4713. It frequently shows up at year 0, but again,
not always.

As you can see, I'm handing in 0,0,1, and my NSDateComponents object
ends up with just a change of +1 days.

Finally, note that if I try creating a new date, it succeeds. Further,
it -always- succeeds this second time in the debugger.

My gmtCalendar and deltaDateComponents:... are just wrapper methods -
I return a static NSCalendar set to GMT, and a pre-existing
NSDateComponents if I've already made one. Those are static class
variables that get looked up.

It almost seems to be related to my gmtCalendar method. If I take it
out, and instead just create a new one each time, I can't make it fail
here. When I put it back in, it will fail occasionally as before. I
don't see anything suspect with my gmt method.

Here's my gmtCalendar method:

static NSCalendar* gmtCalendar = nil;
-(NSCalendar*) gmtCalendar {
@synchronized(self) {
if (gmtCalendar == nil) {
NSLog(@NEEDS NEW GMT!);
NSCalendar* newGMTCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
[newGMTCalendar setTimeZone:[NSTimeZone timeZoneWithName:@GMT]];
gmtCalendar = newGMTCalendar;
}
}
return gmtCalendar;
}

I'm completely stumped for ideas. Has anybody ever seen any odd
behavior like this with NSDateComponents?

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: NSCalendar dateByAddingComponents: yields inconsistent results

2011-02-19 Thread Jim Thomason
 Is this method called from different threads? NSCalendar is
 thread-unsafe (not to be shared across threads):

Gaaah. Yes, that's exactly it. I'm glad I tracked the issues with
gmtCalendar and posted the method.

I re-wrote it to use the threadDictionary instead of a static and all
my problems magically went away. 4 hours of my life I'd like back.

Many thanks,

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Crash in NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:

2011-01-27 Thread Jim Thomason
 Well, no. 'error' is an OUTPUT ONLY pointer. Specifically, on entry:

 1. 'error' is either NULL (no error information should be returned), or a 
 valid address to return a NSError* into, if an error occurs
 2. '*error' is trash (-- subtle, but important)

 On output:

 1. If 'error' was NULL, you of course don't try to return anything
 2. If 'error' is non-null and you return NO, '*error' must point to a valid 
 NSError object that you created
 3. If 'error' is non-null and you return YES, '*error' does not need to be 
 preserved (you can set it whatever trash you want) (-- subtle but important)

 If I read your post correctly, you're trying to interpret '*error' as input, 
 which is a no-no.

No, not quite. More accurately I was assuming that error is explicitly
a pointer to nil upon entry (or, I suppose, a pointer to some other
valid NSError that appeared from somewhere and was handed through to
us).

So basically the important thing is that setting error to something
(even a nil, at a minimum) is required if writeToURL:... returns NO.
Which makes sense if the input pointer could be garbage. And
specifically, the fix that I came up with of explicitly setting *error
= nil is the proper fix.

Otherwise, returning NO without explicitly setting the error parameter
will result in a dangling pointer and undefined results.

I still think this is a bad thing. At a minimum, I'd consider it a
documentation bug where the docs need to explicitly state that you
have to assign to it in some manner if you return NO. It's possible
that the docs may say that somewhere regarding object pointers handed
in like this in general, but I sure didn't see it in
NSPersistentDocument's.

I'm not that up on my pointer allocations. Is there some
memory/performance reason why it isn't explicitly set to a nil first?
Personally, if I'm using one of these methods that takes an NSError**,
I always hand in a pointer to an explicit nil to ensure the space is
wiped clean.

Incidentally, it originally manifested for me because I have some
fancy code to combined complex errors into a single message for
display purposes so as not to display a Multiple Validation Errors
Ocurred message. That code was what was assuming that it'd be given
either a valid NSError or nil, because it's called very recursively
internally elsewhere in the code.

Thanks for the info this makes it much more clear.

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Crash in NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:

2011-01-26 Thread Jim Thomason
This is an extremely odd bug I just encountered, and it appears to be
in NSPersistentDocument.

Here's the deal - my coredata app implements
writeToURL:ofType:forSaveOperation:originalContentsURL:error: so I can
do some final sanity checks on my data before saving. If the checks
succeed, we bubble up to super and write as normal. If they fail, it
records the error and returns NO. All pretty standard stuff.

The problem is, in my case, if there's a failure, it'll only
successfully fail once. So I save it once and it's fine, reports the
error, we carry on. If I keep trying to save and getting the error,
then after 2-4 attempts at it I'll get a crash with EXC_BAD_ACCESS. As
best as I can tell, it's on the error pointer.

Some trivial checks indicate that subsequent calls to writeToURL:...
keeps tossing in the same error address. It just seems that at some
point after the first call, it gets populated with...something. Which
in turn invokes a crash.

I almost duplicated this with a trivial test case:

http://www.prototypesite.net/persistentdocumentcrasher.zip

You can recreate it on your own, too. The trivial test case there is
simply an empty CoreData Document based app. The only modification is
the addition of this method to the NSPersistentDocument class:

- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName
forSaveOperation:(NSSaveOperationType)saveOperation
originalContentsURL:(NSURL *)absoluteOriginalContentsURL
error:(NSError **)error {
NSLog(@CAN WRITE WITH %p %@ [%@], error, *error, self);
return NO;
}

The NSLog is superfluous, the issue exists whether or not it is there.
Once that's in place, the write will always fail. Here's the result of
trying to save 2x:

2011-01-26 23:31:47.025 Crasher[38797:a0f] CAN WRITE WITH
0x7fff5fbfe308 (null) [MyDocument: 0x10044f2f0]
2011-01-26 23:31:48.888 Crasher[38797:a0f] CAN WRITE WITH
0x7fff5fbfe308 MyDocument: 0x10044f2f0 [MyDocument: 0x10044f2f0]
2011-01-26 23:31:48.888 Crasher[38797:a0f] -[MyDocument
localizedFailureReason]: unrecognized selector sent to instance
0x10044f2f0
2011-01-26 23:31:48.897 Crasher[38797:a0f] Exception detected while
handling key input.
2011-01-26 23:31:48.897 Crasher[38797:a0f] -[MyDocument
localizedFailureReason]: unrecognized selector sent to instance
0x10044f2f0


The first save is fine - pointer to the NSError and a null value. But
the second one gets weird. You can see that suddenly my error pointer
is now pointing to my document (at the same memory address as self),
and that's presumably causing all hell to break loose. In short, WTF?

The trivial test doesn't crash like my app does, but I'll chalk that
up to my real app being a real app with more stuff in it.
Incidentally, adding in the same log line to my app moves the crash to
the NSLog, so presumably it ends up pointing to an invalid address.
But it's clearly demonstrating different behavior upon re-entering the
method, which indicates to me that something's clearly not set up
right. I'd expect identical behavior upon every single entry.
Something changes here.

It can be trivially repaired by just setting *error = nil upon entry
into the method. That wipes out whatever is dangling around and then
everything behaves correctly. But that's a dippy fix - I should be
able to assume that the error pointer that Cocoa is generating for me
is valid and I can just work with it w/o explicitly wiping it out
first, right?

This is with XCode 3.2.5 on MacOS X 10.6.6. I'm filing a bug report,
but also wanted to raise to the list in case anyone else had
encountered it before and could shed some light on the situation.

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Any way for a managed object to get at its document object?

2010-10-07 Thread Jim Thomason
On Thu, Oct 7, 2010 at 5:14 PM, Rick Mann rm...@latencyzero.com wrote:
 I have an NSPersistentDocument-based app. I need to implement a setNeedsFoo 
 method on the managed object that causes the receiver to be placed into an 
 NSMutableSet on the document, for later foo processing. As part of being 
 added to the set, it sets a timer in the document so that this set of objects 
 gets processed.

 I don't see any obvious way of getting at the document. Any suggestions? 
 Thanks!

I've used this little snippet in my code for years w/o issue. It's
always felt like an extreme hack, but I couldn't tell you a better way
to do it.

I created a superclass for all of my managed objects, which is just a
subclass of NSManagedObject. That class gets one extra method:

-(MyDocument*) document {
return [[NSApp delegate] documentForManagedObjectContext:[self
managedObjectContext]];
}

That's just a wrapper to a method defined on the delegate. Then in my
app delegate:

-(id) documentForManagedObjectContext:(NSManagedObjectContext*) context {

for (id doc in [[NSDocumentController sharedDocumentController] 
documents]) {
if ([doc managedObjectContext] == context) {
return doc;
}
}

return nil;

}

Obviously, that's Leopard only due to the fast enumeration, but you
can refactor it back to an NSEnumerator easy enough if you need Tiger
support.

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Tracking Area resets to view's bounds

2010-09-28 Thread Jim Thomason
I'm utterly confused by what I thought would be something simple.

I have a custom view that I want to establish a few tracking areas
for. So I go and create several NSTrackingAreas and add them to the
view. All looks well. But later on, when my mouse events fire off,
they're associated with the ENTIRE view, not just my tracking area.
Even more bizarre, the tracking area at the memory address I
originally created has had its associated rect adjusted to be the
view.

I've boiled it down to a trivial test case.

- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
//this one ends up with a tracking area encompassing the entire view
[self addTrackingArea:
[[[NSTrackingArea alloc]
initWithRect:NSMakeRect(100, 100, 50, 50)
options:NSTrackingActiveInKeyWindow
 | NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved | NSTrackingInVisibleRect owner:self userInfo:nil
] autorelease]
];

//this one works as expected
[self addTrackingRect:NSMakeRect(100,100,50,50) owner:self
userData:nil assumeInside:NO];

NSLog(@HAS TRACKING AREAS %@, [self trackingAreas]);
}
return self;
}

- (void)mouseEntered:(NSEvent *)theEvent {
NSLog(@MOUSE ENTERED  IN %@, [theEvent trackingArea]);return;
}

If I do it new-style with addTrackingArea, then the entire view
becomes my tracking area. If I do it old-style with addTrackingRect,
it behaves as I would've expected. For example, doing it with tracking
areas:


2010-09-28 13:26:41.564 TrackingAreaTest[32602:a0f] HAS TRACKING AREAS (
NSTrackingArea 0x100621760: rect={{100, 100}, {50, 50}},...)
2010-09-28 13:26:43.122 TrackingAreaTest[32602:a0f] MOUSE ENTERED  IN
NSTrackingArea 0x100621760: rect={{0, 0}, {400, 400}}, ...
2010-09-28 13:26:43.539 TrackingAreaTest[32602:a0f] MOUSE EXITED FROM
NSTrackingArea 0x100621760: rect={{0, 0}, {400, 400}}, ...

Same tracking area (or same memory address, at least), but different
rectangles. Only difference I can see is that the first one (called
right after I set it) has extra flags of pendingInstall notInstalled
disabled. The one I get from mouseEntered is installed enabled.

I'm completely stumped. Surely I'm doing something horribly stupid,
but bugger all if I know what it is. What do I need to do to make it
work?

Sample code at:
http://www.prototypesite.net/trackingareatest.zip

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


What's the point of @properties?

2010-09-19 Thread Jim Thomason
I'm refactoring and updating a lot of my older code, and one of the
things I'm finally looking into is declaring things as properties.

But...what's the point? I've been trying to read up on the subject and
have found a lot of posts and discussion about the subject, but very
little of it seems to get down to the meat of what these things are
and why I should care about them.

At the simplest level, I just look at them as some syntactic sugar. So
I get to write one @property line in my @interface and one @synthesize
line in my @implementation (assuming no more complicated behavior, of
course). So it's nifty in that I save myself a lot of redundant
typing, but realistically? I could accomplish the same thing with a
preprocessor macro and have more fine grained control over exactly how
my generated methods look. I mean, it's cool and all that it's built
in and saves me from writing my own macro, but realistically this
isn't terribly interesting.

I know I'd get use of the dot syntax (I do need to use @properties to
do that, right?), but I'm eschewing it anyway. Again, I've seen all
sorts of arguments about people disliking it because it's not
objective-Cish or confusion about structs or whatever, but for me, I
simply just don't care to use it. I've got lots of existing code that
uses methods and I don't see any reason to update. I'm just a stick in
the mud sometimes.

So basically, I get a language built-in version of a macro, and an
option to use a new syntax that I'm not interested in anyway.

Is there something else I'm not seeing or some other utility to them
that I don't yet understand?

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Migrating changed objects between contexts

2009-12-02 Thread Jim Thomason
 It shouldn't deadlock. The doc for -lock says: If you lock (or successfully 
 tryLock) a managed object context, the thread in which the lock call is made 
 must have a retain until it invokes unlock. If you do not properly retain a 
 context in a multi-threaded environment, this will result in deadlock. Did 
 you heed it?

It didn't matter one way or the other. Incidentally, I've seen that
warning too, but in this case I was sharing the [document
managedObjectContext] across threads, so it was guaranteed to exist as
long as the window was open. What was the need to retain it in that
case, anyway?

Sigh. Nevermind, I'm an idiot. My worker thread that refreshes my
graph does 3 different things in it. 1 is fairly old and has been
around for months, the other 2 things are newly added.

The original one ended up calling rearrangeObjects on an array
controller, and since that's not threadsafe (right?) I dispatched the
call to the main thread, and helpfully set waitUntilDone:YES. That was
fine originally, since the app was guaranteed not to be looking at the
context in the main thread, and basically I got lucky and could get
away with it.

But now, due to additional processing in the main thread, it was
looking at the context. So my worker thread would happily chug along
until it reached the rearrangeObjects call. It'd hand it off to the
main thread and wait for it to finish. But the main thread was paused
since my worker thread had the lock on the context. And blamo.
Deadlock.

Solution? Disturbingly easy to see now 12 hours into trying to fix it.
Just do the rearrangeObjects on the main thread as before, but set
waitUntilDone:NO. All problems miraculously fixed.

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Migrating changed objects between contexts

2009-12-01 Thread Jim Thomason
I'm stumped and hoping that there's some easy solution that I just
haven't dug up yet. Yes, this is another coredata multithreading
question.

Anyway, in my application the user types in data and fills out forms
and such. It's all tied into CoreData via bindings. Nothing exciting.
But - I've also got a separate thread that wakes up when the data is
changed (via notifications) and updates a graphical representation of
what was typed in. So the user types in the values and my separate
thread reformats it into a graph.

Up until tonight, I'd managed to get away with using the same managed
object context in both threads. I was careful to lock and unlock it in
my second thread, and it seemed to work ok. Unfortunately, I've
expanded the graphing that happens in my second thread, and now I
can't get the thing to run without deadlocking. So I'm looking into
doing it the right way and having one context per thread and handing
around objectIDs to determine what to load. This works fine, as long
as the changes have been saved to the store so my secondary thread
picks them up.

But I don't know a good method to migrate any unsaved changes from one
context to another and that's what I'm looking for. Otherwise, I can
just hand along the IDs and load up my objects to graph them. But I
gotta get those changes moved over.

So. First off, is there some way I can just leave the existing code in
there that uses the same context and just locks it in the secondary
thread? The second thread basically consisted of:

-(void) makeGraph {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  [[document managedObjectContext] lock];
  //big honkin' code to make the graph
  [[document managedObjectContext] unlock];
  [pool release];
}

But since both the second thread and the main thread were trying to
load up the same object at once, it deadlocked. Is there some other
bit of locking magic I can add in to do it?

Otherwise, is there some slick, quick easy way to get the changes from
the first context into the second? Presumably, this needs to be done
from the main thread. So I'd create the secondary context in the main
thread (guaranteed not to be used by anyone else), copy the changes
over, then hand it off to the thread. If I tried copying from the main
context in the secondary thread, I assume I could end up with the main
thread trying to access my main context and another deadlock. I'm
somewhat concerned that this could negate my performance gains by
using a separate thread if I just have to do all of this copying and
initialization in my main thread before handing off to the background
one.

However, to do this right I'm going to need to end up writing a lot of
migration code to move from one context to another. I can do it, but
if there's a better way w/o handrolling my own copying routines,
that's clearly what I'd prefer. The added caveat is that I'm still
trying to target Tiger, so none of the whizbang cool coredata features
added to Leopard will help me. If there's a simple method in Leopard
that lets me do it, though, I'll consider abandoning Tiger.

It seems like this would be a common problem with an easy solution.
Otherwise, all the talk about using multiple contexts seems rather
moot if I can't see unsaved changes, am forced to save in advance, or
have to write my own routines to copy the objects myself.

So am I missing some elegant built-in solution that will Just Work for me?

Many thanks,

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: CoreData could not fulfill a fault after Save As

2009-10-14 Thread Jim Thomason
On Wed, Oct 14, 2009 at 2:25 PM, Ben Trumbull trumb...@apple.com wrote:
 The short description is this - I have a document based CoreData app.
 I can carefully craft a set of data. I then open the document, select
 a particular record, and do a Save As. This works fine. But when I
 select a second record, I get errors that CoreData could not fulfill a
 fault. If I quit the app and re-launch it, I can operate on the copy I
 just saved w/o issue, so apparently the data is there. I haven't a
 clue what the problem is.

 Does your app run correctly on 10.5.* ?  There's a known regression similar
 to this in 10.6.0 and 10.6.1.

 If this reproduces on a system other than 10.6.0 or 10.6.1, please file a
 bug.

Thank you, that was the puzzle piece I was missing. I was indeed
running on 10.6.1. I deployed over to my other box running 10.5.8 and
set up  an identical test. No problems whatsoever.

So I'll stop banging my head against the wall and sit back and wait
for the bugfix.

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: grouping undo across method calls in CoreData [with possible solutions]

2009-10-06 Thread Jim Thomason
Figured I'd address all the comments inline in one batch, and then
point out what I came up with. An almost viable solution is up top for
reference purposes, and a seemingly better one is towards the bottom.

Hm, do operations using primitive accessors also get registered on the undo 
stack? If not, you could maybe use that approach, so the setting of the 
ordered value would not ever get registered?

This actually worked in that I didn't end up with the extra undo
into the interim state, but the array controller put the objects into
the wrong row. My array controller was sorted on the ordered value,
and by setting it through the primitives, the notes never fired to
re-sort it. Firing the KVO notes myself fixed it, but that also added
an empty frame onto the stack again, so back to square one.

I was able to make this work by subclassing NSArrayController and
overriding addObject: to fetch immediately afterwards.

-(void) addObject:(id) newObject {
  [super addObject:newObject];
  [self fetch:nil];
}

In fact, using this approach, I didn't need to detach the selector at
all and could just set the value in awakeFromInsert:, though I don't
have any idea if not detaching and setting it directly is going to
cause other bad problems. But, there's a slight visual hiccup
sometimes using this approach - When I tried integrating it into my
actual app, you could briefly see both items appear and then one
vanish. As a result, I'm not thrilled with using this approach.

Also note that it wouldn't scale well, since it'd cause a refetch of
the entire array's contents upon every insert. Fortunately, I have
fairly small object sets, so this may be viable for me.

I hope I list a better idea at the end of this email.

I guess it is tricky dealing with begin/endUndoGrouping when using delayed 
invoking. Still, AFAIK it should work. Can you elaborate on why it does not?

I don't remember exactly what was happening with it, I could make it
crash, but haven't been able to reproduce in simplified test cases so
I'm assuming the error existed elsewhere. Regardless in further
testing, if I begin/end in the method performed after the delay, it
has no effect and I still need to do it in two steps. If I begin in
awake from insert and end in the method after the delay, I get the
duplicate row on the array controller.

I also tried popping all references to the newly created object off
the stack and using prepareWithInvocationTarget: with a method that
just drops the object:
Which extra undo state do you have? What is the registered undo that does 
nothing?

The problem was that the object's creation apparently creates two
separate sets of undo information - one for the object itself, and one
for its managed object context. I remove the undo actions for the
object, but can undo twice because one undo calls my prepared
invocation, and the second undo undoes the object add that the context
performed.

That's also why I can now redo twice and create a ghost object - my
object is recreated, but the managed object context also redoes its
object insertion, so it shows up as a default object with no post-set
values. Further, I refer to it as a ghost since it doesn't actually
exist - if you save the document and re-open it, the ghost vanishes.

If I try to use the undo manager to remove all actions on the context
(a dangerous action anyway, since I'm not sure what other existing
actions may be there), I can still undo twice. But this time, once the
doc is back in its clean newly opened state, the context still lists
the ghost as being deleted. An attempt to save here causes the app to
crash, which makes sense, since it'd be attempting to delete a
non-existent object.

I haven't a clue if it's possible to make this technique work.


You might consider a different approach. Instead of trying to bend Core Data 
undo to your will, you might be able to finesse the situation by preparing 
all the information for your object creation *first*, then creating the object 
in a single event cycle (and hence undo action).

I considered this...but that would then require a lot of management
outside of creation to ensure that I'm keeping this cached calculated
value in sync with reality. Including making sure that the cached
value is incremented upon object insertion, and properly decremented
upon deletion (it's decremented only if you delete the highest order
object - if you delete something in the middle, we end up with a hole
in the order, but that's okay, we just keep marching ever upward). So
that would've meant finding places to add hooks for add and delete and
just generally seemed like a mess. I'm pretty sure I would've needed
an additional method call before all deletions, as per an earlier
thread of mine about coredata pre-delete hooks.

===

But, through all of that, I may actually have a viable solution - I
subclassed NSArrayController and added createOrder to my addObject:
method there:

@implementation MyArrayController

-(void) addObject:(id) 

grouping undo across method calls in CoreData

2009-10-05 Thread Jim Thomason
I've got a CoreData document based application, and I'm trying to undo
my object creation in a single step.

Here's the issue - I'm storing an ordered index on my entities so I
can keep track of the order of creation. To do this, upon object
creation, I yank out the highest order parameter for my entity, add 1
to it, and use it to set up my ordered column. But the issue is, in
order to do this and make it work well, I have to put the code to
create the ordered column in a separate selector that I hit using
performSelector:, as such:

-(void) awakeFromInsert {
  [super awakeFromInsert];
  [self performSelector:@selector(createOrder:) withObject:nil afterDelay:0];
}

-(void) createOrder {
  int highOrderIndex = [self getHighestIndexSomeHow];
  [self setValue:[NSNumber numberWithInt:highOrderIndex] forKey:@ordered];
}

If I were to just directly call [self createOrder]; in
-awakeFromInsert, I'd end up with a duplicate entry in my
NSArrayController (though not in the context). AFAIU, that's because I
can't go out and perform queries in CoreData during awakeFromInsert,
and this is the acceptable workaround.

But the problem is, if the user undoes the creation of a new object,
two undos are required. The first one will bump the ordered parameter
back down to zero, and then the second one will actually drop the
object. It's fairly confusing since the ordered parameter isn't
displayed to the user, so it appears that the undo does nothing the
first time, but then works the second.

Even worse - potentially they could hit undo once and end up with an
object in a quasi-state with an invalid order parameter.


How can I deal with this? I've been trying various combinations of
begin/endUndoGrouping, and even turning on and off groupsByEvent, but
I haven't hit the magic incantation yet.

I also tried popping all references to the newly created object off
the stack and using prepareWithInvocationTarget: with a method that
just drops the object:

...
//at the end of createOrder up above
[undoManager removeAllActionsWithTarget:self];
[[undoManager prepareInvocationWithTarget:self] negateCreation];
}

-(void) negateCreation {
  [[self managedObjectContext] deleteObject:self];
}

That gets me closer - it actually does drop the object immediately
upon undo, but I still have an additional undo state on the stack.
That is, I can hit undo once and delete my object entirely, but then I
can hit undo a second time, and seemingly nothing happens. At that
point, I can hit redo twice, and two additional objects will appear.
One with a valid order, and one without. I'm not sure if this approach
is a dead-end or not.

Can anyone point me in the right direction?

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


proper technique for CoreData SQLite fetch with sort descriptors

2009-09-25 Thread Jim Thomason
First off, I'll say that I'm trying to maintain Tiger compatibility in
my app, so if anyone tries to duplicate this on Leopard or Snow
Leopard, they may not have any luck.

I have an NSArrayController bound to a set of objects in an SQLite
CoreData store. The NSArrayController by default has several
NSSortDescriptors associated with it to properly order the objects
(since there are several properties to sub-sort on).

One of those, however, causes it to blow up badly - specifically, I
have it set on keyPath creator.classRank, where classRank is a
method sitting up in my object class that isn't appropriate to stick
into my data store. I get an error about an unresolved keyPath for
creator.classRank. Some digging around yielded this post:

http://lists.apple.com/archives/Cocoa-dev/2005/Aug/msg00797.html

Which is basically the same issue that I'm having - in my case, it's
the keyPath that doesn't exist in the SQLite store that's causing the
fetch to fail. To address it, I overrode fetchWithRequest:merge:error:
in my NSArrayController subclass, as such:

- (BOOL)fetchWithRequest:(NSFetchRequest *)fetchRequest
merge:(BOOL)merge error:(NSError **)error {

//Make a copy of the fetchRequest's sortDescriptors
NSMutableArray* safeSortDescriptors = [NSMutableArray
arrayWithArray:[fetchRequest sortDescriptors]];

//pull out the classRankSortDescriptor (this is a static class
variable which is used initially to populate the controller's
sortDescriptors during awakeFromNib
[safeSortDescriptors removeObject:classRankSortDescriptor];

//reset the sort descriptors to the sanitized version, without the
offending descriptor
[fetchRequest setSortDescriptors:safeSortDescriptors];

//carry on our merry way
return [super fetchWithRequest:fetchRequest merge:merge error:error];
}

This works fine, and I'm not seeing any issues. Proper behavior on
Tiger, Leopard, and Snow Leopard. The fetch executes just fine, and
then the original sort descriptors (with creator.classRank) in my
NSArrayController subclass sort my data appropriately.

I have two questions -
1) Is this the proper technique to use to address this issue? Or is
there a different method I should subclass or technique I should use
instead? This feels kinda hackish, so I want to be sure I'm doing it
the right way.

2) I didn't seem to have any problems just leaving the new sort
descriptor in place on either Leopard or Snow Leopard, this is purely
a Tiger issue. Can anyone confirm if this behavior has changed and
this hack is no longer necessary on Leopard or higher? I wasn't sure
if the behavior had changed to allow this, or if I'd just gotten lucky
somehow due to an unrelated changed in the OS.

Thanks,

-Jim...
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Securely limit the running an application by serial number

2009-07-03 Thread Jim Thomason
 I'm writing a 64-bit only app. Any pointers on where I can find info on
 obfuscation?


 http://unsanity.org/archives/000101.php

In addition to that, don't even think about doing your checks in
objective-C. It's just too easy to hack around, and if somebody's
dedicated to cracking you, it's an easy entry point.

So do it all in C. It's much tougher to crack into.

Once you've written it all in C, then convert it all to a C macro
instead. That makes it excruciatingly difficult to find it. And, at
that point, there is no if statement to crack - the macro duplicates
the code all over the app, so even if somebody hacked into the
assembly and switched it in one place, you've still got unaltered
checks all over the rest of the place.

Raw C executes pretty fast, so you can pepper your app with it. In
completely unrelated methods, even, just to spread out the checks
everywhere.

Wanna get really hardcore? Write 3 different versions of your
validation macro and vary which one you use. That's now 3 different
blocks of assembly that the black hat is going to have to decipher,
disassemble, and hack to get inside.

Sound like too much trouble to you? Well, then security really isn't
that important anyway. :-)

Just remember - it's always an arms race, and the more time you spend
writing security functionality for your application, the less time
you're spending actually developing the stuff that the user cares
about. No end user is going to be impressed at all with your app that
so securely locks them down to a single machine and if that gives your
competition time to catch up with a better feature set, you're in big
trouble.

Oh, I also wrote up an article with my experience in doing some of
this stuff a few years ago. Doesn't specifically address tying to the
hardware, but may be useful for general pointers, too:

http://www.jimandkoka.com/m.cgi/Journal.mchn?state=display_entryjournal_entry_id=283

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Forcing NSTreeController to re-sort, and select inserted

2009-05-22 Thread Jim Thomason
I've been fighting with NSTreeController for a couple of days now and
have gotten nowhere.

I have a hierarchy of disparate objects. It's pretty simple - Class A
has many Class B. That's it. I'd like to display it in an OutlineView.
I don't care about adding in additional Class A (Parent) objects, but
I do care about adding  additional Class B (Child) objects. That's
where the headaches start.

I've tried overriding NSTreeController's addChild: method, and
implementing the same code in an external method in my view's
controller. It works, in that it properly adds the right objects to
the outlineview, but it adds it into a random spot in the outline
view. If I manually re-sort the outline (clicking the column headers),
then the rows slide into the appropriate position. So they're being
placed in the right spot internally in the collection, the tree
controller is just refusing to update the sort order.

I've tried calling [myTreeController rearrangeObjects] and even
[myTreeController setSortDescriptors:(what I need)] and neither seems
to have any effect.

I also tried re-wiring everything to use a proxy class which hid all
of the entities from the TreeController, with the intent of overriding
NSTreeController's newObject method upon creation, but it doesn't
appear to be called by addChild:. Yes, I did change the TreeController
in Interface Builder to indicate that it was now using a class instead
of an Entity. No dice. I was hoping I could do this and just let
addChild: operate as it otherwise normally does and hopefully sort
correctly and select the selected item, but if newObject isn't being
called, I'm stuck.

Any suggestions? I either need to get newObject to be called via
addChild (which I thought should work. Hopefully I'm missing something
obvious), or need to know some way to force the tree controller to
re-sort everything into the proper slot, and select the new item.

And it all has to run under Tiger, naturally. I'm about to give up.

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Changing CoreData store type

2009-04-29 Thread Jim Thomason
Howdy all,

Hopefully this is a ridiculously simple question with a ridiculously
simple answer, but I just haven't been able to find it.

I have a document based CoreData app and I want to change the store
type of the file. So it previously saved as XML, and I now want those
docs to save as SQLite. But, i still want to be able to view the XML
based docs, just require the user to re-save as SQLite. There are no
changes to the model. All the data looks and is structured the same.

So I added a new document type with a SQLite store and a different
doctype and set it to editor. I left the old doc available as an
editable document.

At this point, I can open up an XML document, edit it, save it, and
then re-save it as a SQLite document w/o any issues.

The problem is when I flip the XML doc from Editor - Viewer. I can no
longer save it in place (as expected), but whenever I try to save it
as the SQLite doc, the app crashes. I know that it's bombing somewhere
inside NSPersistentDocument's
writeToURL:ofType:forSaveOperation:originalContentsURL:error:, but
beyond that am lost. In the save document window, the doc type is
correctly set to the new extension for the SQLite store.

Again, when the app is set to editor for XML, I can re-save the doc as
SQLite. When I can only view the XML docs, re-saving as SQLite
crashes.

I've tried all sorts of incantations with PersistentStoreCoordinator's
migratePersistentStore:toURL:options:withType:error:,
addPersistentStoreForURL:, removePersistentStore:error: and have
gotten nowhere. I've also tried explicitly setting the document's
fileType, but have had no luck.

Clearly, this is something that should be easy, since the app handles
it automatically when I can edit the XML docs.

So what do I need to do?

Many thanks in advance,

-Jim
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


CoreData delete clean up

2009-04-24 Thread Jim Thomason
I just can't find a solution for this. Basically, I need a pre-delete
hook in CoreData but can't seem to find one.

Here's the deal - I have a Foo object which has many Bar objects. Foo
also has a property that's calculated off of the various values in
Bar.

So Bar has many custom setKey methods that twiddle the value up in
the Foo object to keep it up to date. All works well and good.

The problem is if I delete a Bar object. I need a way to have the Bar
object revert the cached Foo property to what it would've been had it
never existed. Basically, a pre-delete cleanup hook.

So what happens is, upon delete it marches through all of my setKey
methods in some order to wipe them out and screws up my cached
property. Basically, it ends up backing out the Bar object multiple
times, since while it's knocking out all of the properties, it doesn't
know that the object is actually deleted. Boom. Big mess.

Problems and caveats:
* I can't just have Foo monitor removeBarObject because it's not
guaranteed to wipe out the relationship first. It may have called a
half a dozen custom setKeys in Bar first so I'm still in some
inconsistent state.
* I have to have Bar notify Foo of changes (as opposed to having Foo
observe all of Bar's related properties) since there are relatively
few Foo objects and a -lot- of Bars. Further, the Bars only rarely
change their value. So to have a few Foos monitoring tons of Bars all
the time is just going to create a whole bunch of additional overhead
that I don't want.
* I have to store the property up in Foo, since it can also be
manipulated via other means. That is, I can't just replace the
calculated property with keyPath monitoring of the Bars.
* validateForDelete is called way too late in the process. I watched
it. It's very helpfully called after my object data is wiped out, all
of my setKeys are called, and my object's a mess.
* likewise for isDeleted. Doesn't work as a flag.

Possibilities:
* I can add an explicit flagForDeletion method to my Bar object and
explicitly call this every time I'm going to delete one. This seems
error-prone to me, since I may forget to put it somewhere. Further, it
makes it difficult to use in abstract situations unless I add dummy
flagForDeletion flags to all of my objects just to ensure that I can
always call the method. I know I can do it with a category, but still.
Likewise, I can add that into my ArrayController to handle the
majority of the cases.

For now, I've gone with that approach. the ArrayController's
removeObjectAtArrangedIndex: method calls flagForDeletion, which for
most objects does nothing, but for the Bars properly updates Foo's
property and then flags them as trash so the setKey values won't
update.

I hate having the extra method, though. Is there any better approach I
can use? With in the constraints of the above caveats, of course.

-Jim...
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Report writer for Cocoa?

2009-01-14 Thread Jim Thomason
A lot of people tend to link in webkit and layout a printed report using
html and css. It's somewhat eqasier than standard web dev since you know
that only webkit will be displaying your layout. No need for cross browser
compatability.

I use that aqpproach for one of my apps and it works well enough. Don't get
me wrong - it still feels like a major hack, but thre results are decent and
it was pretty quick and easy to implement.

-jim..

sent from my G1

On Jan 14, 2009 2:13 PM, Jon C. Munson II jmun...@his.com wrote:

Namaste!

I could be missing the obvious, however, my question is whether a report
writer tool (like Crystal Reports or MS Access, by way of example) exists
for Cocoa?

I Googled around for a bit tyring to find something (other than ReportMill).

I've looked at (and read) the printing-relevant Apple dox.  I've read the
relevant chapter in Hillegass' book too.  I can see how much work writing
pretty reports is going to be.

Unless...

I missed a point concerning an NSView - it knows about PDF, etc.

The dox don't really go into this much, so here's a follow-on question to
the first:

If I take the time to draw out a view in IB with all my fields, etc., will
that print as-is?  This, then, would become the report writer, right?

I'm looking for good, solid advice on creating reports.  I do have some
graphics I'd like to include in my reports, but most are lists, and some are
lists with child details too.

Many thanks in advance (and I hope this isn't a Help Vampire question)!!!

Peace, Love, and Light,

/s/ Jon C. Munson II


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/jim%40jimandkoka.com

This email sent to j...@jimandkoka.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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Bindings alert issue

2008-11-11 Thread Jim Thomason
Here's a peculiar little case that I hope is easy to resolve.

Here's the case I ran into:

I had bound an NSTextField to an attribute of an object. The interface
at that point implied that the user could update the value in that
field, then immediately click a button to perform an action. The
problem was that the value wasn't updated yet, since the user hadn't
pressed enter. Just clicking the button apparently isn't enough for
the text field to lose focus and commit the changes.

To fix, I rewired to use an NSObjectController that pointed at my
object, and then bound through that instead of directly to the object.
Then, when my save: method was called, I first called
[myObjectController commitEditing] and checked its return value. If it
succeeded, then there were no validation errors and I continued
saving. If it failed, then I bowed out and presented the dialog to the
user to fix. Worked like a charm - either my field was saved or the
user got an error right away.

The problem is that when the button is pressed the error message
displays in a new window, whereas if the user were to hit enter, the
error message displays in a sheet.

I have a simple little test program to illustrate the issue:
http://www.bassetsoftware.com/osx/bindingsfail.zip

Type in any value to the field. If you type in Microsoft, it fails
with a validation error. If you type it in and hit Return, the error
displays in a sheet. If you type it in and hit the Save changes
button, it displays in a window. It's as if the object controller no
longer knows what window it's associated with, so the sheet displays
as a window instead.

Is there anything I can do differently to get my error to display in a
sheet? Because if there isn't something else I can do, I'm going to
consider this a bug and file a report.

Thanks,

-Jim.
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


NSCalendarDate has subsecond precision

2008-08-15 Thread Jim Thomason
Wow. I just spent about an hour and a half debugging this, since it's
rather nefarious. Now I need to go back to all sorts of existing data
and correct for it, too. :-(

Anyway, I'm just posting to the list as an informational thing just in
case anybody else runs into a similar issue. I wasn't having any luck
with what I was googling for, so I figured another post would be
useful. Personally, I think this constitutes a bug in NSCalendarDate
(since there's no way to specify the submillisecond precision it's
using) and am going to file a bug indicating as such.

First of all, the origin of this. I had a little method that returns
today at midnight. Basically, I just created an NSCalendarDate
object with [NSCalendarDate date] and subtracted off the current
hours, minutes, and seconds to yield today with time values of
00:00:00. That worked just fine, and for today (for example), I got a
nice value back of: 2008-08-15 00:00:00 -0500.

I encountered a problem today when I hit the case of comparing two
objects both created to be today at midnight (got me how I didn't
hit it before). The issue is that NSCalendarDate internally has
subsecond precision, but there doesn't seem to be any way to get or
set that information, other than via timeIntervalSinceDate et. al.

So two different NSCalendarDates created by using this method would
actually have slight subsecond variations in their time, based upon
when the todayAtMidnight method was called.

Solution? I tweaked the method. Instead of subtracting off from the
now value, I create a new NSCalendarDate and set the year/month/day
to today's, and leave everything else 0. That has the additional
effect of leaving the subseconds set to 0.

Incidentally, if anybody has a more clever way of creating such a
method, I'd love to hear it. It's my understanding that natural
language strings (today at midnight) use is strongly discourage, so
I'm trying to avoid it. Or I'll just stick with my new method, since
it works.

Here's a test case to look at. Sample output would include:

kent:~ jim$ ./test
2008-08-15 16:26:30.263 test[96256:10b] 2008-08-15 00:00:00 -0500 =
2008-08-15 00:00:00 -0500 == 1 (seconds apart: 0.262046)
kent:~ jim$ ./test
2008-08-15 16:26:30.547 test[96257:10b] 2008-08-15 00:00:00 -0500 =
2008-08-15 00:00:00 -0500 == 1 (seconds apart: 0.546184)
kent:~ jim$ ./test
2008-08-15 16:26:30.814 test[96258:10b] 2008-08-15 00:00:00 -0500 =
2008-08-15 00:00:00 -0500 == 1 (seconds apart: 0.813310)

That one was sneaky. Hopefully this'll help somebody else.

-Jim..

#import Foundation/Foundation.h
#include stdlib.h

/*And you can compile it on the command line with: cc -Wall -o test
-framework Foundation DateCompare.m */

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSCalendarDate* today = [NSCalendarDate date];

NSCalendarDate* todayAtMidnight1 = [today
dateByAddingYears:0
months:0
days:0
hours: -[today hourOfDay]
minutes: -[today minuteOfHour]
seconds: -[today secondOfMinute]
];

NSCalendarDate* todayAtMidnight2 = [NSCalendarDate
dateWithYear:[today yearOfCommonEra]
month:[today monthOfYear]
day:[today dayOfMonth]
hour:0 minute:0 second:0 timeZone:[today timeZone]
];

NSLog(@%@ = %@ == %d (seconds apart: %f),
todayAtMidnight1,
todayAtMidnight2,
[todayAtMidnight1 compare:todayAtMidnight2],
[todayAtMidnight1 timeIntervalSinceDate:todayAtMidnight2]
);

[pool release];

return 0;
} // main
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]