Doc-Based, Need to open a text-based document

Okay, then I’m very confused… because the code is what is failing.

I want to STOP the app from letting someone open the old documents.

New documents work fine… it’s the old ones that are a problem. Those FAIL when I run the data through this:

set theString to current application’s NSString’s alloc()'s initWithData_encoding_(theData, current application’s NSUTF8StringEncoding)

So, my only choice seems to be to detect an older file type and warn the user and stop. Then, the user will have to choose some other menu item (NOT Open, but “Convert Old File”) which will run something separate from the document file management routines.

Does that make sense?

Am I missing something??

Try changing NSUTF8StringEncoding to NSMacOSRomanEncoding.

That comes through like this:

<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 00530074 0061006e 00640061 00720064 00200054 0065006d 0070006c 00610074 0065000d 004d006f 00640069 00660069 00630061 00740069 006f006e 00200049 006e0066 006f003a 004c0061 00730074 0020006d 006f0064 00690066 00690065 00640020 00620079 0020004d 00610072 006b0020 004d0075 006e0072 006f002c 00200054 00750065 00730064 00610079 002c0020 004d0061 00790020 00320032 002c0020 00320030 00310032 00200037 003a0032 0036003a 00300032 00200050 004d000d 00560065 00720073 0069006f 006e003a 0031002e 0035002e 00300030 0031000d 00500061 00740068 003a0057 0054004d 20140043 006c0069 0065006e 0074003a 0053006f 006c0075 00740069 006f006e 0073003a 00520065 006c0069 0061006e 00630065 00200056 00690074 0061006d 0069006e 003a0043 006f006d 00700061 006e0079 00200052 00650073 006f0075 00720063 00650073 003a0054 00650073 00740020 004d0061 00740065 00720069 0061006c 003a0053 00650072 00760065 00720020 00530069 006d0075 006c0061 00740069 006f006e 003a0052 0065006c 00690061 006e0063 00650020 00530065 00720076 00650072 003a004e 00650078 00500072 00650073 00730020 00280054 00650073 00740029 003a000d 00570069 006e0064 006f0077 00200042 006f0075 006e0064 0073003a 00340037 00200031 00300037 00310020 00370035 00310020 00310034 00300030 00200025 000d0053 00740061 00720074 00200043 006f006d 00700061 006e0079 003a0054 00650073 00740020 002d0020 00310038 00320037 00350035 000d0053 00740061 00720074 0020004c 00610062 0065006c 003a002d 000d0047 0072006f 00750070 003a0041 002d005a 000d0043 006c0069 0065006e 0074003a 00540065 00730074 0020002d 00200031 00380032 00370035 0035000d 00520045 004c0020 00530074 006f0063 006b0020 00490074 0065006d 003a0059 00650073 000d0050 0072006f 00640075 00630074 00200046 0061006d 0069006c 0079003a 000d0050 0072006f 00640075 00630074 00200053 0069007a 0065003a 000d0042 00610063 006b0067 0072006f 0075006e 0064003a 00440065 00660061 0075006c 0074000d 00430065 006e0074 00650072 00200050 0061006e 0065006c 003a0044 00650066 00610075 006c0074 000d0055 00500043 003a0044 00650066 00610075 006c0074 000d0054 00650078 00740020 0043006f 006c006f 0072003a 00440065 00660061 0075006c 00740020 00280046 0072006f 006d0020 004d0061 00730074 00650072 00200046 0069006c 00650029 000d0054 00650078 00740020 0043006f 006c006f 00720020 00410064 00640072 00650073 0073003a 00440065 00660061 0075006c 00740020 00280046 0072006f 006d0020 004d0061 00730074 00650072 00200046 0069006c 00650029 000d0054 00650078 00740020 0043006f 006c006f 00720020 00500072 006f0064 00750063 00740020 004e0061 006d0065 003a0044 00650066 00610075 006c0074 00200028 00460072 006f006d 0020004d 00610073 00740065 00720020 00460069 006c0065 0029000d 00520065 00700065 00610074 003a0031 000d0053 00740061 00720074 0020006e 00650077 00200070 00610067 0065003a 004e006f 000d004e 006f0074 00650073 003a000d 0025000d>

Sorry that last one was with a different encoder. The NSMacOSRomanEncoding one returned:

