Can I use my own filename when using NSTemporaryDirectory - objective-c

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.

Related

Mac Objective-C convert HFS style paths to POSIX path [duplicate]

This question already has answers here:
How to convert a classic HFS path into a POSIX path
(2 answers)
Closed 3 years ago.
While trying the approach suggested here, working directory gets prefixed instead of path conversion. Leading : is HFS path does not make any difference.
NSString * ttt = #"Macintosh HD:Users:gautam:code:Help:";
if (CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)ttt, kCFURLPOSIXPathStyle, false))
{
NSString * posixPath = [(__bridge NSURL*)url path];
// posixPath __NSCFString * "/Users/gautamjha/code/Macintosh HD:Users:gautam:code:Help:"
const char * secondName = [posixPath UTF8String];
// above does not help either working directory gets prefixed.
}
The error occurs because you are passing the source type kCFURLPOSIXPathStyle, but you want to create the URL from an HFS path.
As mentioned in my linked answer the constant kCFURLHFSPathStyle is unavailable, you have to replace it with the raw value 1.
if (CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)ttt, 1, false))

iOS keychain - Different values found on subsequent reads

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.

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.

How to convert file name with path to short file name (DOS style) in Adobe AIR?

How to convert file name with path to short file name (DOS style) in Adobe AIR?
For example convert next path
"C:\Program Files\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe"
to
"C:\PROGRA~1\COMMON~1\ADOBEA~1\VERSIONS\1.0\RESOUR~1\ADOBEA~1.EXE"
Is there any algorithm?
Assuming your text portion is a string variable, you can split it by using "\" as delimiter. Then, you will have an array which you can use to check if each block is longer than 8 characters. While looping the array you can chop the last characters of each long block and put ~1. Since you're in the loop, you can progressively add to a temporary variable all these changes which will give you the final edited result at the end.
The only part that's a bit tricky is to pay attention to .exe part at the end.
So, if I were you, I'd start reading on String.split(), String.substring(), for loop, arrays
Here's my handy method that does this below:
public static string GetShortPathName(string path)
{
string[] arrPath = path.Split(System.IO.Path.DirectorySeparatorChar);
path = arrPath[0]; // drive
// skip first, ( drive ) and last program name
for (int i = 1; i < arrPath.Length - 1; i++)
{
string dosDirName = arrPath[i];
if (dosDirName.Count() > 8)
{
dosDirName = dosDirName.Substring(0, 6) + "~1";
}
path += System.IO.Path.DirectorySeparatorChar + dosDirName;
}
// include program name if any
path += System.IO.Path.DirectorySeparatorChar + arrPath[arrPath.Length - 1];
return path;
}