UTI's, file types, & icons, yet again

The problem: Saving a data file doesn’t add a file extension in the Save dialog and the resulting file, even with a manually added extension does not have the correct metadata so it’s seen as a text document and the custom icon is not displayed.

I’ve read all the relevant documentation and years worth of Xojo and RealBasic forum posts on this topic, and it seems to be a recurring problem. I’m developing for the Mac platform and am trying to avoid the deprecated MacCreator and MacType codes. I’m posting here in the General forum because I think this is of general interest.

Here’s what I’ve done:

My Build Settings look like this:
Mac App Name: SectorMaker
Framework: Cocoa
Creator Code: ???
File Types: (first 2 not relevant but shown for completeness)
ExportFileTypes.Sec Role: None
ExportFileTypes.Metadata Role: None
SaveFileTypes.Data CHECKED and Role: Editor
Bundle Identifier: com.naasirka.sectormaker

SaveFileTypes File Types Set (Only 1 file type defined)
Display Name: SectorMaker Data
Object Name: Data
MacType: ???
MacCreator: ???
Extensions: nsec
UTI’s: com.naasirka.sectormaker.nsec
Icon: Defined and loaded in

FileSaveMenuItem MenuHandler (excerpted)

[code] dim xml As XmlDocument
dim f as FolderItem, dlg As New SaveAsDialog, t As TextOutputStream
dlg.InitialDirectory=SpecialFolder.Documents
dlg.PromptText=“Save Sector Data”
dlg.Filter=SaveFileTypes.Data
dlg.SuggestedFileName=SectorName
f=dlg.ShowModalWithin(MainWindow)
if f <> Nil then
t=TextOutputStream.Create(f)
xml=New XmlDocument

blah, blah, blah

t.Write xml.Transform(IndentXML)
t.Close

end if
Return True
[/code]

Manually edited info.plist file in bundle:

[code]<?xml version="1.0" encoding="UTF-8"?>

CFBundleExecutable SectorMaker CFBundleName SectorMaker CFBundleIdentifier com.naasirka.sectormaker CFBundleInfoDictionaryVersion 6.0 CFBundleVersion 1.0.0.0.0 CFBundleDevelopmentRegion en CFBundlePackageType APPL CFBundleSignature ???? CFBundleGetInfoString 1.0 Copyright © 2013 Art Gorski CFBundleShortVersionString 1.0 CFBundleIconFile SectorMaker.icns LSMinimumSystemVersion 10.6.0 CFBundleDocumentTypes CFBundleTypeName SectorMaker Data CFBundleTypeIconFile Data.icns CFBundleTypeOSTypes **** CFBundleTypeExtensions nsec LSItemContentTypes com.naasirka.sectormaker.nsec CFBundleTypeRole Editor UTExportedTypeDeclarations UTTypeConformsTo public.data public.item UTTypeIdentifier com.naasirka.sectormaker.nsec UTTypeTagSpecification public.filename-extension nsec [/code]

Can anyone see anything wrong in any of this? Thanks in advance for your help.

Update: Put my built app on another Mac and the icon and file metadata now works. Must be a caching issue on my development Mac.

However, the file extension is still not added in the Save dialog. If I do something like:

dlg.SuggestedFileName=SectorName + ".nsec"

when the Save dialog opens, the entire string is selected for editing, so the dialog doesn’t think the “.nsec” is an extension but part of the filename. And the “Hide extension” checkbox doesn’t do anything.

So can anyone offer any advice on how to get the Save dialog to behave?

However, the file extension is still not added in the Save dialog
Is your application define (for the OS) the nsec extension ?

Does your application exists on your development machine where you do not see the correct icon ?

Nota: I set a custom icon to a SQLite db file (.sqlite). The icon is defined in a FileType in the application. It is only shown when I have the application in the hard disk. If I delete it, do my business, power off: I loose the custom icon. When I build the application, the db file see its custom icon back.

The problem: Saving a data file doesn’t add a file extension in the Save dialog and the resulting file, even with a manually added extension does not have the correct metadata so it’s seen as a text document and the custom icon is not displayed.
If you use TextOutputStream, your file will be seen as text file. On OS X, some text file icons are set by OS X.