unable to set argument 3 - the AppleScript value <NSAppleEventDescriptor: 'obj '{ ‘form’:‘usrp’, ‘want’:‘prop’, ‘seld’:‘utxt’(“NSMacOSRomanEncoding”), ‘from’:‘null’() }> could not be coerced to type Q. (error -10000)

That sounds like you left out the “current application’s”. How about you copy and paster the first three or four lines of your handler here.

Here is the whole thing:

on readFromData_ofType_error_(textDocument, typeName, outError)
		--	Detect old document types
		set blnOldDocument to (typeName as string) = "LabelDocument1"
		if blnOldDocument = true then
			set theString to current application's NSString's alloc()'s initWithData_encoding_(textDocument, current application's NSMacOSRomanEncoding)
			log textDocument
			--display dialog "This document must be converted!"
			return false
		--	This subroutine will load a document file into the curent document's interface
		set listDocumentData to current application's NSKeyedUnarchiver's unarchiveObjectWithData_(textDocument)
		set {my refUIWeekdaySelection, my refUITableData} to (listDocumentData as list)
		return true
	end readFromData_ofType_error_

Try logging theString rather than textDocument (which is not a great name for data…).

Whoops… good catch, although it’s not getting that far.

readFromData:ofType:error:]: unable to set argument 3 - the AppleScript value <NSAppleEventDescriptor: 'obj '{ ‘form’:‘usrp’, ‘want’:‘prop’, ‘seld’:‘utxt’(“NSMacOSRomanEncoding”), ‘from’:‘null’() }> could not be coerced to type Q. (error -10000)

That should be NSMacOSRomanStringEncoding. My mistake for typing from memory.

<Shameless plug: Using my AppleScriptObjC Explorer as an external editor gives you code-completion, which avoids this sort of typo.>

So, no errors but now I am back to just having the first four characters of the text from the file:


I think this happened way back earlier in this or another thread.

So, this IS decoding it with no error but I don’t’ have all the data.

I wonder if it’s a logging artefact. Coerce it to text and log paragraph 2 of the result.

set x to theString as text
log x
set y to paragraph 2 of x
log y

The only result was


Very strange. The file you sent me reads fine here.

As a document of a document based app in a readFromData_ofType_error routine?

It shouldn’t make any difference; data is data. But send me the project and file again if you want me to check.

What a saga…

So it turns out that stringWithContentsOfFile_encoding_error_ reads the file (sort of) OK, but initWithData_encoding_ has no luck, even though you’d expect them to do the same thing.

It looks like the file has mixed encoding: the first line was saved as MacRoman text, and the rest as Unicode (I suspect courtesy of the madness of the write command at one time). Whatever, initWithData_encoding_ gives up where the encoding changes.

Surprisingly, this (sort of) works:

set theString to current application's NSString's alloc()'s initWithData_usedEncoding_(dataFromDocument, reference)

I say “surprisingly” because no such method is listed. But it seems to be an undocumented analog to stringWithContentsOfFile_usedEncoding_. (The latter claims UTF8 encoding in this case, which isn’t correct).

Anyway, the only reliable way I can see is to split the data. And in fact if the first line doesn’t matter, which I suspect is the case, you can just skip it, and decode the rest, which is – for yet another wrinkle – NSUTF16LittleEndianStringEncoding. So:

		set aBit to dataFromDocument's subdataWithRange_({19, (dataFromDocument's |length|() as integer) - 20})
		set theString to current application's NSString's alloc()'s initWithData_encoding_(aBit, current application's NSUTF16LittleEndianStringEncoding)
		log theString

Even then there’s an odd character or two in the Path in the file.

If you really needed it, I’d advise replacing readFromData_ofType_error_ in your app, as mentioned earlier.


Nope, I don’t need the first line or that path… so that code works perfectly.


Now I can parse the old info, put it into the new interface and then force the user to SAVE AS when they are trying to save the file.

I am curious to know… when you say replacing readFromData_ofType_error_, what would I replace that with and would it still give me all the “free” document management stuff, including the cool new features? I’m not sure I followed that earlier… Feel free to point me to a particular area of your book if that’s mentioned. I don’t recall it from the doc section, but I’m not sure I read the whole thing through yet.

Yes, you keep all that.

I only covered the default ones; for most cases they’re all that’s needed. Search in the Xcode docs for “Overriding the URL and File Package Reading Methods” for details. A case where they’re needed is if you use file packages.