How do I get data out of NSRuleEditor?
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...
> 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...
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...
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?
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?
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
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?
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?
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?
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?
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
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
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
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?
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
-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
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?
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?
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]
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?
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?
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
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?
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
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
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
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:
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:
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?
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
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?
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
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
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
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]
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
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
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
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
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
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
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?
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
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
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]