Objective-c saving raw text - objective-c

I implemented saving and loading methods in my document-based application. In the saving method, I have
[NSArchiver archivedDataWithRootObject:[self string]];
Where [self string] is a NSString.
When saving a file with just "normal content" inside of it, the contents of the file created are:
streamtypedè#NSStringNSObject+normal content
Is there a way to store in a file just raw text?
Thanks for your help.

There are methods inside NSString for saving in a file:
NSString * s = #"Foo bar";
NSError * err = NULL;
BOOL result = [s writeToFile:#"/tmp/test.txt" atomically:YES encoding:NSASCIIStringEncoding error:&err];

Since i am new with cocoa, i don't know if this is the right way to do it or even a valid way.
But after a quick look at the documentation i found this method of NSString instances, - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
A quick try on a sample project it worked fine with:
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
So something like this might work for you:
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
return [[self string] dataUsingEncoding:NSUnicodeStringEncoding];
}

Related

How to convert &#8211,&#8222 etc in Objective-C

I made server side by Python and which return some scraped html string to client side which is made by Objective-C.
But When I try to show from client side which retuned string from server , it contains &#8211,&#8222,etc.But I don't know why it contains above characters.
Do you have any idea? And I want to convert them correctly with Objective-C. Do you have any idea? Thanks in advance.
If you want to stick with Cocoa you could also try to use NSAttributedString and initWithHTML:documentAttributes:, you will lose the markup than, though:
NSData *data = [#"<html><p>&#8211 Test</p></html>" dataUsingEncoding:NSUTF8StringEncoding];
NSAttributedString *string = [[NSAttributedString alloc] initWithHTML:data documentAttributes:nil];
NSString *result = [string string];
These are HTML Entities
Here is NSString category for HTML and here are the methods available:
- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;

How to write/save pure plain text files in a document based application?

In a document based application I am able to save/read from a file, but the problem comes when I have to read from a pure plain text file.
I have only a string to read/write, so that's the code:
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
code=[codeView string];
return [NSKeyedArchiver archivedDataWithRootObject: code];
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
code=[NSKeyedUnarchiver unarchiveObjectWithData: data];
return YES;
}
The problem is that saving a NSData may produce a file like this one:
bplist00‘X$versionX$objectsY$archiverT$top�܆£
U$null“
V$classYNS.stringÄP“Z$classnameX$classes_NSMutableString£XNSStringXNSObject_NSKeyedArchiver—TrootÄ#-27;AFMWYZ_jsÖâíõ≠∞µ����������������������������∑
Unreadable for humans, and unreadable for other applications like text edit.I need to be able to read and save plain text files, in my plist file I already tried to achieve this by changing the document type name to public.text.
How do I save/read a pure string, encoded in UTF-8?
That gobbledygook is the output of an NSKeyedArchiver. You don't want an archiver here. Instead, just ask the string for its dataUsingEncoding:, passing whatever encoding you'd like to use for the text (usually UTF-8 these days).
#RamyAlZuhouri: check out the "Document types" in the file "Info-TextEdit.plist" from the "TextEdit"-Project (Apple Code-Example).
Probably here: ~/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleOSX10_8.CoreReference.docset/Contents/Resources/Documents/samplecode/TextEdit

Is there a way to "auto detect" the encoding of a resource when loading it using stringFromContentsOfURL?

