iOS keychain - Different values found on subsequent reads - objective-c

I'm using the keychainItemWrapper to store a token in my ios keychain. I can write successfully and read the first time successfully. However, once I read subsequent times, or run my program again, I'm getting a different value, or data in a different format. Any ideas?
Details:
1) Using KeychainItemWrapper - https://gist.github.com/dhoerl/1170641
2) Testing on simulator
Code:
NSString* mytoken = #"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwYTVjM2U4N2FmY2I0NTNlYWEzZjI3MDBlYjgwZWE4YiIsInN1YiI6ImxpbmRzZXk0IiwiaWF0IjoxNTE5MTk5MTgxLCJuYmYiOjE1MTkxOTkxODEsImV4cCI6MTUxOTE5OTc4MX0.v10D61EE6tq6u9YG3QIQ_XefexlC22gwx-tv-HgOEsQ";
KeychainItemWrapper* keychain1 = [[KeychainItemWrapper alloc] initWithIdentifier:#"com.test.test" accessGroup:nil];
[keychain setObject:mytoken forKey:(id)kSecValueData];
NSString* result1a = [keychain1 objectForKey:(id)kSecValueData];
NSLog(#"result1a (works!):\n %#:", result1a);
result1a (works!):
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwYTVjM2U4N2FmY2I0NTNlYWEzZjI3MDBlYjgwZWE4YiIsInN1YiI6ImxpbmRzZXk0IiwiaWF0IjoxNTE5MTk5MTgxLCJuYmYiOjE1MTkxOTkxODEsImV4cCI6MTUxOTE5OTc4MX0.v10D61EE6tq6u9YG3QIQ_XefexlC22gwx-tv-HgOEsQ
NSString* result1b = [keychain1 objectForKey:(id)kSecValueData];
NSLog(#"result1b (works!):\n%#", result1b);
result1b (works!):
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwYTVjM2U4N2FmY2I0NTNlYWEzZjI3MDBlYjgwZWE4YiIsInN1YiI6ImxpbmRzZXk0IiwiaWF0IjoxNTE5MTk5MTgxLCJuYmYiOjE1MTkxOTkxODEsImV4cCI6MTUxOTE5OTc4MX0.v10D61EE6tq6u9YG3QIQ_XefexlC22gwx-tv-HgOEsQ
KeychainItemWrapper* keychain2 = [[KeychainItemWrapper alloc] initWithIdentifier:#"com.test.test" accessGroup:nil];
NSString* result2 = [keychain2 objectForKey:(id)kSecValueData];
NSLog(#"result2 (weird value!):\n%#", result2);
result2 (weird value!):
<65794a68 62476369 4f694a49 557a4931 4e694a39 2e65794a
7164476b 694f6949 77595456 6a4d3255 344e3246 6d593249 304e544e
6c595745 7a5a6a49 334d4442 6c596a67 775a5745 34596949 73496e4e
31596949 36496d78 70626d52 7a5a586b 30496977 69615746 30496a6f
784e5445 354d546b 354d5467 784c434a 75596d59 694f6a45 314d546b
784f546b 784f4445 73496d56 34634349 364d5455 784f5445 354f5463
344d5830 2e763130 44363145 45367471 36753959 47335149 515f5865
6665786c 43323267 77782d74 762d4867 4f457351>

You are actually getting the same value, but it's in hex format. If you convert that last value in to String you'll get the same value. You can see it on this hex converter http://string-functions.com/hex-string.aspx Just paste that last result and hit convert.
So for some reason, your first result is in String and your last result is in NSData format.

Related

Applescript from Mac App says "Expected end of line but found \U201c\"\U201d."

I am trying to perform a copy/paste for my to the the last active app, here's my code:
NSString *appleScriptSource = [NSString stringWithFormat:#"\ntell application \"%#\" to activate\ntell application \"System Events\" to tell process \"%#\"\nkeystroke \"v\" using command down\nend tell", [lastApp localizedName], [lastApp localizedName]];
NSDictionary *error;
NSAppleScript *aScript = [[NSAppleScript alloc] initWithSource:appleScriptSource];
NSAppleEventDescriptor *aDescriptor = [aScript executeAndReturnError:&error];
The problem is that on some computers it works just fine, but on others it fails. My error output from error that is returned by executeAndReturnError is:
2012-06-13 17:43:19.875 Mini Translator[1206:303] (null) (error: {
NSAppleScriptErrorBriefMessage = "Expected end of line but found \U201c\"\U201d.";
NSAppleScriptErrorMessage = "Expected end of line but found \U201c\"\U201d.";
NSAppleScriptErrorNumber = "-2741";
NSAppleScriptErrorRange = "NSRange: {95, 1}";
})
I can't seem to figure out what it means or why it happens.
We tried copying the generated apple-script code into the Apple Script editor, and here it works just fine.
My App is sandboxed - i have added the bundle identifiers for the key "com.apple.security.temporary-exception.apple-events" for the apps i want to support.
Any suggestions?
I am guessing that the \u201c and \u201d are red herrings and just represent smart quotes around a double quote in the error message produced by apple script, and your issue lies with the localized name of the last application you are formatting into the script. I am not sure why you might see this on one machine and not another.
For example if the name was 'Some " App' then the double quotes would end up mismatched as it would end up injected into the middle of a double quoted string. You might want to try and replace any double quotes in the name with '\"' which will escape them.
e.g.
NSString *esc = [[lastApp localizedName] stringByReplacingOccurrencesOfString:#"\"" withString:#"\\\""];

Soap request with NSData and base64 encoding

I'm using a sudzc soap classes to communicate with a remote web service.
Most of requests works but i'm experiencing problem trasferring data:
i've to send some data encoded in base64, i allocate a NsData object this way:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"little_amount_of_data" ofType:#"dat"];
NSData* dummy = [NSData dataWithContentsOfFile:filePath];
[service sendAudioFile:self action:#selector(sendAudioFileHandler:) username: self.username password: self.password fileBytes: dummy numBytes: [dummy base64Encoding].length audioTimestamp: [NSString stringWithFormat:#"%0.f",[[NSDate date]timeIntervalSince1970]]];
The SOAP request looks right (data correctly encoded, right length) but i'm receiving this response from the server (iis7 i think, i don't have access to it):
Impossibile elaborare la richiesta. ---> Offset e lunghezza eccedono i limiti della matrice o il conteggio รจ maggiore del numero di elementi presenti dall'indice alla fine dell'insieme di origine.
translated:
Unable to process request. ---> Offset and length exceed the limits of the array or the count is greater than the number of items from the index at the end of the source.
if client sends a void base64 string (lenght=0), server replies with a success statement.
The WSDL describe the field as base64Binary
I'm using NSData+Base64.h/NSData+Base64.m
Any hints?
Is client or server fault?
solved, problem was on lenght. I was sending the lenght of the encoded file, the webservice wants the lenght of the original file.

Can I use my own filename when using NSTemporaryDirectory

I am generating a PDF file and saving it to my device before e-mailing it from within my application. At the moment it does not get cleared down either manually or automatically so I was looking at NSTemporaryDirectory. I have looked at various sites and also on here for the answer to my specific query but cannot find it.
I have the following function:
+(NSString *)getTempFilePathName {
NSString *tempFilePathName = nil;
NSString *tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:#"tempfile.XXXXXX"];
const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation];
char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1);
strcpy(tempFileNameCString, tempFileTemplateCString);
int fileDescriptor = mkstemp(tempFileNameCString);
if (fileDescriptor != -1) {
// File opened successfully
tempFilePathName = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
close(fileDescriptor);
}
free(tempFileNameCString);
return tempFilePathName;
}
This returns me an NSString with the full path and filename to a temp file ending with the 'XXXXXX' component of the filename replaced with unique combo of letters and numbers. As I am using this to save a PDF file, I need to fix the 'XXXXXX' bit with the extension ".PDF". Preferably I'd like to also specify the filename itself too so something like "Order-123.PDF".
Can I just edit my method to pass in a filename and use that in the stringByAppendingPathComponent parameter? Is the directory name generated unique per call to this method?
I have solved this by myself. After the line that calls the above routine I do:
NSString *newFilePath = [tempNameStub stringByAppendingPathExtension:#"pdf"];
Which adds .pdf to the end.

How to set artwork to an iTunes song using NSApplescript in Xcode?

there are some similars questions here but none involves NSApplescript.
I'm trying to add iTunes artwork to a selected track, my code is:
set newFile to add aFileName as POSIX file to ipod_lib
set current_track to newFile
set jpegFilename to ":temp:artwork.jpg" as string
set data of artwork 1 of current_track to (read (file jpegFilename) as picture)
tell current_track
set name to "Song Name" as string
set artist to "Custom Artist" as string
set album to "Custom Album" as string
set year to "2011" as string
set track number to "1" as number
set track count to "38" as number
end tell
Where aFileName is the path of an mp3.
I'm testing this using Script Debugger 4.5 and it works fine, but when I copy the code to my Xcode project and run it wont set the artwork neither the other meta data.
But if I comment the "set data of artwork.." line, then it does set the other meta data (name, artist, etc)
My Xcode code is:
NSString *scriptote = #"with timeout of 600 seconds\n"
"tell application \"iTunes\"\n"
...
"set newFile to add aFileName as POSIX file to ipod_lib\n"
"set current_track to newFile\n"
"set jpegFilename to \":temp:artwork.jpg\" as string\n"
// If a comment the following line, everything else works, if I left this line, no meta data is set.
"set data of artwork 1 of current_track to (read (file jpegFilename) as picture)\n"
"tell current_track\n"
"set name to \"Song Name\" as string\n"
"set artist to \"Custom Artist\" as string\n"
"set album to \"Custom Album\" as string\n"
"set year to \"2011\" as string\n"
"set track number to \"1\" as number\n"
"set track count to \"38\" as number\n"
"end tell\n"
...
;
if ((ascript = [[NSAppleScript alloc] initWithSource:scriptote])) {
status = [[ascript executeAndReturnError:&errorInfo] stringValue];
if (!errorInfo) {
// do something
NSLog(#"NO Error");
} else {
// process errors
// NSRange errorRange = [[errorInfo objectForKey:#"NSAppleScriptErrorRange"] rangeValue];
NSLog(#"Error\n Error line: ");
}
[ascript release];
}
I have been searching on google for many hours without luck.
I don't want to use ScriptBridge framework because I will need to translate lot of applescripts so its not an option for me right now.
Any help will be greatly appreciated.
Found the problem, in case someone else reach here in the future the problem was with the HFS path format style.
I was getting the path to my artwork using NSSearchPathForDirectoriesInDomains and then replacing all the #"/" for #":" to format the path in HFS style.
The problem is that HFS path format style need a full path including Volume Name and NSSearchPathForDirectoriesInDomain and any other NSFileManager methods return paths starting in /Users/.... and I needed a path like this: Macintosh HD/Users/...
To get the HFS full path I used the following code:
// Get an HFS-style reference to a specified file
// (imagePath is an NSString * containing a POSIX-style path to the artwork image file)
NSURL *fileURL = [NSURL fileURLWithPath:imagePath];
NSString *pathFormatted = (NSString *)CFURLCopyFileSystemPath((CFURLRef)fileURL, kCFURLHFSPathStyle);
That solves the problem, use the pathFormatted string to set the data of artwork and it should work.
Hope this would help someone someday -)

Scripting Bridge and com.apple.iWork.Pages -- can this work?

I am trying to count the words in Pages document (the doc format is RTF) using the scripting bridge. (I can do it using NSApplescript but I would rather not have all the applescript-aware duct tape in my code)
When I perform this task using applescript (and NSAppleScript APIs) I can do this very simply (and successfully):
on wordCount(appName,docName)
local mydoc
local wordcount
tell application appName
set mydoc to document docName
set wordcount to count of words of mydoc
log "wordcount = " & wordcount
return wordcount
end tell
end wordCount
However when I try the equivalent using the scripting bridge all my objects seem to have null contents. My code is as follows:
+ (NSUInteger) wordCountForApp: (SBApplication*) sbApp docNamed: (NSString*) docName
{
PagesApplication *pages = (PagesApplication*)sbApp;
PagesDocument *doc = [[pages documents] objectWithName:docName];
PagesText *text = [doc bodyText];
SBElementArray *words = [text words];
NSUInteger wc = [words count];
NSLog(#"Pages word count = %ul", (unsigned int) wc);
return wc; // wc comes back as zero always ... grrrr
}
I have verified that I am running this stuff on the main thread (and that equivalent code works against TextEdit). Any ideas as to what is going on/how to work around?
Thanks for having read this far....
That code works for me. The equivalent in F-Script:
> pages := SBApplication applicationWithBundleIdentifier: 'com.apple.iWork.Pages'
> (pages documents objectWithName: 'fun') bodyText words count
303
I'd suggest you step through it with a debugger and make sure that each object is what you're expecting, i.e. pages, [pages documents], etc.
If you're writing this code for external use, ideally you should not refer to documents by name; the user may have multiple documents with the same name open.
Another option is objc-appscript, which provides an neat ASTranslate utility that transforms AppleScript into Objective-C (or Ruby or Python for the other appscript bindings). For example, for the above, you'd have something like:
#import "PGGlue/PGGlue.h"
PGApplication *pages = [PGApplication applicationWithName: #"Pages"];
PGReference *ref = [[pages documents] byName: #"fun"];
PGCountCommand *cmd = [[ref count] each: [PGConstant word]];
id result = [cmd send];
So the problem was that I was asking for a document named "something.rtf" that I had just opened in Pages. But when Pages opens "something.rtf" it names it "something". And then when you ask for document named "something.rtf" it does not return nil because the document does not exist by that name. Instead, it returns a PagesDocument named "something.rtf" which has no valid contents: a NIL document. Which I guess I just was too stupid to recognize when I submitted to SO.
I have since checked other apps and this seems to be normal applescript behavior when you ask for a document by name (to get back a "valid object" containing a NIL document) oh well.