views:

160

answers:

2

I have an document based application which formats an XML file.

Writing and reading of document is done in my NSDocument subclass

- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError

but if the file is an invalid XML, my app is simply crashing.

So I implemented:

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename  
{  
  if(safe){open new document using .....makeDocumentWithContentsOfURL:......}  
   else{present alert}  
}

But there are lot of apparent side effects with this. I have to override couple of other methods:

-(BOOL)writeSafelyToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName     forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError  
{  
    return [self writeToURL:absoluteURL ofType:typeName error:outError];  
    //return YES;  
}

And this is where the beach-ball cursor appears and eventually the application becomes unresponsive.

Is there a better way to validate the document before opening?

+2  A: 

You should be implementing -readFromURL:ofType:error: such that it does not crash on bad XML. This is the routine that you should be doing your validation in. What part of your code is causing the crash, and what kind of crash is it?

Regarding the beachball in -writeSafelyToURL:ofType:forSaveOperation:error:, you're probably creating an infinite loop. It is possible that -writeToURL:ofType:error: calls -writeSafelyToURL:..... In any case, this is a very strange way to overload it. What are you trying to achieve here? I don't understand how overloading -application:openFile: is related to either your first problem or the overload you describe.

Rob Napier
This is what I did earlier , but bad XML makes the app creash- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outErrorNSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithXMLString:string options:NSXMLNodePreserveWhitespace error:if(err){return NO;}else{do something..return YES;}}I don't know what more to implement than this...
And what was the crash?
Rob Napier
Rajesh: That's not how you handle an error return. Test whether `xmlDoc` is `nil`; *only if it is `nil`* should you examine the `err` variable. Also, please edit the crash log into your question.
Peter Hosey
+1  A: 

The best bet is calling this in your application:openFile: method:

[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:filename] display:YES error:&error];

Using that I haven't had any issues (I'm new to the Document Architecture as well). Just do your validation before that line and everything should work.

Another thing you might find useful: if you override any of the NSDocument loading/saving methods for different types, be sure to call the super version of each at the end if you don't do the save/load within them. So for example you can have readFromData:ofType:error: for one type of data but readFromFileWrapper:ofType:error: for another, and both will automatically work as long as you call [super ...] at the end of each if you don't handle the requested type.

jfm429
Whoa... um, just realized that was a serious gravedig... I was searching for something, saw this, and answered it. Anyhow... hope someone finds it useful anyway. :D
jfm429