Is there a way to "auto detect" the encoding of a resource when loading it using stringFromContentsOfURL? The current (non-depracated) method, + (id)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;, wants a URL encoding. I've noticed that getting it wrong does make a difference for what I want to do. Is there a way to check this somehow and always get it right? (Right now I'm using UTF8.)
I'd try this function from the docs
Returns a string created by reading data from a given URL and returns by reference the encoding used to interpret the data.
+ (id)stringWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError **)error
this seems to guess the encoding and then returns it to you
What I normally do when converting data (encoding-less string of bytes) to a string is attempt to initialize the string using various different encodings. I would suggest trying the most limiting (charset wise) encodings like ASCII and UTF-8 first, then attempt UTF-16. If none of those are a valid encoding, you should attempt to decode the string using a fallback encoding like NSWindowsCP1252StringEncoding that will almost always work. In order to do this you need to download the page's contents using NSData so that you don't have to re-download for every encoding attempt. Your code might look like this:
NSData * urlData = [NSData dataWithContentsOfURL:aURL];
NSString * theString = [[NSString alloc] initWithData:urlData encoding:NSASCIIStringEncoding];
if (!theString) {
theString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
}
if (!theString) {
theString = [[NSString alloc] initWithData:urlData encoding:NSUTF16StringEncoding];
}
if (!theString) {
theString = [[NSString alloc] initWithData:urlData NSWindowsCP1252StringEncoding];
}
// ...
// use theString here...
// ...
[theString release];

How to save a text document in Cocoa with specified NSString encoding?

I'm trying to create a simple text editor like Textedit for Mac OS X, but after many hours of research can't figure out how to correctly write my document's data to a file. I'm using the Cocoa framework and my application is document-based. Looking around in the Cocoa API I found a brief tutorial, "Building a text editor in 15 minutes" or something like this, that implements the following method to write the data to a file:
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
[textView breakUndoCoalescing];
NSAttributedString *string=[[textView textStorage] copy];
NSData *data;
NSMutableDictionary *dict=[NSDictionary dictionaryWithObject:NSPlainTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
data=[string dataFromRange:NSMakeRange(0,[string length]) documentAttributes:dict error:outError];
return data;
}
This just works fine, but I'd like to let the user choose the text encoding. I guess this method uses an "automatic" encoding, but how can I write the data using a predefined encoding? I tried using the following code:
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
[textView breakUndoCoalescing];
NSAttributedString *string=[[textView textStorage] copy];
NSData *data;
NSInteger saveEncoding=[prefs integerForKey:#"saveEncoding"];
// if the saving encoding is set to "automatic"
if (saveEncoding<0) {
NSMutableDictionary *dict=[NSDictionary dictionaryWithObject:NSPlainTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
data=[string dataFromRange:NSMakeRange(0,[string length]) documentAttributes:dict error:outError];
// else use the encoding specified by the user
} else {
NSMutableDictionary *dict=[NSDictionary dictionaryWithObjectsAndKeys:NSPlainTextDocumentType,NSDocumentTypeDocumentAttribute,saveEncoding,NSCharacterEncodingDocumentAttribute,nil];
data=[string dataFromRange:NSMakeRange(0,[string length]) documentAttributes:dict error:outError];
}
return data;
}
saveEncoding is -1 if the user didn't set a specific encoding, otherwise one of the encodings listed in [NSString availableStringEncodings]. But whenever I try to save my document in a different encoding from UTF8, the app crashes. The same happens when I try to encode my document with the following code:
NSString *string=[[textView textStorage] string];
data=[string dataUsingEncoding:saveEncoding];
What am I doing wrong? It would be great if someone knows how Textedit solved this problem.
Perhaps you remember that NSDictionary can only store objects...
NSMutableDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
NSPlainTextDocumentType,
NSDocumentTypeDocumentAttribute,
[NSNumber numberWithInteger:saveEncoding],
NSCharacterEncodingDocumentAttribute,
nil];

How to I read a file in a specific folder with Objective-C?

