One of the key data sources of my app is an array of dictionaries containing product information which is stored in a plist file.
I need to supply this data as a table (csv text file)
I know how to read the file in, bind it to an array controller, display it in a Table View, etc., etc. However, getting the data into the right arrangement to writeToFileAtomically is completely eluding me. I just keep getting the plist array, not tabular data, in the variable I want to write out as text.
I know it must be something incredibly simple to do, but you know how it goes.
on exportPIRtable_(sender)
set plistExportPath to "/Users/jhaney/Desktop/PIRexport.txt"
set exportDictionary to current application's NSDictionary's dictionaryWithObjects_forKeys_(pirArrayController's arrangedObjects(), {"Product_Name", "Brand", "Building_Environment", "Channel", "Comments_Notes", "Department", "Geography", "Key_words", "Language", "Market_Code", "PIR_Number", "Performance_Category", "Product_Classification", "Product_Name", "Product_Related", "Reviewer", "USG_Organization", "User_Access"})
log exportDictionary
exportArray's writeToFileAtomically_(plistExportPath, true)
end exportPIRtable_
However, I am getting the following error:
-[NSDictionary initWithObjects:forKeys:]: count of objects (872) differs from count of keys (1) (error -10000)
So, it thinks that my objects are in the first level of the array, when actually each of the 872 objects has a dictionary of 18 keys. I want to assemble a table with each “object” as a row, and 18 columns containing their values.
It means that when you read the file, you define the correct structure to get its content. Why don’t you use the same structure to write it back?
It is right, that’s exactly what you give to it: an array of 872 objects (the arrangedObjects of your controller) with a single key. You don’t have an array of dictionaries, but one dictionary with an array!
Maybe you should use a dictionary containing an array of dictionaries, like this:
(your arranged objects)
(your first record)
…
(your last record)
Then you could archive you root dictionary…
What do you think?
PS You can use the buttons in the editor mode (B, I, U, Quote...) to format your answer.
It’s been awhile since I’ve coded in ASOC, but I think you’d get the idea. \n and \t in the string are respectively a return and tab character, in case you were wondering.
Looks a bit complicated vs the cocoa way, but if it works, you’ll get no complaints from me!
Odd that you mention stringWithFormat being unreliable in ASOC. Perhaps it needs NSString objects created before being used in this method. not sure. Sad, because in this case it is very useful.
Well – these are the sort of things that made me switch to Objective-C.
@ jhaneyzz : if your app does not pilot the Finder or other apps, you should really consider using Obj-C. Not only for the code readability, but also for speed if you are dealing with large tables.
This is a key independent way using the Objective-C equivalent of AppleScript text item delimiters.
it assumes that the first array entry contains all keys
on exportPIRtable_(sender)
set contentArray to pirArrayController's arrangedObjects()
set allKeys to contentArray's objectAtIndex_(0)'s allKeys()
set csvLines to current application's NSMutableArray's array()
csvLines's addObject_(allKeys's componentsJoinedByString_("\t"))
repeat with aDict in contentArray
set theArray to aDict's objectsForKeys_notFoundMarker_(allKeys, "n/a")
csvLines's addObject_(theArray's componentsJoinedByString_("\t"))
end repeat
set csvParagraphs to csvLines's componentsJoinedByString_("\r")
csvParagraphs's writeToFile_atomically_encoding_error_(plistExportPath, true, current application's NSUTF8StringEncoding, missing value)
end exportPIRtable_
@ jhaneyzz : if your app does not pilot the Finder or other apps, you should really consider using Obj-C. Not only for the code readability, but also for speed if you are dealing with large tables.
Unfortunately, the purpose of this app is to merge multiple data sources + business rules + Digital Assets so the users (Marketing Managers) can classify their assets, images, documents, video, etc.
Once they have identified the asset visually (using Extensis Portfolio currently) and using my app to find the right ID code, I send applescript to Portfolio to tag the assets.
Portfolio is involved really only to give the users a visual method of selecting individual or groups of assets to tag.
Coercing between AppleScript strings and OBC strings has been a real hassle.