I am upgrading an older AppleScript Studio document-based application that used to save documents as text files with it’s own extension. I need my new AS Obj-C app to be able to read the old documents. Can I do that?
Right now I am getting this error:
[<NSDocument 0x7fff74b64450> valueForUndefinedKey:]: this class is not key value coding-compliant for the key NSError. (error -10000)
Perhaps I need to inform my application that it should be able to read it’s documents like text instead of key-value??
if outError is not missing value then
set contents of outError to my NSError's errorWithDomain_code_userInfo_(my NSOSStatusErrorDomain, my unimpErr, missing value)
end if
It says:
readFromData:ofType:error:]: [<NSDocument 0x7fff74b64450> valueForUndefinedKey:]: this class is not key value coding-compliant for the key NSError. (error -10000)
I’m not actually doing anything with the data coming in, just logging it and it’s class. It is:
NSConcreteData
What the heck is that and how do I turn it into text. The Xcode help guide gives no results for this.
Yes – it means you’re trying to use the template-provided handlers, which are broken. See chapter 22 of my book for details.
The main problem with it, though, is that it’s attempting to use the reserved AS word “data” as a parameter variable. Change it to something like theData.
That worked, sort of. It returned the first four characters of the first paragraph of the text in the document. but there are 1344 characters in 26 paragraphs total.
Actually, looking at your data, it might well be UTF16. Whatever you saved it as from the old doc, you need to use the matching encoding enum to read it again.
Changing 8 to 16 in that line makes the four characters come in as chinese so I don’t’ think that’s correct.
set theString to current application's NSString's alloc()'s initWithData_encoding_(theData, current application's NSUTF16StringEncoding)
This was just text saved by an AS Studio app… so text saved by AppleScript using the write to file command with no special stuff at all. A plain text file. However, it has a custom extension to make it’s icon show up.
When I open it with text editor, it just shows up as several paragraphs of text.
dle2utxt0
Print Date:Monday
Application:QuarkXPress 7.0
Template:Standard Template
Modification Info:Last modified by Mark Munro, Friday, May 18, 2012 5:08:38 PM
Version:1.5.001
Path:WTM Server:Work:Client:Solutions:Reliance Vitamin:Company Resources:Test Material:Server Simulation:More Stuff:
Window Bounds:183 650 887 979 %
Start Company:New Row
Start Label:
Group:A-F
Client:
REL Stock Item:Yes
Product Family:
Product Size:
Background:Default
Center Panel:Default
UPC:Default
Text Color:Default (From Master File)
Text Color Address:Default (From Master File)
Text Color Product Name:Default (From Master File)
Repeat:1
Start new page:No
Notes:
%
It’s definitely Unicode of some flavour – notice all the nulls (00) in the data. You probably had Unicode text when you saved – there was at least one version of the OS where the write command would save that as Unicode. It even says “utxt” in the first line. If you wrote it out a bit at a time, it might be partly Unicode and partly MacRoman. That looks the case, given the first few characters look like ASCII/MacRoman.
Yes, I remember that OS… it might have been the one the old version of this app was built in.
One note, I am saving the document on 10.7 with the old app and trying to open it with the new app and it’s failing. I imagine the text encoding is burned into the old app as it was from the OS it was built on?
In any event, it looks like I’ll need to use a new extension and have my client use an upgrade file menu item or something that will simply read the file as a text file and then convert it to the new document format or something. Less than ideal but I’m not seeing another alternative.
Can’t make «class ocid» id «data kptr00000000E8C6D175FF7F0000» into type string. (error -1700)
I also tried this from those old days:
try
set textDocument to (textDocument as Unicode text) as string
set textDocument to «class ktxt» of (textDocument as record)
end try
-- result = Can't make «class ocid» id «data kptr00000000E8C6D175FF7F0000» into type string. (error -1700)
Any other thoughts, however obscure would be appreciated.
Okay, this is frustrating… Now I simply want to put in a dialog to stop and warn the user to use an upgrade menu instead of opening the document. However, I can’t detect the different class.
if class of textDocument = "NSConcreteData" then
doesn’t work because class of textDocument isn’t a string
if class of textDocument = NSConcreteData then
doesn’t work because the variable NSConcreteData isn’t’ defined.
If you want to check the class of a variable, use isKindOfClass_. That also works with subclasses, so you can use isKindOfClass_(current application’s NSData). But I don’t see how that’s going to help you; readFromData:ofType:error: is always going to return data.
There’s nothing odd about the file. It doesn’t seem to use any non-ASCII characters and it reads fine here with either of these:
set x to current application's NSString's stringWithContentsOfFile_encoding_error_("/Users/shane/Desktop/TEST OLD.RELV", current application's NSUTF8StringEncoding, missing value)
set x to current application's NSString's stringWithContentsOfFile_encoding_error_("/Users/shane/Desktop/TEST OLD.RELV", current application's NSMacOSRomanStringEncoding, missing value)
If I read it as data first, I get what you’re getting passed:
10:01:48.377 [6] set y to current application's NSData's dataWithContentsOfFile_("/Users/shane/Desktop/TEST OLD.RELV")
--> <<showing first 128 of 1364 bytes>>
<646c6532 00000000 75747874 00000544 000d0050 00720069 006e0074 00200044 00610074 0065003a 004d006f 006e0064 00610079 000d0041 00700070 006c0069 00630061 00740069 006f006e 003a0051 00750061 0072006b 00580050 00720065 00730073 00200037 002e0030 000d0054 0065006d 0070006c 00610074 0065003a>
10:01:48.378 [7] set z to current application's NSString's alloc()'s initWithData_encoding_(y, current application's NSUTF8StringEncoding)
--> dle2utxtD
Print Date:Monday
Application:QuarkXPress 7.0
Template:Standard Template
Modification Info:Last modified by Mark Munro, Tuesday, May 22, 2012 7:26:02 PM
Version:1.5.001
Path:WTM Client:Solutions:Reliance Vitamin:Company Resources:Test Material:Server Simulation:Reliance Server:NexPress (Test):
Window Bounds:47 1071 751 1400 %
Start Company:Test - 182755
Start Label:-
Group:A-Z
Client:Test - 182755
REL Stock Item:Yes
Product Family:
Product Size:
Background:Default
Center Panel:Default
UPC:Default
Text Color:Default (From Master File)
Text Color Address:Default (From Master File)
Text Color Product Name:Default (From Master File)
Repeat:1
Start new page:No
Notes:
%
So maybe you’re looking in the wrong place for the problem…
Well, I don’t have control over how it’s loaded because the data is handed to me by the readFromData_ofType_error_
I’ll play around with isKindOfClass_ and stopping the user from doing this and get them to run an conversion process instead. Then I can load the data myself and convert it.
on readFromData_ofType_error_(textDocument, typeName, outError)
set blnClassMatch to textDocument's isKindOfClass_(current application's NSData)
log "blnClassMatch=" & blnClassMatch
This returns true, tell me the data is a match. Perhaps because the document being opened has the correct extension?
Is there a way to ask the incoming data what class it is and get a response that I can compare to something… like:
if class of textDocument = NSConcreteData then DO THIS
You’re missing the point: as long as you use readFromData_ofType_error_, you’re always going to get data. You’re essentially asking for the file as a collection of bytes, which you then have to convert to whatever you think they should be. Changing extensions isn’t going to change anything in that regard.
You need to take this passed in data, and convert it to text using something like:
set theString to current application's NSString's alloc()'s initWithData_encoding_(theData, current application's NSUTF8StringEncoding)
That does work.
You also have to do the reverse when saving.
If that’s all too hard, you can get rid of readFromData_ofType_error_ and dataOfType_error_, and replace them with readFromURL_ofType_error_ and writeToURL_ofType_error_. In that case you will be passed a URL for the file, and you can read it directly yourself.