Swift 3: Display Image from URL

2019-01-17 03:13发布

In Swift 3, I am trying to capture an image from the internet, and have these lines of code:

var catPictureURL = NSURL(fileURLWithPath: "http://i.imgur.com/w5rkSIj.jpg")
var catPictureData = NSData(contentsOf: catPictureURL as URL) // nil
var catPicture = UIImage(data: catPictureData as! Data)

What am I doing wrong here?

标签: swift3
8条回答
我只想做你的唯一
2楼-- · 2019-01-17 03:54
let url = ("https://firebasestorage.googleapis.com/v0/b/qualityaudit-678a4.appspot.com/o/profile_images%2FBFA28EDD-9E15-4CC3-9AF8-496B91E74A11.png?alt=media&token=b4518b07-2147-48e5-93fb-3de2b768412d")


self.myactivityindecator.startAnimating()

let urlString = url
    guard let url = URL(string: urlString) else { return }
    URLSession.shared.dataTask(with: url)


{
(data, response, error) in
        if error != nil {
            print("Failed fetching image:", error!)
            return
        }

        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            print("error")
            return
        }

        DispatchQueue.main.async {
            let image = UIImage(data: data!)
        let myimageview = UIImageView(image: image)
            print(myimageview)
            self.imgdata.image = myimageview.image
self.myactivityindecator.stopanimating()

     }
  }.resume()
查看更多
forever°为你锁心
3楼-- · 2019-01-17 03:55

You could also use Alamofire\AlmofireImage for that task: https://github.com/Alamofire/AlamofireImage

The code should look something like that (Based on the first example on link above):

import AlamofireImage

Alamofire.request("http://i.imgur.com/w5rkSIj.jpg").responseImage { response in
    if let catPicture = response.result.value {
        print("image downloaded: \(image)")
    }
}

While it is neat yet safe, you should consider if that worth the Pod overhead. If you are going to use more images and would like to add also filter and transiations I would consider using AlamofireImage

查看更多
老娘就宠你
4楼-- · 2019-01-17 04:01

There's a few things with your code as it stands:

  1. You are using a lot of casting, which is not needed.
  2. You are treating your URL as a local file URL, which is not the case.
  3. You are never downloading the URL to be used by your image.

The first thing we are going to do is to declare your variable as let, as we are not going to modify it later.

let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")! // We can force unwrap because we are 100% certain the constructor will not return nil in this case.

Then we need to download the contents of that URL. We can do this with the URLSession object. When the completion handler is called, we will have a UIImage downloaded from the web.

// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)

// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
    // The download has finished.
    if let e = error {
        print("Error downloading cat picture: \(e)")
    } else {
        // No errors found.
        // It would be weird if we didn't have a response, so check for that too.
        if let res = response as? HTTPURLResponse {
            print("Downloaded cat picture with response code \(res.statusCode)")
            if let imageData = data {
                // Finally convert that Data into an image and do what you wish with it.
                let image = UIImage(data: imageData)
                // Do something with your image.
            } else {
                print("Couldn't get image: Image is nil")
            }
        } else {
            print("Couldn't get response code for some reason")
        }
    }
}

Finally you need to call resume on the download task, otherwise your task will never start:

downloadPicTask.resume().

All this code may look a bit intimidating at first, but the URLSession APIs are block based so they can work asynchronously - If you block your UI thread for a few seconds, the OS will kill your app.

Your full code should look like this:

let catPictureURL = URL(string: "http://i.imgur.com/w5rkSIj.jpg")!

// Creating a session object with the default configuration.
// You can read more about it here https://developer.apple.com/reference/foundation/urlsessionconfiguration
let session = URLSession(configuration: .default)

// Define a download task. The download task will download the contents of the URL as a Data object and then you can do what you wish with that data.
let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
    // The download has finished.
    if let e = error {
        print("Error downloading cat picture: \(e)")
    } else {
        // No errors found.
        // It would be weird if we didn't have a response, so check for that too.
        if let res = response as? HTTPURLResponse {
            print("Downloaded cat picture with response code \(res.statusCode)")
            if let imageData = data {
                // Finally convert that Data into an image and do what you wish with it.
                let image = UIImage(data: imageData)
                // Do something with your image.
            } else {
                print("Couldn't get image: Image is nil")
            }
        } else {
            print("Couldn't get response code for some reason")
        }
    }
}

downloadPicTask.resume()
查看更多
Rolldiameter
5楼-- · 2019-01-17 04:01

Using Alamofire worked out for me on Swift 3:

Step 1:

Integrate using pods.

pod 'Alamofire', '~> 4.4'

pod 'AlamofireImage', '~> 3.3'

Step 2:

import AlamofireImage

import Alamofire

Step 3:

Alamofire.request("https://httpbin.org/image/png").responseImage { response in

if let image = response.result.value {
    print("image downloaded: \(image)")
self.myImageview.image = image
}
}
查看更多
甜甜的少女心
6楼-- · 2019-01-17 04:01

The easiest way according to me will be using SDWebImage

Add this to your pod file

  pod 'SDWebImage', '~> 4.0'

Run pod install

Now import SDWebImage

      import SDWebImage

Now for setting image from url

    imageView.sd_setImage(with: URL(string: "http://www.domain/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))

It will show placeholder image but when image is downloaded it will show the image from url .Your app will never crash

This are the main feature of SDWebImage

Categories for UIImageView, UIButton, MKAnnotationView adding web image and cache management

An asynchronous image downloader

An asynchronous memory + disk image caching with automatic cache expiration handling

A background image decompression

A guarantee that the same URL won't be downloaded several times

A guarantee that bogus URLs won't be retried again and again

A guarantee that main thread will never be blocked Performances!

Use GCD and ARC

To know more https://github.com/rs/SDWebImage

查看更多
Luminary・发光体
7楼-- · 2019-01-17 04:04

Swift

Good solution to extend native functionality by extensions

import Foundation
import UIKit

extension UIImage {
    convenience init?(url: URL?) {
        guard let url = url else { return nil }

        do {
            let data = try Data(contentsOf: url)
            self.init(data: data)
        } catch {
            print("Cannot load image from url: \(url) with error: \(error)")
            return nil
        }
    }
}

Usage

Convenience initializer is failable and accepts optional URL – approach is safe.

imageView.image = UIImage(url: URL(string: "some_url.png"))
查看更多
登录 后发表回答