Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa/Objective-C get a HFS path (path:to:desktop) from a posix path (path/to/desktop)

I am on OSX, Objective-C.

I have a path/NSURL like

/Users/xxx/Desktop/image2.png

But i pass it to a third party application that excpects finder pathes like

Harddisk:Users:Desktop:image2.png

Is there any method (i can't find) to convert pathes like that or get them out of an NSURL (if possible without string modifying)?

In AppleScript it is

return POSIX file "/Users/xxx/Desktop/image2.png" -->  Harddisk:Users:xxx:Desktop:image2.png

EDIT: This is pretty much the same: Cocoa path string conversion Unfortunately, the method is deprecated...

like image 329
Pat_Morita Avatar asked May 13 '26 13:05

Pat_Morita


2 Answers

There is no (easy) alternative at the moment.

The function CFURLCopyFileSystemPath is not deprecated, only the enum case kCFURLHFSPathStyle is deprecated but the raw value 1 is still working and avoids the warning.

I'm using this category of NSString

@implementation NSString (POSIX_HFS)

- (NSString *)hfsPathFromPOSIXPath
{
    CFStringRef hfsPath = CFURLCopyFileSystemPath((CFURLRef)[NSURL fileURLWithPath:self], 1);
    return (NSString *)CFBridgingRelease(hfsPath);
}
@end

The function works also in Swift. The Swift version is a bit more sophisticated and adds the trailing semicolon representing a dictionary implicitly, here as an extension of URL:

extension URL {

  func hfsPath() -> String?
  {
    if let cfpathHFS = CFURLCopyFileSystemPath(self as CFURL, CFURLPathStyle(rawValue: 1)!) { // CFURLPathStyle.CFURLHFSPathStyle)
      let pathHFS = cfpathHFS as String
      do {
        let info = try self.resourceValues(forKeys: [.isDirectoryKey, .isPackageKey])
        let isDirectory = info.isDirectory!
        let isPackage =  info.isPackage!

        if isDirectory && !isPackage {
          return pathHFS + ":" // directory, not package
        }
      } catch _ {}
      return pathHFS
    }
    return nil
  }
}
like image 123
vadian Avatar answered May 15 '26 21:05

vadian


Vadians answer is better than this one - but if vadians method is deprecated, this will be an alternative. Idea is to use applescripts methods to get HFS path called easily with an osascript from an NSString category.

NSString category (credits: https://stackoverflow.com/a/19014463/4591992)

@implementation NSString (ShellExecution)

- (NSString*)runAsCommand {
    NSPipe* pipe = [NSPipe pipe];

    NSTask* task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/sh"];
    [task setArguments:@[@"-c", [NSString stringWithFormat:@"%@", self]]];
    [task setStandardOutput:pipe];

    NSFileHandle* file = [pipe fileHandleForReading];
    [task launch];

    NSString* result = [[NSString alloc] initWithData:[file readDataToEndOfFile] encoding:NSUTF8StringEncoding];
    return result;
}

@end

Usage for this case:

NSString* posixToHFS = [NSString stringWithFormat:@"osascript -e 'POSIX file \"%@\" as text'",filePath];
filePath = [posixToHFS runAsCommand];
like image 32
Pat_Morita Avatar answered May 15 '26 21:05

Pat_Morita



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!