Core data app does not save my data, why? - cocoa

I am writing my first core data app. For some reason, my edits are gone after quitting and restarting the app. Saving, closing window, and re-opening (without quitting) retains the data. If I open the saved file in textedit, I see my edited field. Something must go wrong during reading. Perhaps I forgot to change a setting somewhere? Does anyone recognize this behavior?

Are you saving the NSManagedObjectContext after making changes to your model objects?
Try
NSError *error;
if (![myContext save:&error]) {
// Handle error
}
The save message returns a BOOL for success. You should check that value to see if the save was successful. If not, the NSError reference that you pass in will contain information on why the save may have failed.
If you post your code, I might be able to help further.

The array controllers should have "prepares content" turned on. Otherwise, loading does not populate the array, and another save permentently removes the edits!

Related

Assertion error when using NSCollectionView with QLPreviewView

I am using an NSCollectionView where each NSCollectionViewItem uses a QLPreviewView to get a rendering of a file's content.
(This is an attempt at a file browser for images and other previewable files.)
Initially, this works fine.
However, once collection items are getting re-used, I get an assertion error (both in 10.13 and 10.14):
[QL] Assertion failure (unreachable code) - [… MyPreviewView activated … doc:[QLPreviewDocument …]] is already activated
Apparently, before I can re-use a NSCollectionViewItem, the previously used QLPreviewItem needs to be set to inactive state somehow. How do I do that?
I've tried to send the close message to the QLPreviewView instance but that doesn't make a difference.
I also do not get a dealloc call on my QLPreviewView subclass, which suggests that the object is still referenced by something else, possibly the QLPreviewDocument, which then gets confused about the change of state.
I have made a demo project available on github: https://github.com/tempelmann/NSCollectionViewWithQLPreview
To test: Run it, then scroll down. When reaching items 50 to 60, the assertion will be triggered.
The fix is to set QLPrewiewView's shouldCloseWithWindow property to NO.
This, I suspect, tells the controller behind the scenes not to attach itself to higher level structures, i.e. tells it to remain self-sufficient.
So, adding this line to the code that sets up a new MyPrewiewView object in the sample code's ViewController.m file prevents the error:
qlView.shouldCloseWithWindow = NO;

dequeueReusableCellWithIdentifier never returns

When I call dequeueReusableCellWithIdentifier it is freezing my code and does never return any cell (or nil) I change the code from my custom class to a UITableViewCell to be sure the problem wasn't in my class, I also create a brand new empty cell to call with the identifier.
I add a log before and after the call for dequeueReusableCellWithIdentifier as you can see in the screenshot the one before gets called once and the one after never.
I try to clean and build, clean the project folder, delete DerivedData, restart the computer. I can't see any exceptions or what is really holding the code.
Any suggestions?
I am not sure what happened to XCode, but, if someone find the same problem here is what I had to do.
I didn't find anything wrong with the cell (yes I was using storyboard and the identifier was set correctly) and noting was wrong with the code in the custom class as well. I even went to the point of create a secondary custom class and custom cell and it did not help, so I try to put a invalid identifier and even there XCode did not return me an error (as it should).
I had to delete my custom cell from the storyboard, as soon as I did that all start to work again, first the error that the identifier didn't exist, than the temporary one start to work, than I recreate the original one (exactly as before) and all start to work again.
Very overkill but worked for me. Thanks for all the help!
It is expressed that you are printing println("return dequeueReusableCellWithIdentifier"), but can't see your return cell code at the end of your function, that must conform to your function expectation.

How to Fix Error: Incompatible Pointer Types Assigning to

Let me preface this by saying I'm new so I might not be the best at asking questions but here it goes. I am getting this error when I hit build in XCode with this code.
-(IBAction)unwindToRecipeDetails:(UIStoryboardSegue*)segue
{
ChangeRecipeDetailViewController *source = [segue sourceViewController];
recipeLabel = source.textView; // error: Incompatible Pointer Types Assigning to UILabel from UITextField
}
Here's what I'm trying to do. I based the code off of this snippet which works...
-(IBAction)unwindToRecipeBook:(UIStoryboardSegue *)segue;
{
AddRecipeViewController *source = [segue sourceViewController];
RecipeItem *item = source.recipeItem;
}
This is supposed to make AddRecipeViewController the data source for the initial RecipeBook page when the user navigates backward. I'm trying to implement the same thing for when a user navigates backward from the ChangeRecipe page to the RecipeDetails page.
Apparently I mixed two different types of code in the error, UILabel and UITextField. I get that they are incompatible but what could I change either one to in order to make it work. It is a little different than what I am basing my code off of in that I don't just want to transfer the same text, I want to change its format as well.
Again, I'm new at this so if anyone needs more information I'll gladly post it. Thanks.
Update 1: Palpatim: Thank you. Your solution worked. So to clarify, in order to transfer text I have to put .text after the initial source. This combines two unlike objects and transfers only text to text. Is this correct? I'm new at coding and am just trying to learn.
Philip Mills: I meant I wanted to change the format of the text when I transfer it from something that is editable like a textview to something static like a label.
Thanks for the help.