If you want to be able to save data in a file (text data or not) and get your own icon / extension seen as belonging to your application, use BinaryStream.

You have an example for save:
http://documentation.xojo.com/index.php/SaveAsDialog

Add the code in your project, add a MenuItem to call it, add in the code stuff to save your data and try what the result is.

Why don’t you use:
http://documentation.xojo.com/index.php/XMLDocument.SaveXML

to save your xml data ?

I’d be back tomorrow with more time if needed.

Thanks, Emile. Everything works great now even with TextInputStream except that the Save dialog does not append the .nsec extension to the filename. Saving the file without an extension, it is recognized as a text file by the Finder, but if I add the .nsec extension it immediately displays the correct icon and all the metadata on the file is correct. So the only problem I have left if how to get the Save dialog to automatically add the extension to the suggested file name.

You must specify the suggested file name with the file extension when displaying the save as dialog.

It doesn’t help that Xojo’s missing a large chunk of UTI functionality, so it can easily mess up the launch services database.

You may also want to use a binary stream as I believe the text streams set the MacType to be Text.

Lastly, while you may want to forget the legacy MacType and MacCreator, setting this won’t hurt.

You may also find it easier to deal with UTI, if you use App Wrapper as it has a visual UTI editor and can embedded the UTI at build or run time (the mini version doesn’t support UTI).

Art:

I am not really sure that you have to use TextInputStream / TextOutputStream to do that. These two are involved in TEXT operations only.

If you use BinaryStream…
Get an eye below; this have been done with Xojo provided code (mostly):

  1. New project (Xojo 3.3)
  2. Add a PushButton you name “PB_Save”
    Copy / Paste the code below:
'wMain.Controls.PB_Save.Action Sub Action()
Dim dlg as New SaveAsDialog
Dim f as FolderItem
dim Output As BinaryStream
dlg.InitialDirectory=SpecialFolder.Documents
dlg.promptText="Prompt Text"
dlg.SuggestedFileName="Suggested Filename"
dlg.Title="Title Property"
dlg.Filter=FT_Custom.All //defined as a file type in FileTypes1 file type set
f=dlg.ShowModal()
If f <> Nil then
//file saved
Output = BinaryStream.Create(f,true)
Output.Write("Some data.")
Output.WriteInt8 15
Output.Close
Else
// User canceled
End if
'End Sub

Add a new FileType Set and name it FT_Custom
Click in the + sign and fills the fields (you can skip Type and Creator
Put nsec in Extensions
Paste an Icon Image and Mask in Icon (Image AND Mask)

Go to the App, click in Icon and paste Icon Image and Mask (Image AND Mask).

Save the project,
Build the project (move the application beside your project if it was saved in multiple folders),
Run the application,
Click in the Save Button,
Save the data

Quit the application and watch your file with your own custom icon and its file extension.

You’re done.

To read the file contents, you only have to do the reverse:

Dim Input As Binary Stream

Input = BinaryStream.Open(f) // Probably
AString = Input.Read // Probably
AnInt8 = Input.ReadInt8 // Probably
Input.Close // Probably

Code to read was not tested.

HTH,

Emile

Thanks, I’ll give binarystream a try.

BTW: when you try, be careful and delete any application that use your file extension or use a different one.

If you already have an application (in your hard disk) with the same file extension, strange things can arise.

Made the switch to binarystream, added the file extension to the suggestedfilename, and changed the MacType to “nSec” in the filetype. I wish Xojo provided better documentation on getting this to work properly but everything seems fine now.

It only miss (I do not found it) an article on what to use to save data: TextOutputStream for TEXT and BinaryStream for the rest of the kinds of data to save.

Also, an article on how to drag and drop (to Desktop / Finder and onto Application) can be fine.

Not that this is difficult, but why 100,000 (and more) Xojo users have to spend (waste ?) hours to test what technology to use to achieve their goals…

Now, who am I to advice the Xojo team ?