Encrypted Data not writing to file? - cocoa

In an encryption tool I am nearly finished with, I can't seem to write the encrypted data to a file.
Here is what I have:
NSData *encryptedData = [data AES256EncryptWithKey:key];
[encryptedData writeToFile:#"~/Desktop/file.txt" atomically:YES];
If 'file.txt' is not found, it should create it.
Thank You

First, -writeToFile:atomically: is the name of the method you are trying to use-- not, as you have written, -writeToFile:automatically:. And second, this method should usually be avoided in favor of one that takes an out NSError parameter.
Try -writeToFile:options:error: if you'd like to be able to log a useful diagnostic when something goes wrong.

Related

Guess NSData encoding using file in /tmp as intermediation?

I want to guess a received NSData's encoding. I searched in Stackoverflow and found one answer here which indicates "can't".
However, I noticed a NSString method stringWithContentsOfFile:usedEncoding:error:, and I wanted to know whether I can achieve this goal in sequence below:
1> Get an NSData object
2> Store this NSData object into a file with random file name in directory /tmp
3> Call NSString's stringWithContentsOfFile:usedEncoding:error: method to read from this temporary file.
4> Delete the temporary file.
5> Read the enc parameter to determine the encoding
I know I can experiment by myself, but I have no various data source with different encoding in my hand. Therefore I raised a question here. Could my opinion work? Could this solution find every possible encoding OS X could recognized?

Encoding an NSMutableArray

I have an object containing various NSString objects and variables which I us NSCoding to archive to a file on the disk and later unarchive. So far everything has been working perfectly.
Today, I wanted to add an NSMutableArray to the object and tried to encode using the:
[encoder encodeObject:myArray ForKey:#"myArray"];
and later decode it using:
[self setMyArray:[decoder decodeObjectForKey:#"myArray"]];
It doesn't appear to be working, and while I don't get any errors in the encoding or decoding itself, I do get an error if I try to modify the value of the array after decoding from the file.
I'm sure I'm doing something completely wrong here, but not entirely certain what. I'm thinking perhaps it may have something to do with it not properly allocing during the unarchive.
Anything look blatantly obvious as the source of the problem?
It doesn't appear to be working, and while I don't get any errors in
the encoding or decoding itself, I do get an error if I try to modify
the value of the array after decoding from the file.
Decoding an archive gives you immutable objects regardless of whether they were mutable or immutable when you encoded them. You're not doing anything particularly wrong -- it's working as advertised.
See this answer for another example of a similar problem, and a solution:
[self setMyArray:[[decoder decodeObjectForKey:#"myArray"] mutableCopy];

Write data to file Cocoa?

I need to use the writeToFile: methods in writing data (that is encrypted) to a file. However, say I have:
NSData *encryptedData = [data AES256EncryptWithKey:key];
And I write the encryptedData to a file by:
[encryptedData writeToFile:#"file.txt" automatically:YES];
This for some reason does not write the data to "file.txt." This is a very simple question and I know I am missing something super basic. If file.txt is not actually there, it must be created.
This probably has nothing to do with Cocoa or NSData.
On Unix (like Mac OS X), paths that start with / are absolute. Paths that start with ~ are relative to the current user's home directory. Anything else (such as file.txt) is relative to the current directory. When running something from Xcode, that is the path of the executable (the compiler's output path).
So, to write that to the desktop, that would be:
[encryptedData writeToFile:#"~/Desktop/file.txt" atomically:YES];
For the documents folder, that would be:
[encryptedData writeToFile:#"~/Documents/file.txt" atomically:YES];
Don't forget that paths are also case-sensitive.
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
returns a boolean to say if it was successful or not. I'd start there, if you see a YES then the file wrote somewhere successfully.
If that doesn't work then i'd double check the object you're trying to encode supports the NSCoding protocol. If you object doesn't support NSCoding take a look at this blog post for a nifty simple way of adding it.
Also its "atomically" not "automatically" :)

Decode unknown NSData

I've come across a resource that I would like to use, but I'm not sure how to proceed. The resource is a plist and one of the keys holds an NSData object. However, I don't know what the NSData represents. Is there a way to figure out how I should decode the NSData object to be able to read its contents?
So I assume you can't ask the provider of the resource what the data is for? Try dumping the data out to a file using -writeToFile:atomically:. Then you can use the file command-line tool to see if it knows what format the file is in. Or you can use xxd to look at the bytes and see if you recognise the format. There's no foolproof way to go from 'arbitrary set of bytes' to 'understanding of the context of those bytes', you either need to recognise it or ask someone.

Unfiltering NSPasteboard

Is there a way to unfilter an NSPasteboard for what the source application specifically declared it would provide?
I'm attempting to serialize pasteboard data in my application. When another application places an RTF file on a pasteboard and then I ask for the available types, I get eleven different flavors of said RTF, everything from the original RTF to plain strings to dyn.* values.
Saving off all that data into a plist or raw data on disk isn't usually a problem as it's pretty small, but when an image of any considerable size is placed on the pasteboard, the resulting output can be tens of times larger than the source data (with multiple flavors of TIFF and PICT data being made available via filtering).
I'd like to just be able to save off what the original app made available if possible.
John, you are far more observant than myself or the gentleman I work with who's been doing Mac programming since dinosaurs roamed the earth. Neither of us ever noticed the text you highlighted... and I've not a clue why. Starting too long at the problem, apparently.
And while I accepted your answer as the correct answer, it doesn't exactly answer my original question. What I was looking for was a way to identify flavors that can become other flavors simply by placing them on the pasteboard AND to know which of these types were originally offered by the provider. While walking the types list will get me the preferred order for the application that provided them, it won't tell me which ones I can safely ignore as they'll be recreated when I refill the pasteboard later.
I've come to the conclusion that there isn't a "good" way to do this. [NSPasteboard declaredTypesFromOwner] would be fabulous, but it doesn't exist.
-[NSPasteboard types] will return all the available types for the data on the clipboard, but it should return them "in the order they were declared."
The documentation for -[NSPasteboard declareTypes:owner:] says that "the types should be ordered according to the preference of the source application."
A properly implemented pasteboard owner should, therefore, declare the richest representation of the content (probably the original content) as the first type; so a reasonable single representation should be:
[pb dataForType:[[pb types] objectAtIndex:0]]
You may be able to get some use out of +[NSPasteboard typesFilterableTo:]. I'm picturing a snippet like this:
NSArray *allTypes = [pb types];
NSAssert([allTypes count] > 0, #"expected at least one type");
// We always require the first declared type, as a starting point.
NSMutableSet *requiredTypes = [NSMutableSet setWithObject:[allTypes objectAtIndex:0]];
for (NSUInteger index = 1; index < [allTypes count]; index++) {
NSString *aType = [allTypes objectAtIndex:index];
NSSet *filtersFrom = [NSSet setWithArray:[NSPasteboard typesFilterableTo:aType]];
// If this type can't be re-created with a filter we already use, add it to the
// set of required types.
if (![requiredTypes intersectsSet:filtersFrom])
[requiredTypes addObject:aType];
}
I'm not sure how effective this would be at picking good types, however.

Resources