I am a newbie to Objective-C. Right now, am working on files. My question is..
How do i search for a file in a specific folder ?
Lets say, I get an input string "input". Now all i want to do is search and read the file "input.txt" from a specific path maybe "user/desktop/files" folder. How do I do this?
I know using NSFileHandle in reading a file by specifying the full path. But I dont know how to do this.
Please help me out.
Thanks
There are some NSString methods you should consider using.
// path contains the path to the folder you want to find the file in.
// create the full file name
NSString* shortPath = [#"input" stringByAppendingPathExtension: #"txt"];
NSString* fullPath = [path stringByAppendingPathComponent: shortFileName];
// open the file. we convert to an NSURL so we can use the better open method
NSURL* fileURL = [NSURL fileURLWithPath: fullPath];
NSError* error = nil;
NSFileHandle *file=[NSFileHandle fileHandleForReadingFromURL: fileURL
error: &error];
if (file == nil)
{
// error contains info on what went wrong
}
else
{
// do what you need
}
In general, to work with paths, you use the following methods which are defined in NSPathUtilities.h (rather than in NSString.h itself):
#interface NSString (NSStringPathExtensions)
+ (NSString *)pathWithComponents:(NSArray *)components;
- (NSArray *)pathComponents;
- (BOOL)isAbsolutePath;
- (NSString *)lastPathComponent; // frequently-used
- (NSString *)stringByDeletingLastPathComponent; // frequently-used
- (NSString *)stringByAppendingPathComponent:(NSString *)str; // frequently-used
- (NSString *)pathExtension; // frequently-used
- (NSString *)stringByDeletingPathExtension; // frequently-used
- (NSString *)stringByAppendingPathExtension:(NSString *)str; // frequently-used
- (NSString *)stringByAbbreviatingWithTildeInPath;
- (NSString *)stringByExpandingTildeInPath;
- (NSString *)stringByStandardizingPath;
- (NSString *)stringByResolvingSymlinksInPath;
- (NSArray *)stringsByAppendingPaths:(NSArray *)paths;
- (NSUInteger)completePathIntoString:(NSString **)outputName
caseSensitive:(BOOL)flag matchesIntoArray:(NSArray **)outputArray
filterTypes:(NSArray *)filterTypes;
- (__strong const char *)fileSystemRepresentation;
- (BOOL)getFileSystemRepresentation:(char *)cname maxLength:(NSUInteger)max;
#end
So, you would do something like:
NSString *fullpath = [[path stringByAppendingPathComponent:input]
stringByAppendingPathExtension:#"txt"];
These methods take care of handling the path separator for you.
If the file is known to be a text file, you can use the following methods in NSString:
- (id)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc
error:(NSError **)error;
- (id)initWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc
error:(NSError **)error;
+ (id)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc
error:(NSError **)error;
+ (id)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc
error:(NSError **)error;
/* These try to determine the encoding, and return the encoding which was used.
Note that these methods might get "smarter" in subsequent releases of the
system, and use additional techniques for recognizing encodings. If nil
is returned, the optional error return indicates problem that was
encountered (for instance, file system or encoding errors). */
- (id)initWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc
error:(NSError **)error;
- (id)initWithContentsOfFile:(NSString *)path usedEncoding:(NSStringEncoding *)enc
error:(NSError **)error;
+ (id)stringWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc
error:(NSError **)error;
+ (id)stringWithContentsOfFile:(NSString *)path usedEncoding:(NSStringEncoding *)enc
error:(NSError **)error;
/* Write to specified url or path using the specified encoding.
The optional error return is to indicate file system or encoding errors.
*/
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile
encoding:(NSStringEncoding)enc error:(NSError **)error;
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile
encoding:(NSStringEncoding)enc error:(NSError **)error;
The latter can be used to write to files.
You'll find many classes in Cocoa have methods to read in from a file or URL themselves. For example, NSImage has a method to read from a file. You can generally think about items at a higher level than file handles (though they do have their place). For generic data, there is always NSData which can also read in from files.
To programmatically get listings of the items in a folder, you can use NSFileManager, then use the methods of NSString to construct paths for individual items.
Oh, another tip if you didn't already know. If you're in an Xcode source code window, hold down the Command key and double-click on any class or method name or data type to open up the header file for that object. For example, Command-double-click on NSString opens up NSString.h. Hold down Command-Option and double-click to open up the Xcode help window and search for the highlighted term.
Ok i just did something with NSString here...
NSString *input=[TextInput stringValue];
NSString *path=#"/Users/mith/Desktop/files/";
NSString *fullpath=[NSString stringWithFormat:#"%#%#.txt",path,input];
NSFileHandle *file=[NSFileHandle fileHandleForReadingAtPath:fullpath];`
Ok now, this works for me fine... But is there a better way to do this ?
Thanks