Skip to content

[NSURL] Implementation of '.checkResourceIsReachable' #904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Docs/Status.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ There is no _Complete_ status for test coverage because there are always additio
| `NSMutableURLRequest` | Mostly Complete | Incomplete | |
| `URLResponse` | Mostly Complete | Incomplete | |
| `NSHTTPURLResponse` | Mostly Complete | Substantial | |
| `NSURL` | Mostly Complete | Substantial | `checkResourceIsReachable()`, and resource values remain unimplemented |
| `NSURL` | Mostly Complete | Substantial | Resource values remain unimplemented |
| `NSURLQueryItem` | Mostly Complete | N/A | |
| `URLResourceKey` | Complete | N/A | |
| `URLFileResourceType` | Complete | N/A | |
Expand Down
20 changes: 19 additions & 1 deletion Foundation/NSURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -610,8 +610,26 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
*/
/// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
/// - Note: Since this API is under consideration it may be either removed or revised in the near future
// TODO: should be `checkResourceIsReachableAndReturnError` with autoreleased error parameter.
// Currently Autoreleased pointers is not supported on Linux.
open func checkResourceIsReachable() throws -> Bool {
NSUnimplemented()
guard isFileURL,
let path = path else {
throw NSError(domain: NSCocoaErrorDomain,
code: CocoaError.Code.fileNoSuchFile.rawValue)
//return false
}

guard FileManager.default.fileExists(atPath: path) else {
throw NSError(domain: NSCocoaErrorDomain,
code: CocoaError.Code.fileReadNoSuchFile.rawValue,
userInfo: [
"NSURL" : self,
"NSFilePath" : path])
//return false
}

return true
}

/* 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.
Expand Down
7 changes: 7 additions & 0 deletions Foundation/URL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,13 @@ public struct URL : ReferenceConvertible, Equatable {
_url.removeCachedResourceValue(forKey: key)
}

/// 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. This method is currently applicable only to URLs for file system resources. For other URL types, `false` is returned.
public func checkResourceIsReachable() throws -> Bool {
return try _url.checkResourceIsReachable()
}

// MARK: - Bridging Support

/// 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.
Expand Down
53 changes: 53 additions & 0 deletions TestFoundation/TestNSURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class TestNSURL : XCTestCase {
("test_fileURLWithPath", test_fileURLWithPath),
("test_fileURLWithPath_isDirectory", test_fileURLWithPath_isDirectory),
("test_URLByResolvingSymlinksInPath", test_URLByResolvingSymlinksInPath),
("test_reachable", test_reachable),
("test_copy", test_copy),
("test_itemNSCoding", test_itemNSCoding),
]
Expand Down Expand Up @@ -422,6 +423,58 @@ class TestNSURL : XCTestCase {
XCTAssertEqual(result, "file:///tmp/")
}
}

func test_reachable() {
var url = URL(fileURLWithPath: "/usr")
XCTAssertEqual(true, try? url.checkResourceIsReachable())

url = URL(string: "https://www.swift.org")!
do {
_ = try url.checkResourceIsReachable()
XCTFail()
} catch let error as NSError {
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
XCTAssertEqual(CocoaError.Code.fileNoSuchFile.rawValue, error.code)
} catch {
XCTFail()
}

url = URL(fileURLWithPath: "/some_random_path")
do {
_ = try url.checkResourceIsReachable()
XCTFail()
} catch let error as NSError {
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
XCTAssertEqual(CocoaError.Code.fileReadNoSuchFile.rawValue, error.code)
} catch {
XCTFail()
}

var nsURL = NSURL(fileURLWithPath: "/usr")
XCTAssertEqual(true, try? nsURL.checkResourceIsReachable())

nsURL = NSURL(string: "https://www.swift.org")!
do {
_ = try nsURL.checkResourceIsReachable()
XCTFail()
} catch let error as NSError {
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
XCTAssertEqual(CocoaError.Code.fileNoSuchFile.rawValue, error.code)
} catch {
XCTFail()
}

nsURL = NSURL(fileURLWithPath: "/some_random_path")
do {
_ = try nsURL.checkResourceIsReachable()
XCTFail()
} catch let error as NSError {
XCTAssertEqual(NSCocoaErrorDomain, error.domain)
XCTAssertEqual(CocoaError.Code.fileReadNoSuchFile.rawValue, error.code)
} catch {
XCTFail()
}
}

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