6

I found several similar questions on StackOverflow but none of them solve my problem.

I am trying to get a image from a url. Here's how I do it:

let url = NSURL(string: "http://pic3.zhimg.com/8161ba9638273e0fb1a0201789d22d8e_m.jpg")
let data = NSData(contentsOfURL: url!)
let image = UIImage(data: data!)

But I got an error telling me that data is nil.

How can I solve this? Thanks.

UPDATE

Here's some screenshots of the error:

enter image description here enter image description here

hklel
  • 1,624
  • 23
  • 45
  • 1
    Your code is perfectly working fine. I think you are getting nil data because of some network issue/restrictions. I checked the same code in my playground and I'm getting the result. – Midhun MP Sep 14 '15 at 14:48
  • @MidhunMP I tried it in playground and it worked. But when I run it in `viewDidLoad` of a newly created project I got the same error – hklel Sep 14 '15 at 14:52
  • Try with `NSData(contentsOfURL:option:error)`. You may get the error. Could this be related to absence of "https" with iOS9 (and the App Transport Security to set)? – Larme Sep 14 '15 at 15:21
  • @Larme Oh yeah! I forgot to add this domain to the info.plist file. Thanks! :) – hklel Sep 14 '15 at 15:28
  • 5
    seriously...?! do you really want to use a synchronous request on the main thread for fetching an image from external resource? why people never read the docs?! _"Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated."_ ([source](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/#//apple_ref/occ/clm/NSData/dataWithContentsOfURL:)) – holex Sep 14 '15 at 15:30
  • 1
    @holex I totally forgot about that lol ... you are the real MVP – Lamour Sep 14 '15 at 15:32
  • @holex thanks for reminding. I will check it out – hklel Sep 14 '15 at 15:33

2 Answers2

15

This is probably a result of Apple's new app transport security denying a non-HTTPS request. To work around this you need to modify your app's Info.plist file. You can either define an exception for that particular domain

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>pic3.zhimg.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

or disable ATS altogether

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
hennes
  • 9,147
  • 4
  • 43
  • 63
3

I think you should, before all, create a resilient code.

if let url = NSURL(string: "http://pic3.zhimg.com/8161ba9638273e0fb1a0201789d22d8e_m.jpg")
{ 
    if let data = NSData(contentsOfURL: url) 
    {
        if let image = UIImage(data: data) 
        {
            //Do something
        }
    }
}
dede.exe
  • 1,300
  • 1
  • 16
  • 27