xCode ios How to write a mutable array to a file on the desktop?

I have a one-time need to create a file from an iOS mutable array. The array will be a short animated drawing.
That will be input to an app.
I write the array, and redraw it in the app, so I know that it's getting populated.
I've tried to do something as simple as this:
- (void) writeFile {
//CREATE FILE
NSLog(#"%s", __FUNCTION__);
[writeArray writeToURL:[NSURL fileURLWithPath:[#"~/Desktop/animation.data" stringByExpandingTildeInPath]] atomically:NO];
}
but I must be doing something wrong, as no file appears..
As the file is small (4-8K), maybe I should take a different approach?
Any help will be appreciated.
Of course this won't work on the device, but I assume you're just trying to work in the Simulator for some kind of testing. fileURLWithPath: doesn't expand ~. You need a full path here. None of the path searching routines is going to point into your user folder in any case, since that doesn't exist on iOS.

Cocoa Drag and Drop, reading back the data

Ok, I have a NSOutlineView set up, and I want it to capture PDF's if a pdf is dragged into the NSOutlineView.
My first question, I have the following code:
[outlineView registerForDraggedTypes:[NSArray arrayWithObjects:NSStringPboardType, NSFilenamesPboardType, nil]];
In all the apple Docs and examples I've seen I've also seen something like MySupportedType being an object registered for dragging. What does this mean? Do I change the code to be:
[outlineView registerForDraggedTypes:[NSArray arrayWithObjects:#"pdf", NSStringPboardType, NSFilenamesPboardType, nil]];
Currently I have it set up to recognize drag and drop, and I can even make it spit out the URL of the dragged file once the drag is accepted, however, this leads me to my second question. I want to keep a copy of those PDF's app side. I suppose, and correct me if I'm wrong, that the best way to do this is to grab the data off the clipboard, save it in some persistant store, and that's that. (as apposed to using some sort of copy command and literally copying the file to the app director.)
That being said, I'm not sure how to do that. I've the code:
- (BOOL)outlineView:(NSOutlineView *)ov acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)childIndex
{
NSPasteboard *pboard = [info draggingPasteboard];
NSURL *fileURL;
if ( [[pboard types] containsObject:NSURLPboardType] ) {
fileURL = [NSURL URLFromPasteboard:pboard];
// Perform operation using the file’s URL
}
NSData *data = [pboard dataForType:#"NSPasteboardTypePDF"];
But this never actually gets any data. Like I said before, it does get the URL, just not the data.
Does anyone have any advise on how to get this going? Thanks so much!
Dragged Types
Dragged types are just strings that define a system pasteboard type (like NSFilenamesPboardType) or your app's own internal type (like "MyWidgetIdentifierType" to identify a widget by some internal ID).
A drag type of "PDF" doesn't get you anything. You might as well call it "Bob8374Type" ... if you don't give your app the ability to recognize the type (or nothing ever puts anything into the pasteboard for that type), it's utterly useless. You're working with dragged files, so NSFilenamesPboardType is correct.
NSPasteboardTypePDF won't help you unless there is NSPasteboardTypePDF data on the pasteboard. When files are dragged, you get NSFilenamesPboardType. Doesn't matter if the file is .pdf or .xyz; you're only getting paths.
Copy the File or Store a Path
You need to decide whether you intend to copy the dropped PDF or just store a path (or better yet, file system reference) to it. If you're going to copy the PDF, you'll need to make sure you're aware of the proper storage locations (like the Application Support folder, etc).
Assuming you really do want to copy the dropped pdfs somewhere, you don't need the PDF data. You can use NSFileManager to copy (or move) the file at the given path to a new location. If you have some other storage mechanism (ie, you want to suck the PDF data of the file into some other data structure), you can just get the PDF data directly using NSData's +dataWithContentsOfURL:options:error: and do with its data what you please.

Resources