Skip to content

Commit b92b859

Browse files
mbvreddyparkera
authored andcommitted
implementation for NSURL.standardizedURL and NSURL.filePathURL properties (#360)
1 parent 48556cc commit b92b859

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

Foundation/NSURL.swift

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,20 @@ public class NSURL: NSObject, NSSecureCoding, NSCopying {
521521

522522
/* A string constant for the "file" URL scheme. If you are using this to compare to a URL's scheme to see if it is a file URL, you should instead use the NSURL fileURL property -- the fileURL property is much faster. */
523523
public var standardized: URL? {
524-
NSUnimplemented()
524+
guard (path != nil) else {
525+
return nil
526+
}
527+
528+
let URLComponents = NSURLComponents(string: relativeString)
529+
guard ((URLComponents != nil) && (URLComponents!.path != nil)) else {
530+
return nil
531+
}
532+
guard (URLComponents!.path!.contains("..") || URLComponents!.path!.contains(".")) else{
533+
return URLComponents!.url(relativeTo: baseURL)
534+
}
535+
536+
URLComponents!.path! = _pathByRemovingDots(pathComponents!)
537+
return URLComponents!.url(relativeTo: baseURL)
525538
}
526539

527540
/* Returns whether the URL's resource exists and is reachable. This method synchronously checks if the resource's backing store is reachable. Checking reachability is appropriate when making decisions that do not require other immediate operations on the resource, e.g. periodic maintenance of UI state that depends on the existence of a specific document. When performing operations such as opening a file or copying resource properties, it is more efficient to simply try the operation and handle failures. If this method returns NO, the optional error is populated. This method is currently applicable only to URLs for file system resources. For other URL types, NO is returned. Symbol is present in iOS 4, but performs no operation.
@@ -535,7 +548,11 @@ public class NSURL: NSObject, NSSecureCoding, NSCopying {
535548
/* Returns a file path URL that refers to the same resource as a specified URL. File path URLs use a file system style path. An error will occur if the url parameter is not a file URL. A file reference URL's resource must exist and be reachable to be converted to a file path URL. Symbol is present in iOS 4, but performs no operation.
536549
*/
537550
public var filePathURL: URL? {
538-
NSUnimplemented()
551+
guard isFileURL else {
552+
return nil
553+
}
554+
555+
return URL(string: absoluteString)
539556
}
540557

541558
override public var _cfTypeID: CFTypeID {
@@ -769,6 +786,38 @@ extension NSURL {
769786

770787
return URL(fileURLWithPath: resolvedPath)
771788
}
789+
790+
private func _pathByRemovingDots(_ comps: [String]) -> String {
791+
var components = comps
792+
793+
if(components.last == "/") {
794+
components.removeLast()
795+
}
796+
797+
guard !components.isEmpty else {
798+
return self.path!
799+
}
800+
801+
let isAbsolutePath = components.first == "/"
802+
var result : String = components.removeFirst()
803+
804+
for component in components {
805+
switch component {
806+
case ".":
807+
break
808+
case ".." where isAbsolutePath:
809+
result = result.bridge().stringByDeletingLastPathComponent
810+
default:
811+
result = result.bridge().stringByAppendingPathComponent(component)
812+
}
813+
}
814+
815+
if(self.path!.hasSuffix("/")) {
816+
result += "/"
817+
}
818+
819+
return result
820+
}
772821
}
773822

774823
// NSURLQueryItem encapsulates a single query name-value pair. The name and value strings of a query name-value pair are not percent encoded. For use with the NSURLComponents queryItems property.

TestFoundation/TestNSURL.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,12 @@ class TestNSURL : XCTestCase {
150150
result["parameterString"] = url.parameterString ?? kNullString
151151
result["relativePath"] = url.relativePath ?? kNullString
152152
result["isFileURL"] = url.isFileURL ? "YES" : "NO"
153-
// Not yet implemented
154-
// result["standardizedURL"] = url.standardizedURL?.relativeString ?? kNullString
155-
153+
do {
154+
let url = try url.standardized()
155+
result["standardizedURL"] = url.relativeString
156+
} catch {
157+
result["standardizedURL"] = kNullString
158+
}
156159
// Temporarily disabled because we're only checking string results
157160
// result["pathComponents"] = url.pathComponents ?? kNullString
158161
result["lastPathComponent"] = url.lastPathComponent ?? kNullString
@@ -223,14 +226,11 @@ class TestNSURL : XCTestCase {
223226
}
224227
if let url = url {
225228

226-
// TODO: NSURL.standardizedURL isn't implemented yet.
227-
var modifiedExpectedNSResult = expectedNSResult as! [String: Any]
228-
modifiedExpectedNSResult["standardizedURL"] = nil
229229
if title == "NSURLWithString-parse-ambiguous-url-001" {
230230
// TODO: Fix this test
231231
} else {
232232
let results = generateResults(url, pathComponent: inPathComponent, pathExtension: inPathExtension)
233-
let (isEqual, differences) = compareResults(url, expected: modifiedExpectedNSResult, got: results)
233+
let (isEqual, differences) = compareResults(url, expected: expectedNSResult as! [String: Any], got: results)
234234
XCTAssertTrue(isEqual, "\(title): \(differences)")
235235
}
236236
} else {

0 commit comments

Comments
 (0)