Skip to content

Commit fcc4292

Browse files
committed
implementation for NSURL.standardizedURL and NSURL.filePathURL properties
change _standardizedURLPath to private function
1 parent e74f745 commit fcc4292

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+
internal 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
@@ -149,9 +149,12 @@ class TestNSURL : XCTestCase {
149149
result["parameterString"] = url.parameterString ?? kNullString
150150
result["relativePath"] = url.relativePath ?? kNullString
151151
result["isFileURL"] = url.isFileURL ? "YES" : "NO"
152-
// Not yet implemented
153-
// result["standardizedURL"] = url.standardizedURL?.relativeString ?? kNullString
154-
152+
do {
153+
let url = try url.standardized()
154+
result["standardizedURL"] = url.relativeString
155+
} catch {
156+
result["standardizedURL"] = kNullString
157+
}
155158
// Temporarily disabled because we're only checking string results
156159
// result["pathComponents"] = url.pathComponents ?? kNullString
157160
result["lastPathComponent"] = url.lastPathComponent ?? kNullString
@@ -222,14 +225,11 @@ class TestNSURL : XCTestCase {
222225
}
223226
if let url = url {
224227

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

0 commit comments

Comments
 (0)