Mac file path

Hi All.
I’m just starting with Xojo and although over all I’m finding it pretty accessible, I’m totally stuck on a probably trivial problem. I’m on Mac Big Sur 11.3.
I’m retrieving a file path which is stored in an plist file as xml style tag. I fetch this with a shell script - “plutil -p '” + filePath + “.plist’”, which works just fine. The path is returned as text in the form :
Macintosh HD:System:Volumes:Data:Volumes:My files HD:My Folder:My File.txt
This is actually new to the last couple of systems. I need it to be in “Posix” format, as they would say in Applescript like this :
/Volumes/My files HD/My Folder/My File.txt
to use it in Xojo. In AppleScript, this would be a piece of cake !
I can’t seem to find any easy way to do this in Xojo. I can add a slash in front and do a “ReplaceAl(”:","/")" but that’s not enough !
Could any kind soul help me out here please ? TIA.

If the filepath is stored in a file why not store it as a posix path in the first place?

It’s deprecated, but you can call:

var f = new folderitem(myOldColonsPath)

to create a folderitem initialized with the old-style Mac path you have, and then access the folderitem’s .NativePath property to get it in the POSIX form.

Ahh ! That’s because it’s stored by other software. I just need to recover the value. It’s also a string as such and that’s how I need it ! See my answer to Mathew.
Thanks for your answers.

Thanks for your answer. I’m not sure if I want to use a solution based on deprecated functions, as I don’t think the colon path format is going to disappear anytime soon on Mac. The other thing is that I’m using the conversion as a string, as I need to place different suffixes on it according to which file I’m addressing wit it after… .txt, .xml, .plist all based on the same root path.

Use

dim f as new folderitem(myOldColonsPath, Folderitem.PathModes.Native)

Thanks for your reply.
My as yet sparse understanding of Xojo leads me to believe that this would return a folderItem and not a string, which is what I need, to be able to use it in the command line after. How could I then convert this back to a string ?
I have solved it temporarily by incorporating an AppleScript 1 liner (well 3 if you count the “On Run” and “End Run” !), which does the job perfectly, but I was really trying to see if there was a simple native Xojo solution…

If you need to convert between path types then you need a folderitem.

I have an old declare to make a folderitem out of an absolute path (yes, this is still necessary with paths that come from AppleScript):

Protected Function AbsolutePath(hasAbsolutePath As String) As Folderitem
  
  Dim theNativePath As String
  
  #If TargetMacOS Then
    
    Declare Function CFURLCopyFileSystemPath Lib "Foundation" (anURL As Ptr, pathStyle As Int32) As CFStringRef
    Declare Function CFURLCreateWithFileSystemPath Lib "Foundation" (CFURLCreateWithFileSystemPath As Ptr, filePath As CFStringRef, pathStyle As Int32) As Ptr
    
    Const kCFURLPOSIXPathStyle = 0
    Const kCFURLHFSPathStyle = 1
    
    Dim ptrNSURL As Ptr = CFURLCreateWithFileSystemPath(nil, hasAbsolutePath, kCFURLHFSPathStyle)
    theNativePath = CFURLCopyFileSystemPath(ptrNSURL, kCFURLPOSIXPathStyle)
    
  #Else
    'Windows, Linux: NativePath is the same as Xojo's deprecated AbsolutePath
    theNativePath = hasAbsolutePath
    
  #EndIf
  
  Return New FolderItem(theNativePath, folderItem.PathModes.Native)
  
End Function

You would then use this function first and then call the NativePath function of the resulting Folderitem.

Thanks a lot for that. I’ll try it out as soon as I have a moment.
I guess my dream of a one-liner in Xojo is ephemeral then !
Ah well. I’ll still opt for the Xojo native solution if it works for me :smiley:

Perhaps all you need to add to:

is:

mypath = f.NativePath

This doesn’t work. PathModes.native is the POSIX path. If you just provide the old-style path as a string, the FolderItem constructor still knows what to do.

For the code in a button:

var f as folderitem

f = new FolderItem("Macintosh HD:Applications", Folderitem.PathModes.Native)

msgbox f.NativePath

The result is: /Users/yourname/Development/Macintosh HD:Applications

However,

var f as folderitem

f = new FolderItem("Macintosh HD:Applications")

msgbox f.NativePath

The result is: /Applications

Yes, it returns a folderitem pointing the the file of interest. Then you just use the .NativePath or .ShellPath to get the version of the path you want back. it converts it for you. Two lines of code.

Wow ! Now that IS cool :+1:

I’ll test this, and be back with my verdict :smiley:

Mmmm… I’m obviously doing something very wrong, as this doesn’t work for me at all :frowning:
If I take your code as is, when my test app is on my desktop, it returns :
/Users/me/Desktop/Macintosh HD/Applications
If I change the path to something on an external disk
f = new FolderItem(“Misc:Test Folder:some picture.png”)
it returns :
/Users/me/Desktop/Misc/Test Folder/some picture.png
… so it appears to be adding the path to my test app in front of the actual path that I’m asking for !
I’m going to try Beatrix’s proposal to see if I have any more luck with the more complex solution…
I’ll be back !

Well, despite what Mathew says, your solution works just fine for me, just as it is !

Feeding it “Misc:Test Folder:some picture.png” as a path returns :

/Volumes/Misc/Test Folder/some picture.png

… which is exactly what I was expecting, and hoping for ! OK, so Mathew’s solution seemed sooo much simpler, but too good to be true apparently.

I’ll wait to see if I get anymore feedback on this, but short of anything else, I’ll have to accept your solution as the working one.
Thanks again for your help :+1:

Not sure… just tried it with a new project, placing a single button on the Window with the code:

var f as folderitem

f = new FolderItem("Macintosh HD:Applications")

msgbox f.NativePath

It returns /Applications. :man_shrugging:

But glad you found a workable solution.

Perhaps this is something to do with Big Sur… ? I did exactly what you say here, new project, single button on the window with your exact code copy/pasted and it returns :
/Users/me/Desktop/Macintosh HD/Applications
… when my new project is on on the desktop. If I do the same thing before saving the new project anywhere, it adds some very obscure path full of numbers and unknown subfolder names, before adding “/Macintosh HD/Applications” on the end. Really weird :thinking: Some temporary folder or something ?
Thanks very much for your efforts anyway. Really appreciated.

Update :
I built the little app and put it on a virtual MacOSX 10.15 Catalina and it works just as you said !!
It does tend to point towards a Big Sur thing, but I’ll try to confirm. I have access to another machine with Big Sur on it so I’ll give it a try. If it works there, then there’s something on my own computer making it go pear shaped !

Update 2 :
Just tried with different paths on my virtual Catalina, and it ONLY works with “Macintosh HD:Applications”. Any other path adds the bits in front :frowning: Still no joy then. I don’t know if you tried with any other paths than the Applications folder, but it’s the only one that works with your code for me.

Interesting; I was wondering about that. I’m not on BS.

It sounds like an OS-level change, but you could also try forcing the old (deprecated) syntax with

f = new FolderItem("Macintosh HD:Applications",0)

I also did try it with some other paths such as Macintosh HD:Users:me:Documents, and it worked.

As I understood it, you were reading a string with an old-style path and wanted to get the POSIX path. I took your path, /System/Volumes/Data/Volumes/My files HD/My Folder/My File.txt – which, BTW, doesn’t even exist on my computer, ran this code:

var f as folderitem

f = new FolderItem("Macintosh HD:System:Volumes:Data:Volumes:My files HD:My Folder:My File.txt",0)

msgbox f.NativePath

And got:

/System/Volumes/Data/Volumes/My files HD/My Folder/My File.txt

Anyway, glad Beatrix’s more robust solution works universally. Thanks for checking it out on Catalina… thought I might be going crazy.

… which would work just fine ! It seems that on BS, the directory catalogues are kept on the new “Data Volume” which now gets greated by the system on APFS. They have separated the system itself from the data for “added security” supposedly ! I’ll try the deprecated format for the hell of it, but I’m not crazy about using deprecated stuff in general, as you know it’s going to stop working at some point !
Thanks again for your help and tenacity :slight_smile:

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.