I am trying to load a file from my app bundle in Swift 3, and I came across a weird situation with the Swift type inferencing. If I use the following code, I get an error on the third line that says Value of optional type "String?" not unwrapped
Value of optional type "String?" not unwrapped
.
let url = NSURL(fileURLWithPath:Bundle.main.bundlePath)
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2?.path
To fix the error I unwrap the value on the third line by changing it to:
let path:String = url2?.path!
I now get the error Cannot force unwrap value of a non-optional type 'String'
. It seems like Swift can't determine whether the path property is a String
or a String?
. The autocomplete feature in Xcode says it is a String
, but the docs say it is a String?
.
The suggested fix by Xcode for the first error was to replace url2?.path
with (url2?.path)!
, which finally ended up working, but I have no idea why this works and the other ways don't.
let path:String = (url2?.path)!
What is going on? Is this a type inference bug in Swift, or am I missing something super obvious
In Swift, Optional chaining like:
let path:String = url2?.path!
... is interpreted as:
let path:String = url2 != nil ? url2!.path!
: nil
As you see the type of path
is non-Optional String
, so the expression causes error.
( url2
's type is URL?
, so the type of property path
is String
, not String?
.)
This is not a direct answer to your question, but I would re-write your code as:
let url = Bundle.main.bundleURL
let url2 = url.appendingPathComponent("foo.txt")
let path:String = url2.path
Shorter, and no worry about Optionals.
You forgot to unwrap url2
appendingPathComponent
returns an optional value and you are trying to access it without unwrapping it.
So,
let url2 = url.appendingPathComponent("foo.txt")!
or
guard let url2 = url.appendingPathComponent("foo.txt") else { }
should fix it
EDIT
let path:String? = url2?.path
works also
You can also do this:
let url = Bundle.main.url(forResource: "foo", withExtension: "txt")!
let path:String = url.path
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.