NSURL getResourceValue in swift

2019-03-24 16:51发布

问题:

Having trouble figuring out how to make the following call in swift:

var anyError: NSError? = nil
var rsrc: NSNumber? = nil
var success = url.getResourceValue(&rsrc, forKey:NSURLIsUbiquitousItemKey, error:&anyError)

The above does not compile:

Cannot convert the expression's type 'Bool' to type 'inout Bool'

So I tried this:

var anyError: NSError? = nil
var rsrc: AutoreleasingUnsafePointer<AnyObject?> = nil
var success = url.getResourceValue(rsrc, forKey:NSURLIsUbiquitousItemKey, error:&anyError)

but this generates EXC_BAD_ACCESS runtime error.

How do I pass in the expected first arg as AutoreleasingUnsafePointer<AnyObject?> (which should point to a boolean NSNumber according to doc), and then be able to check its expected Bool value ?

回答1:

You need to make rsrc an optional AnyObject and pass it by reference like so:

var anyError: NSError?
var rsrc: AnyObject?
var success = url.getResourceValue(&rsrc, forKey:NSURLIsUbiquitousItemKey, error:&anyError)

Note: You do not need to initialize Optionals to nil, they are set to nil by default.

If you then want to check if the value is an NSNumber you can then do a conversion:

if let number = rsrc as? NSNumber {
    // use number
}


回答2:

Here is drewag's code updated for Swift 2.0

    do {
        var rsrc: AnyObject?
        try element.getResourceValue(&rsrc, forKey: NSURLIsDirectoryKey)
        if let number = rsrc as? NSNumber {
            if number == true {
                // do something
            }
        }
    } catch {
    }


回答3:

in swift 3 previous calls are not available/deprecated:

so use:

var keys = Set<URLResourceKey>()
keys.insert(URLResourceKey.isDirectoryKey)
do{
    let URLResourceValues = try fileURL.resourceValues(forKeys: keys)
    }catch _{

   }


回答4:

If the getResourceValue(:forKey:) result is ultimately a logical value, you can cast the returned pointer value directly to a Bool value:

let boolResult = rsrc as! Bool

or simply test it as a Bool value without assigning it:

if rsrc as! Bool {
    // true code
} else {
    // false code
}

or do both:

if let rsrc as! Bool {
    // true
} else {
    // false
}


回答5:

Here's a concrete example as an extension of the URL type:

extension URL {
    var creationDate : Date {
        let url = self as NSURL
        var value : AnyObject?
        try? url.getResourceValue(&value, forKey: .creationDateKey)
        if let date = value as? Date {
            return date
        }
        return .distantPast
    }
}

For convenience, if the call to getResourceValue() fails, it returns the value .distantPast by default. Using the try? form allows discarding the error which isn't always needed.



标签: url swift