NSURL:显示相对网址?

时间:2014-04-24 02:55:00

标签: cocoa path nsurl

有没有人遇到NSURL的解决方案或添加内容来制作基于以下内容的相对文件URL:

NSURL * from = [NSURL URLWithString:@"/Users/me/scripts/python/test.py"];
NSURL * to = [NSURL URLWithString:@"/Users/me/new-scripts/python/test.py"];
NSURL * rel = [NSURL URLFrom:from to:to];
NSLog(@"%@",rel); --> ../../new-scripts/python/test.py

而且我也希望能够采用相对路径“../../new-scripts/python/test.py”并将其与绝对URL组合以获取新的URL。

[NSURL URLWithString:@"../../new-scripts/python/test.py" relativeToURL:[NSURL fileURLWithPath:@"/Users/me/scripts/python/test.py"]];

谷歌上没有遇到过任何问题,我本人也试图自己实施一些东西,但最终可能会有很多错综复杂的正确性。想知道Apple是否存在某种东西或者是否存在C / Posix功能?

谢谢!

1 个答案:

答案 0 :(得分:0)

我遇到了这个https://github.com/karelia/KSFileUtilities,但它不适用于文件网址。所以我写了这个。 http://pastebin.com/FKYjVwpU

#import <Foundation/Foundation.h>

NSString * relativize(NSURL * to, NSURL * from, BOOL fromIsDir);

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //NSURL * u = [NSURL URLWithString:@"../../scripts" relativeToURL:[NSURL fileURLWithPath:@"/Users/aaronsmith/Development/aaron/"]];
        //NSLog(@"%@",u.absoluteString);
        //NSLog(@"%@",[NSURL URLWithString:@"../../scripts.py" relativeToURL:[NSURL fileURLWithPath:@"/Users/aaronsmith/scipts/"]]);

        NSURL * to = NULL;
        NSURL * from = NULL;

        to = [NSURL fileURLWithPath:@"/Users/aaronsmith/uverse/upload-issue.py"];
        from = [NSURL fileURLWithPath:@"/Users/aaronsmith/scripts.scrpt"];
        assert([relativize(to,from,FALSE) isEqualToString:@"./uverse/upload-issue.py"]);

        to = [NSURL fileURLWithPath:@"/Users/aaronsmith/uverse/test/upload-issue.py"];
        from = [NSURL fileURLWithPath:@"/Users/aaronsmith/"];
        assert([relativize(to, from, TRUE) isEqualToString:@"./uverse/test/upload-issue.py"]);
        relativize(to,from,TRUE);

        to = [NSURL fileURLWithPath:@"/Users/aaronsmith/uverse/test/upload-issue.py"];
        from = [NSURL fileURLWithPath:@"/Users/aaronsmith/example/scripts/"];
        assert([relativize(to,from,TRUE) isEqualToString:@"../../uverse/test/upload-issue.py"]);

        to = [NSURL fileURLWithPath:@"/Users/aaronsmith/uverse/test/scripts/stuff/upload-issue.py"];
        from = [NSURL fileURLWithPath:@"/Users/johnson/scripts/"];
        assert([relativize(to,from,TRUE) isEqualToString:@"../../aaronsmith/uverse/test/scripts/stuff/upload-issue.py"]);

        to = [NSURL URLWithString:@"/Users/aaronsmith/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/"];
        assert([relativize(to,from,TRUE) isEqualToString:@"./upload-issue.py"]);

        to = [NSURL URLWithString:@"/Users/aaronsmith/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/scripts.scrpt"];
        assert([relativize(to,from,FALSE) isEqualToString:@"./upload-issue.py"]);

        to = [NSURL URLWithString: @"/Users/aaronsmith/uverse/test/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/test/whatever/scripts/script.scrpt"];
        assert([relativize(to,from,FALSE) isEqualToString:@"../../../uverse/test/upload-issue.py"]);

        to = [NSURL URLWithString: @"/Users/aaronsmith/uverse/test/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/test/whatever/scripts/"];
        assert([relativize(to,from,TRUE) isEqualToString:@"../../../uverse/test/upload-issue.py"]);

        to = [NSURL URLWithString:@"/Users/aaronsmith/uverse/test/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/uverse/test/scripts.scrpt"];
        assert([relativize(to, from, FALSE) isEqualToString:@"./upload-issue.py"]);

        to = [NSURL URLWithString:@"/Users/aaronsmith/upload-issue.py"];
        from = [NSURL URLWithString:@"/Users/aaronsmith/uverse/test/scripts.scrpt"];
        assert([relativize(to, from, FALSE) isEqualToString:@"../../upload-issue.py"]);
    }

    return 0;
}

NSString * relativize(NSURL * to, NSURL * from, BOOL fromIsDir) {
    NSString * toString = [[to absoluteString] stringByStandardizingPath];
    NSMutableArray * toPieces = [NSMutableArray arrayWithArray:[toString pathComponents]];

    NSString * fromString = [[from absoluteString] stringByStandardizingPath];
    NSMutableArray * fromPieces = [NSMutableArray arrayWithArray:[fromString pathComponents]];

    NSMutableString * relPath = [NSMutableString string];

    NSString * toTrimmed = toString;
    NSString * toPiece = NULL;
    NSString * fromTrimmed = fromString;
    NSString * fromPiece = NULL;

    NSMutableArray * parents = [NSMutableArray array];
    NSMutableArray * pieces = [NSMutableArray array];

    if(toPieces.count >= fromPieces.count) {
        NSUInteger toCount = toPieces.count;
        while(toCount > fromPieces.count) {
            toPiece = [toTrimmed lastPathComponent];
            toTrimmed = [toTrimmed stringByDeletingLastPathComponent];
            [pieces insertObject:toPiece atIndex:0];
            toCount--;
        }

        while(![fromTrimmed isEqualToString:toTrimmed]) {
            toPiece = [toTrimmed lastPathComponent];
            toTrimmed = [toTrimmed stringByDeletingLastPathComponent];
            fromPiece = [fromTrimmed lastPathComponent];
            fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent];
            if(![toPiece isEqualToString:fromPiece]) {
                if(![fromPiece isEqualToString:[fromPiece lastPathComponent]] || fromIsDir) {
                    [parents addObject:@".."];
                }
                [pieces insertObject:toPiece atIndex:0];
            }
        }

    } else {
        NSUInteger fromCount = fromPieces.count;

        while(fromCount > toPieces.count) {
            fromPiece = [fromTrimmed lastPathComponent];
            fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent];
            if(![fromPiece isEqualToString:[fromString lastPathComponent]] || fromIsDir) {
                [parents addObject:@".."];
            }
            fromCount--;
        }

        while(![toTrimmed isEqualToString:fromTrimmed]) {
            toPiece = [toTrimmed lastPathComponent];
            toTrimmed = [toTrimmed stringByDeletingLastPathComponent];
            fromPiece = [fromTrimmed lastPathComponent];
            fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent];
            [parents addObject:@".."];
            [pieces insertObject:toPiece atIndex:0];
        }

    }

    [relPath appendString:[parents componentsJoinedByString:@"/"]];
    if(parents.count > 0) [relPath appendString:@"/"];
    else [relPath appendString:@"./"];
    [relPath appendString:[pieces componentsJoinedByString:@"/"]];

    NSLog(@"%@",relPath);

    return relPath;
}