Skip to content

Commit 3c737c9

Browse files
authored
Merge pull request #904 from naithar/nsurl-checkReachable
2 parents 3ef626d + d66717d commit 3c737c9

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

Docs/Status.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ There is no _Complete_ status for test coverage because there are always additio
5757
| `NSMutableURLRequest` | Mostly Complete | Incomplete | |
5858
| `URLResponse` | Mostly Complete | Incomplete | |
5959
| `NSHTTPURLResponse` | Mostly Complete | Substantial | |
60-
| `NSURL` | Mostly Complete | Substantial | `checkResourceIsReachable()`, and resource values remain unimplemented |
60+
| `NSURL` | Mostly Complete | Substantial | Resource values remain unimplemented |
6161
| `NSURLQueryItem` | Mostly Complete | N/A | |
6262
| `URLResourceKey` | Complete | N/A | |
6363
| `URLFileResourceType` | Complete | N/A | |

Foundation/NSURL.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,26 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
610610
*/
611611
/// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
612612
/// - Note: Since this API is under consideration it may be either removed or revised in the near future
613+
// TODO: should be `checkResourceIsReachableAndReturnError` with autoreleased error parameter.
614+
// Currently Autoreleased pointers is not supported on Linux.
613615
open func checkResourceIsReachable() throws -> Bool {
614-
NSUnimplemented()
616+
guard isFileURL,
617+
let path = path else {
618+
throw NSError(domain: NSCocoaErrorDomain,
619+
code: CocoaError.Code.fileNoSuchFile.rawValue)
620+
//return false
621+
}
622+
623+
guard FileManager.default.fileExists(atPath: path) else {
624+
throw NSError(domain: NSCocoaErrorDomain,
625+
code: CocoaError.Code.fileReadNoSuchFile.rawValue,
626+
userInfo: [
627+
"NSURL" : self,
628+
"NSFilePath" : path])
629+
//return false
630+
}
631+
632+
return true
615633
}
616634

617635
/* 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.

Foundation/URL.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,13 @@ public struct URL : ReferenceConvertible, Equatable {
927927
_url.removeCachedResourceValue(forKey: key)
928928
}
929929

930+
/// Returns whether the URL's resource exists and is reachable.
931+
///
932+
/// 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. This method is currently applicable only to URLs for file system resources. For other URL types, `false` is returned.
933+
public func checkResourceIsReachable() throws -> Bool {
934+
return try _url.checkResourceIsReachable()
935+
}
936+
930937
// MARK: - Bridging Support
931938

932939
/// We must not store an NSURL without running it through this function. This makes sure that we do not hold a file reference URL, which changes the nullability of many NSURL functions.

TestFoundation/TestNSURL.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class TestNSURL : XCTestCase {
6161
("test_fileURLWithPath", test_fileURLWithPath),
6262
("test_fileURLWithPath_isDirectory", test_fileURLWithPath_isDirectory),
6363
("test_URLByResolvingSymlinksInPath", test_URLByResolvingSymlinksInPath),
64+
("test_reachable", test_reachable),
6465
("test_copy", test_copy),
6566
("test_itemNSCoding", test_itemNSCoding),
6667
]
@@ -422,6 +423,58 @@ class TestNSURL : XCTestCase {
422423
XCTAssertEqual(result, "file:///tmp/")
423424
}
424425
}
426+
427+
func test_reachable() {
428+
var url = URL(fileURLWithPath: "/usr")
429+
XCTAssertEqual(true, try? url.checkResourceIsReachable())
430+
431+
url = URL(string: "https://www.swift.org")!
432+
do {
433+
_ = try url.checkResourceIsReachable()
434+
XCTFail()
435+
} catch let error as NSError {
436+
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
437+
XCTAssertEqual(CocoaError.Code.fileNoSuchFile.rawValue, error.code)
438+
} catch {
439+
XCTFail()
440+
}
441+
442+
url = URL(fileURLWithPath: "/some_random_path")
443+
do {
444+
_ = try url.checkResourceIsReachable()
445+
XCTFail()
446+
} catch let error as NSError {
447+
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
448+
XCTAssertEqual(CocoaError.Code.fileReadNoSuchFile.rawValue, error.code)
449+
} catch {
450+
XCTFail()
451+
}
452+
453+
var nsURL = NSURL(fileURLWithPath: "/usr")
454+
XCTAssertEqual(true, try? nsURL.checkResourceIsReachable())
455+
456+
nsURL = NSURL(string: "https://www.swift.org")!
457+
do {
458+
_ = try nsURL.checkResourceIsReachable()
459+
XCTFail()
460+
} catch let error as NSError {
461+
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
462+
XCTAssertEqual(CocoaError.Code.fileNoSuchFile.rawValue, error.code)
463+
} catch {
464+
XCTFail()
465+
}
466+
467+
nsURL = NSURL(fileURLWithPath: "/some_random_path")
468+
do {
469+
_ = try nsURL.checkResourceIsReachable()
470+
XCTFail()
471+
} catch let error as NSError {
472+
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
473+
XCTAssertEqual(CocoaError.Code.fileReadNoSuchFile.rawValue, error.code)
474+
} catch {
475+
XCTFail()
476+
}
477+
}
425478

426479
func test_copy() {
427480
let url = NSURL(string: "https://www.swift.org")

0 commit comments

Comments
 (0)