1

I'm writing a simple Twitter app for OS X and I'm currently stuck on downloading the user's profile image. This is the code responsible for downloading the image:

let imageRequest: NSURLRequest = NSURLRequest(URL: NSURL(string: avatarURL)!)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let dataTask = session.dataTaskWithRequest(imageRequest) {
    (data, response, error) in

    println(error)

    if data != nil {
        println("Got image")
        let image = NSImage(data: data!)
        completion(image)
    } else {
        println("Data is nil")
        completion(nil)
    }
}
dataTask!.resume()

avatarURL is a String containing this: https://pbs.twimg.com/profile_images/618168482086129664/C0E92y7G.png, which is the URL to my Twitter avatar. As you can see, it's a perfectly valid URL leading to a perfectly valid image.

But whenever I run my app, the println(error) line prints this into my console:

Optional(Error Domain=NSURLErrorDomain Code=-1002 "The operation couldn’t be completed. (NSURLErrorDomain error -1002.)" UserInfo=0x61000006ea80 {NSErrorFailingURLStringKey=Optional(https://pbs.twimg.com/profile_images/618168482086129664/C0E92y7G.png), NSUnderlyingError=0x600000243720 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1002.)", NSErrorFailingURLKey=Optional(https://pbs.twimg.com/profile_images/618168482086129664/C0E92y7G.png)})

Am I doing something wrong? I've already googled (what a word) this, and almost every single SO page I've found has a solution that basically amounts to "Your URL is missing an URL scheme/has an unsupported URL scheme", which is not the problem I'm having.

Peter W.
  • 2,323
  • 4
  • 22
  • 42
  • Hmm, this code works fine for me (other than curious reference to `println`, which isn't used in Swift 2 anymore). You might want to double check your URL, make sure there aren't any spaces or weird, non-visible characters. – Rob Jul 19 '15 at 23:01
  • Weird. I just typed the URL in manually to make sure I wasn't copying any invisible characters, still nothing. Also, `println` is a wrapper func I wrote that just calls `print` again, to make it work in `NSWindow` subclasses. – Peter W. Jul 19 '15 at 23:58
  • Actually, scratch that. I just cleared all of Xcode's caches and now it works when pasting the URL manually into the code. Normally, I'd get the URL from Twitter's API, and that is when it stops working and produces the error above. what – Peter W. Jul 20 '15 at 00:29
  • Turns out that the "Optional()" part of the string is /actually/ part of the string, not just an indication that the object itself is an Optional, hence why I'm getting an error that indicates that the URL is faulty. I have never seen this before. I think this is actually a bug in either Xcode or Swift itself. – Peter W. Jul 20 '15 at 00:45

1 Answers1

1

I finally figured out how to fix this. Before, I just lazily did this:

var avatarURLString = String(responseObject["profile_image_url_https"])

which apparently returns an Optional that can't be unwrapped with an exclamation mark. Yes, I don't know either. It's just what happened.

Now, I do this:

var avatarURLString = responseObject["profile_image_url_https"] as! String

...which actually yields a proper String object instead of some weird not-quite-Optional. Hooray for using beta versions of programming languages.

Peter W.
  • 2,323
  • 4
  • 22
  • 42
  • It's not that it's a "not-quite-Optional" but rather that it is a non-optional that consists of the string `Optional(` at the start and `)` at the end. Look at the string length and you'll see that `Optional(` and `)` are actually part of the string! It's because it's performed string interpolation on an optional. If you used `String(responseObject["profile_image_url_https"]!)` (to unwrap the optional returned by the subscript function _before_ passing it to the `String` constructor, that would prevent that from happening. Or just do the simple cast, as you showed in your answer above. – Rob Jul 20 '15 at 02:20
  • Unwrapping the object inside of the String constructor did nothing. – Peter W. Jul 20 '15 at 03:09
  • OK. It worked for me, so there must be something else going on. Nevertheless, you have another solution, so that's good. – Rob Jul 20 '15 at 03:18