Ahad Sheriff
Ahad Sheriff

Reputation: 1829

Explicitly specified type 'NSURL?' issue while updating to Swift 3

I am having issues while updating my iOS app's code to the latest version of Swift.

I have a function:

public class func gifWithURL(gifUrl:String) -> UIImage? {
    // Validate URL
    guard let bundleURL:NSURL? = NSURL(string: gifUrl)
        else {
            print("SwiftGif: This image named \"\(gifUrl)\" does not exist")
            return nil
    }

    // Validate data
    guard let imageData = NSData(contentsOf: bundleURL! as URL) else {
        print("SwiftGif: Cannot turn image named \"\(gifUrl)\" into NSData")
        return nil
    }

    return gifWithData(data: imageData)
}

And am getting a warning on the following line:

guard let bundleURL:NSURL? = NSURL(string: gifUrl)

and am getting the warning:

Explicitly specified type 'NSURL?' adds an additional level of optional to the initializer, making the optional check always succeed

Xcode allows me to fix the problem automatically. When I do this auto-fix, my code changes to:

guard let bundleURL:NSURL NSURL(string: gifUrl)

Which is obviously not the correct syntax.

I am unsure what I need to add/remove to get my code fully up to date with Swift 3 standards and working.

Upvotes: 0

Views: 685

Answers (2)

Nirav D
Nirav D

Reputation: 72410

NSURL(string:) will return optional NSURL? instance and you are already optionally wrapping it with guard so remove the : NSURL? because you are setting it again optional instead of non-optional also, in Swift 3 use native URL and Data instead of NSURL and NSData. The whole code would be like.

guard let bundleURL = URL(string: gifUrl), let imageData = try? Data(contentsOf: bundleURL) else {
     print("SwiftGif: This image named \"\(gifUrl)\" does not exist")
     return nil
}
//Access the imageData here

Note: Data(contentsOf:) will throws exception so you need to catch it using do try catch block.

Upvotes: 2

FelixSFD
FelixSFD

Reputation: 6092

You are doing it too complicated. In Swift 3, we don't use NSURL. It's just URL:

guard let bundleURL = URL(string: gifUrl) else {
    print("SwiftGif: This image named \"\(gifUrl)\" does not exist")
    return nil
}

Then you can also get rid of your dangerous force-cast:

guard let imageData = NSData(contentsOf: bundleURL) else {
    print("SwiftGif: Cannot turn image named \"\(gifUrl)\" into NSData")
    return nil
}

Upvotes: 1

Related Questions