FileKit icon indicating copy to clipboard operation
FileKit copied to clipboard

How to get relative path?

Open devSC opened this issue 9 years ago • 3 comments

It's have a easy method to get relative path?

devSC avatar Oct 23 '16 06:10 devSC

relative path from what? from current path?

there is no cocoa functions I think so we must implement it

I could provide a non tested code

  • maybe we must standardize the path before
  • then some code maybe are not swift3 . compliant
  • return a Path will be more elegant
extension Path {
 
    func stringWithPathRelative(to anchorPath: Path) -> String {
        let pathComponents = self. components
        let anchorComponents = anchorPath. components

        var componentsInCommon = 0
        for (c1, c2) in zip(pathComponents, anchorComponents) {
            if c1 != c2 {
                break
            }
            componentsInCommon += 1
        }

        let numberOfParentComponents = anchorComponents.count - componentsInCommon
        let numberOfPathComponents = pathComponents.count - componentsInCommon

        var relativeComponents = [String]()
        relativeComponents.reserveCapacity(numberOfParentComponents + numberOfPathComponents)
        for _ in 0..<numberOfParentComponents {
            relativeComponents.append("..")
        }
        relativeComponents.appendContentsOf(pathComponents[componentsInCommon..<pathComponents.count])

        return String.pathWithComponents(relativeComponents)
    }
}

phimage avatar Jan 16 '17 12:01 phimage

I have something like this in my extension

    func relativeTo(path: Path) -> Path? {
        let root = path.components
        let this = self.components
        
        guard this.starts(with: root) else {
            return nil
        }
        
        let rel = this.suffix(from: root.endIndex)
        let path = rel.map({ $0.rawValue }).joined(separator: "/")
        
        return Path(path)
    }

And I use it like that

let filePath = file.relativeTo(path: Path.userDocuments)

This function does not handle some edge cases, but it suits my needs.

ivankolesnik avatar May 15 '17 10:05 ivankolesnik

I have made separate repo, SwiftyRelativePath, for just this purpose with tests for edge cases.

let url0 = URL(fileURLWithPath: "/computer/qubit/17")
let url1 = URL(fileURLWithPath: "/computer/lab")
url0.relativePath(from: url1) // -> "../qubit/17"

Feel free to import it into FileKit.

neoneye avatar Jan 21 '18 03:01 neoneye