programing

Swift의 URL에서 이미지 로드/다운로드

starjava 2023. 5. 22. 20:06
반응형

Swift의 URL에서 이미지 로드/다운로드

애플리케이션의 URL에서 이미지를 로드하고 싶어서 처음에 Objective-C로 시도했지만 Swift에서는 컴파일 오류가 발생했습니다.

'imageWithData'를 사용할 수 없습니다. 개체 구성 'UIImage(data:)'를 사용하십시오.

내 기능:

@IBOutlet var imageView : UIImageView

override func viewDidLoad() {
    super.viewDidLoad()

    var url:NSURL = NSURL.URLWithString("http://myURL/ios8.png")
    var data:NSData = NSData.dataWithContentsOfURL(url, options: nil, error: nil)

    imageView.image = UIImage.imageWithData(data)// Error here
}

목표 C:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL *url = [NSURL URLWithString:(@"http://myURL/ios8.png")];
    NSData *data = [NSData dataWithContentsOfURL:url];

    _imageView.image = [UIImage imageWithData: data];
    _labelURL.text = @"http://www.quentinroussat.fr/assets/img/iOS%20icon's%20Style/ios8.png";
 }

누가 왜 그런지 설명해 주시겠습니까?imageWithData:Swift와 함께 작동하지 않습니다. 그리고 어떻게 하면 문제를 해결할 수 있을까요?

Xcode 8 이상 • Swift 3 이상

동기화:

if let filePath = Bundle.main.path(forResource: "imageName", ofType: "jpg"), let image = UIImage(contentsOfFile: filePath) {
    imageView.contentMode = .scaleAspectFit
    imageView.image = image
}

비동기식:

완료 핸들러로 메소드를 만들어 URL에서 이미지 데이터 가져오기

func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

이미지 다운로드 방법 만들기(작업 시작)

func downloadImage(from url: URL) {
    print("Download Started")
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else { return }
        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        // always update the UI from the main thread
        DispatchQueue.main.async() { [weak self] in
            self?.imageView.image = UIImage(data: data)
        }
    }
}

용도:

override func viewDidLoad() {
    super.viewDidLoad()
    print("Begin of code")
    let url = URL(string: "https://cdn.arstechnica.net/wp-content/uploads/2018/06/macOS-Mojave-Dynamic-Wallpaper-transition.jpg")! 
    downloadImage(from: url)
    print("End of code. The image will continue downloading in the background and it will be loaded when it ends.")
}

확장:

extension UIImageView {
    func downloaded(from url: URL, contentMode mode: ContentMode = .scaleAspectFit) {
        contentMode = mode
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard
                let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                let data = data, error == nil,
                let image = UIImage(data: data)
                else { return }
            DispatchQueue.main.async() { [weak self] in
                self?.image = image
            }
        }.resume()
    }
    func downloaded(from link: String, contentMode mode: ContentMode = .scaleAspectFit) { 
        guard let url = URL(string: link) else { return }
        downloaded(from: url, contentMode: mode)
    }
}

용도:

imageView.downloaded(from: "https://cdn.arstechnica.net/wp-content/uploads/2018/06/macOS-Mojave-Dynamic-Wallpaper-transition.jpg")

(Swift 4 업데이트)원래 질문에 직접 답변하기 위해 게시된 목표-C 스니펫에 해당하는 신속한 내용이 있습니다.

let url = URL(string: image.url)
let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
imageView.image = UIImage(data: data!)

고지 사항:

중요한 것은 다음과 같습니다.Data(contentsOf:)메소드는 코드가 실행되는 동일한 스레드에서 URL의 내용을 동기적으로 다운로드하므로 응용 프로그램의 메인 스레드에서 이를 호출하지 마십시오.

UI를 차단하지 않고 동일한 코드를 비동기식으로 실행할 수 있는 쉬운 방법은 GCD를 사용하는 것입니다.

let url = URL(string: image.url)

DispatchQueue.global().async {
    let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
    DispatchQueue.main.async {
        imageView.image = UIImage(data: data!)
    }
}

즉, 실제 애플리케이션에서 최상의 사용자 환경을 유지하고 동일한 이미지를 여러 번 다운로드하지 않으려면 다운로드뿐만 아니라 캐시도 사용할 수 있습니다.이를 완벽하게 수행하는 도서관은 이미 꽤 있으며 모두 사용하기 쉽습니다.저는 개인적으로 킹피셔를 추천합니다.

import Kingfisher

let url = URL(string: "url_of_your_image")
// this downloads the image asynchronously if it's not cached yet
imageView.kf.setImage(with: url) 

그리고 이것이 마지막입니다.

이미지를 로드하려면(비동기적으로!) 이 작은 확장자를 빠른 코드에 추가하면 됩니다.

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
                (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
                if let imageData = data as NSData? {
                    self.image = UIImage(data: imageData)
                }
            }
        }
    }
}

다음과 같이 사용합니다.

myImageView.imageFromUrl("https://robohash.org/123.png")

Xcode 12Swift 5

레오 다부스의 대답은 정말 멋집니다!저는 단지 올인원 기능 솔루션을 제공하고 싶었습니다.

if let url = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else { return }
        
        DispatchQueue.main.async { /// execute on main thread
            self.imageView.image = UIImage(data: data)
        }
    }
    
    task.resume()
}

Swift 2.2 || Xcode 7.3

놀라운 결과를 얻었습니다!!Alamofire를 사용한 이미지 스위프트 라이브러리

다음과 같은 여러 기능을 제공합니다.

  • 비동기식으로다운로드.
  • 앱에 대해 메모리 경고가 발생하는 경우 이미지 캐시 자동 삭제
  • 이미지 URL 캐싱
  • 이미지 캐싱
  • 중복 다운로드 방지

애플리케이션에 대해 구현하기 매우 쉽습니다.

단계.1 포드 설치


알라모파이어 3.3.x

포드 '알라모파이어'

Alamofire 이미지 2.4.x

포드 'AlamofireImage'

2단계 가져오기 및 사용

import Alamofire
import AlamofireImage

let downloadURL = NSURL(string: "http://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/6.jpg?v=f4b7c5fee820")!
imageView.af_setImageWithURL(downloadURL)

바로 그거야!!그것은 모든 것을 돌볼 것입니다.


알라모파이어 여러분, iDevelopers의 삶을 편하게 해주셔서 감사합니다;)

스위프트 4:

이미지를 로드하는 동안 로더가 표시됩니다.이미지를 임시로 저장하는 NSCache를 사용할 수 있습니다.

let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
    func loadImageUsingCache(withUrl urlString : String) {
        let url = URL(string: urlString)
        if url == nil {return}
        self.image = nil

        // check cached image
        if let cachedImage = imageCache.object(forKey: urlString as NSString)  {
            self.image = cachedImage
            return
        }

        let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: .gray)
        addSubview(activityIndicator)
        activityIndicator.startAnimating()
        activityIndicator.center = self.center

        // if not, download image from url
        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                if let image = UIImage(data: data!) {
                    imageCache.setObject(image, forKey: urlString as NSString)
                    self.image = image
                    activityIndicator.removeFromSuperview()
                }
            }

        }).resume()
    }
}

용도:-

truckImageView.loadImageUsingCache(withUrl: currentTruck.logoString)

swift 3(오류 처리 포함)

let url = URL(string: arr[indexPath.row] as! String)
if url != nil {
    DispatchQueue.global().async {
        let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
        DispatchQueue.main.async {
            if data != nil {
                cell.imgView.image = UIImage(data:data!)
            }else{
                cell.imgView.image = UIImage(named: "default.png")
            }
        }
    }
}

확장 포함

extension UIImageView {

    func setCustomImage(_ imgURLString: String?) {
        guard let imageURLString = imgURLString else {
            self.image = UIImage(named: "default.png")
            return
        }
        DispatchQueue.global().async { [weak self] in
            let data = try? Data(contentsOf: URL(string: imageURLString)!)
            DispatchQueue.main.async {
                self?.image = data != nil ? UIImage(data: data!) : UIImage(named: "default.png")
            }
        }
    }
}

확장 사용

myImageView. setCustomImage("url")

캐시 지원 포함

let imageCache = NSCache<NSString, UIImage>()

extension UIImageView {

    func loadImageUsingCacheWithURLString(_ URLString: String, placeHolder: UIImage?) {

        self.image = nil
        if let cachedImage = imageCache.object(forKey: NSString(string: URLString)) {
            self.image = cachedImage
            return
        }

        if let url = URL(string: URLString) {
            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

                //print("RESPONSE FROM API: \(response)")
                if error != nil {
                    print("ERROR LOADING IMAGES FROM URL: \(String(describing: error))")
                    DispatchQueue.main.async { [weak self] in
                        self?.image = placeHolder
                    }
                    return
                }
                DispatchQueue.main.async { [weak self] in
                    if let data = data {
                        if let downloadedImage = UIImage(data: data) {
                            imageCache.setObject(downloadedImage, forKey: NSString(string: URLString))
                            self?.image = downloadedImage
                        }
                    }
                }
            }).resume()
        }
    }
}

질문에 대한 최상의 답변 코드를 UIImageView를 확장하는 재사용 가능한 단일 클래스로 포장하여 스토리보드에서 비동기 로드 UIImageView를 직접 사용할 수 있도록 했습니다(또는 코드에서 생성).

제 수업은 다음과 같습니다.

import Foundation
import UIKit

class UIImageViewAsync :UIImageView
{

    override init()
    {
        super.init(frame: CGRect())
    }

    override init(frame:CGRect)
    {
        super.init(frame:frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) {
        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in
            completion(data: NSData(data: data))
        }.resume()
    }

    func downloadImage(url:String){
        getDataFromUrl(url) { data in
            dispatch_async(dispatch_get_main_queue()) {
                self.contentMode = UIViewContentMode.ScaleAspectFill
                self.image = UIImage(data: data!)
            }
        }
    }
}

사용 방법은 다음과 같습니다.

imageView.downloadImage("http://www.image-server.com/myImage.jpg")
let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData)

참고로 swift-2.0 Xcode7.0 베타2용입니다.

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
            (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
                self.image = UIImage(data: data!)
            }
        }
    }
}

Swift 4: NSCache를 사용하고 항상 메인 스레드에서 실행되는 작은 이미지(예: 썸네일)용 단순 로더:

class ImageLoader {

  private static let cache = NSCache<NSString, NSData>()

  class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {

      if let data = self.cache.object(forKey: url.absoluteString as NSString) {
        DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
        return
      }

      guard let data = NSData(contentsOf: url) else {
        DispatchQueue.main.async { completionHandler(nil) }
        return
      }

      self.cache.setObject(data, forKey: url.absoluteString as NSString)
      DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
    }
  }

}

용도:

ImageLoader.image(for: imageURL) { image in
  self.imageView.image = image
}

swift 5

extension UIImageView {
    func load(url: URL) {
        DispatchQueue.global().async { [weak self] in
            if let data = try? Data(contentsOf: url) {
                if let image = UIImage(data: data) {
                    DispatchQueue.main.async {
                        self?.image = image
                    }
                }
            }
        }
    }
}

사용하기 위한

override func awakeFromNib() {
    super.awakeFromNib()
   if let url = URL(string:"<imageURLHere>"){
     imgView.load(url: url)
   }
}

다음을 수행할 수 있습니다.

UIImage(data: data)

스위프트에서 그들은 대부분의 오브젝티브 C 공장 방식을 일반 생성자로 대체했습니다.

참조:

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html #//apple_ref/doc/uid/TP40014216-CH4-XID_26

Swift 2 오류 처리 및 사용자 지정 요청 헤더

UIImageView에 확장 기능을 추가하기만 하면 됩니다.

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSMutableURLRequest(URL: url)
            request.setValue("<YOUR_HEADER_VALUE>", forHTTPHeaderField: "<YOUR_HEADER_KEY>")
            NSURLSession.sharedSession().dataTaskWithRequest(request) {
                (data, response, error) in
                guard let data = data where error == nil else{
                    NSLog("Image download error: \(error)")
                    return
                }

                if let httpResponse = response as? NSHTTPURLResponse{
                    if httpResponse.statusCode > 400 {
                        let errorMsg = NSString(data: data, encoding: NSUTF8StringEncoding)
                        NSLog("Image download error, statusCode: \(httpResponse.statusCode), error: \(errorMsg!)")
                        return
                    }
                }

            dispatch_async(dispatch_get_main_queue(), {
                NSLog("Image download success")
                self.image = UIImage(data: data)
            })
            }.resume()
        }
    }
}

그런 다음 새로운 기능을 사용합니다.imageFromUrl(urlString: String)

용도:

imageView.imageFromUrl("https://i.imgur.com/ONaprQV.png")

스위프트 4

이 방법은 웹 사이트에서 비동기식으로 이미지를 다운로드하여 캐시합니다.

    func getImageFromWeb(_ urlString: String, closure: @escaping (UIImage?) -> ()) {
        guard let url = URL(string: urlString) else {
return closure(nil)
        }
        let task = URLSession(configuration: .default).dataTask(with: url) { (data, response, error) in
            guard error == nil else {
                print("error: \(String(describing: error))")
                return closure(nil)
            }
            guard response != nil else {
                print("no response")
                return closure(nil)
            }
            guard data != nil else {
                print("no data")
                return closure(nil)
            }
            DispatchQueue.main.async {
                closure(UIImage(data: data!))
            }
        }; task.resume()
    }

사용 중:

    getImageFromWeb("http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") { (image) in
        if let image = image {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
            imageView.image = image
            self.view.addSubview(imageView)
        } // if you use an Else statement, it will be in background
    }

Kingfisher는 URL에 이미지를 로드하는 데 가장 적합한 라이브러리 중 하나입니다.

Github URL - https://github.com/onevcat/Kingfisher

// If you want to use Activity Indicator.
imageview_pic.kf.indicatorType = .activity
imageview_pic.kf.setImage(with: URL(string: "Give your url string"))

// If you want to use custom placeholder image.
imageview_pic.kf.setImage(with: URL(string: "Give your url string"), placeholder: UIImage(named: "placeholder image name"), options: nil, progressBlock: nil, completionHandler: nil)

URL에서 이미지를 로드/다운로드하기 위한 작업 코드입니다.다운로드 및 실제 이미지 로드(Swift 4 | Swift 5 코드) 전에 자동으로 NSCache 및 Placeholder 이미지를 표시합니다.

func NKPlaceholderImage(image:UIImage?, imageView:UIImageView?,imgUrl:String,compate:@escaping (UIImage?) -> Void){
    
    if image != nil && imageView != nil {
        imageView!.image = image!
    }
    
    var urlcatch = imgUrl.replacingOccurrences(of: "/", with: "#")
    let documentpath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    urlcatch = documentpath + "/" + "\(urlcatch)"
    
    let image = UIImage(contentsOfFile:urlcatch)
    if image != nil && imageView != nil
    {
        imageView!.image = image!
        compate(image)
        
    }else{
        
        if let url = URL(string: imgUrl){
            
            DispatchQueue.global(qos: .background).async {
                () -> Void in
                let imgdata = NSData(contentsOf: url)
                DispatchQueue.main.async {
                    () -> Void in
                    imgdata?.write(toFile: urlcatch, atomically: true)
                    let image = UIImage(contentsOfFile:urlcatch)
                    compate(image)
                    if image != nil  {
                        if imageView != nil  {
                            imageView!.image = image!
                        }
                    }
                }
            }
        }
    }
}

다음과 같이 사용:

// Here imgPicture = your imageView
// UIImage(named: "placeholder") is Display image brfore download and load actual image. 

NKPlaceholderImage(image: UIImage(named: "placeholder"), imageView: imgPicture, imgUrl: "Put Here your server image Url Sting") { (image) in }

URL에서 이미지를 빠르게 확인하고 싶다면 빠른 해킹.

 let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")
 let imagedData = NSData(contentsOfURL: imageURL!)!
 imageView?.image = UIImage(data: imagedData)

이미지만 있는 사용자 지정 셀을 사용하여 테이블 뷰 내에서 구현했습니다.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
        
        let cell = tableView.dequeueReusableCellWithIdentifier("theCell", forIndexPath: indexPath) as! customTableViewCell

        let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")
        
        let imagedData = NSData(contentsOfURL: imageURL!)!
            
        cell.imageView?.image = UIImage(data: imagedData)
        
        return cell
        
    }

Swift 2.0:

1)

if let url = NSURL(string: "http://etc...") {
    if let data = NSData(contentsOfURL: url) {
        imageURL.image = UIImage(data: data)
    }        
}

OR

imageURL.image =
    NSURL(string: "http:// image name...")
    .flatMap { NSData(contentsOfURL: $0) }
    .flatMap { UIImage(data: $0) }

이 메서드를 VC 또는 확장에 추가합니다.

func load_image(urlString:String)
{   let imgURL: NSURL = NSURL(string: urlString)!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in

        if error == nil {
            self.image_element.image = UIImage(data: data)
        }
    }
}

용도:

self.load_image(" url strig here")
class ImageStore: NSObject { 
    static let imageCache = NSCache<NSString, UIImage>()
}

extension UIImageView {
    func url(_ url: String?) {
        DispatchQueue.global().async { [weak self] in
            guard let stringURL = url, let url = URL(string: stringURL) else {
                return
            }
            func setImage(image:UIImage?) {
                DispatchQueue.main.async {
                    self?.image = image
                }
            }
            let urlToString = url.absoluteString as NSString
            if let cachedImage = ImageStore.imageCache.object(forKey: urlToString) {
                setImage(image: cachedImage)
            } else if let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
                DispatchQueue.main.async {
                    ImageStore.imageCache.setObject(image, forKey: urlToString)
                    setImage(image: image)
                }
            }else {
                setImage(image: nil)
            }
        }
    }
}

용도:

let imageView = UIImageView()
imageView.url("image url")

AsyncImage 이미지를 동시에 로드하고 표시하는 뷰인 iOS 15 이후에 정식으로 도입되었습니다.

 var imageView : AsyncImage

imageView = AsyncImage(url: URL(string: entry.photo))
    .frame(width: 200, height: 200)

또한 다음을 지원합니다.

문서에서 더 보기

Swift 4.1 이미지 URL만 전달하는 기능을 만들었습니다. 이미지가 생성된 후 캐시 키를 완료 블록으로 설정합니다.

   class NetworkManager: NSObject {
  
  private var imageQueue = OperationQueue()
  private var imageCache = NSCache<AnyObject, AnyObject>()
  
  func downloadImageWithUrl(imageUrl: String, cacheKey: String, completionBlock: @escaping (_ image: UIImage?)-> Void) {
    
    let downloadedImage = imageCache.object(forKey: cacheKey as AnyObject)
    if let  _ = downloadedImage as? UIImage {
      completionBlock(downloadedImage as? UIImage)
    } else {
      let blockOperation = BlockOperation()
      blockOperation.addExecutionBlock({
        let url = URL(string: imageUrl)
        do {
          let data = try Data(contentsOf: url!)
          let newImage = UIImage(data: data)
          if newImage != nil {
            self.imageCache.setObject(newImage!, forKey: cacheKey as AnyObject)
            self.runOnMainThread {
              completionBlock(newImage)
            }
          } else {
            completionBlock(nil)
          }
        } catch {
          completionBlock(nil)
        }
      })
      self.imageQueue.addOperation(blockOperation)
      blockOperation.completionBlock = {
        print("Image downloaded \(cacheKey)")
      }
    }
  }
}
extension NetworkManager {
  fileprivate func runOnMainThread(block:@escaping ()->Void) {
    if Thread.isMainThread {
      block()
    } else {
      let mainQueue = OperationQueue.main
      mainQueue.addOperation({
        block()
      })
    }
  }
}

최신 변경 사항을 위해 편집됨 09/2021

// It's better to use extension 
extension UIImageView {
func downloadImage(from URLString: String, with completion: @escaping (_ response: (status: Bool, image: UIImage? ) ) -> Void) {
    guard let url = URL(string: URLString) else {
        completion((status: false, image: nil))
        return
    }
    
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard error == nil else {
            completion((status: false, image: nil))
            return
        }
        
        guard let httpURLResponse = response as? HTTPURLResponse,
              httpURLResponse.statusCode == 200,
              let data = data else {
            completion((status: false, image: nil))
            return
        }
        
        let image = UIImage(data: data)
        completion((status: true, image: image))
    }.resume()
}
}

해피 코딩.건배:)

Swift 2.0 및 X-Code 7.1과 함께 작동하는 안전한 이미지를 가져오는 방법:

static func imageForImageURLString(imageURLString: String, completion: (image: UIImage?, success: Bool) -> Void) {
    guard let url = NSURL(string: imageURLString),
        let data = NSData(contentsOfURL: url),
        let image = UIImage(data: data)
        else { 
            completion(image: nil, success: false); 
            return 
       }

    completion(image: image, success: true)
}

그런 다음 이 메서드를 다음과 같이 부릅니다.

imageForImageURLString(imageString) { (image, success) -> Void in
        if success {
            guard let image = image 
                 else { return } // Error handling here 
            // You now have the image. 
         } else {
            // Error handling here.
        }
    }

이미지를 사용하여 보기를 업데이트하는 경우 "성공한 경우 {}:

    dispatch_async(dispatch_get_main_queue()) { () -> Void in
         guard let image = image 
              else { return } // Error handling here 
         // You now have the image. Use the image to update the view or anything UI related here
         // Reload the view, so the image appears
    }

UI에서 이미지를 사용하는 경우 이 마지막 부분이 필요한 이유는 네트워크 호출에 시간이 걸리기 때문입니다.위와 같이 dispatch_async를 호출하지 않고 이미지를 사용하여 UI를 업데이트하려고 하면 컴퓨터는 이미지를 가져오는 동안 이미지를 찾고 이미지(아직)가 없음을 발견하고 이미지를 찾지 못한 것처럼 이동합니다.dispatch_async 완료 폐쇄 안에 코드를 넣으면 컴퓨터에 "가서 이 이미지를 가져오고 완료되면 이 코드를 완료하십시오."라고 말합니다.그렇게 하면 코드가 호출되고 잘 작동하는 이미지를 갖게 될 것입니다.

이미지를 비동기식으로 다운로드하려면 Kingfisher 라이브러리를 사용하는 것이 좋습니다.킹피셔를 사용할 때 가장 좋은 점은 이미지 URL을 ID로 하여 다운로드된 모든 이미지를 기본적으로 캐시한다는 것입니다.다음 번에 특정 URL로 이미지를 다운로드하도록 요청하면 캐시에서 이미지를 로드합니다.

용도:

newsImage.kf.setImage(with: imageUrl!, placeholder: nil, options: nil, progressBlock: nil, completionHandler: { (image, error, cacheType, imageUrl) in
                if error == nil{
                    self.activityIndicator.stopAnimating()
                }else if error != nil{
                    self.activityIndicator.stopAnimating()
                }
            })

포드를 사용할 수 있습니다.SDWebImage동일한 것을 달성하기 위해.사용하기 쉽습니다.설명서는 여기에서 확인할 수 있습니다. SD Web Image

여기 샘플 코드가 있습니다.

self.yourImage.sd_setImage(with: NSURL(string: StrUrl as String ) as URL!, placeholderImage: placeholderImage, options: SDWebImageOptions(rawValue: 0), completed: { (image, error, cacheType, imageURL) in
                if( error != nil)
                {
                    print("Error while displaying image" , (error?.localizedDescription)! as String)
                }
            })

서버에서 이미지 로드:-

func downloadImage(from url: URL , success:@escaping((_ image:UIImage)->()),failure:@escaping ((_ msg:String)->())){
    print("Download Started")
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else {
            failure("Image cant download from G+ or fb server")
            return
        }

        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        DispatchQueue.main.async() {
             if let _img = UIImage(data: data){
                  success(_img)
            }
        }
    }
}
func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

용도 :-

  if let url = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
                        self.downloadImage(from:url , success: { (image) in
                            print(image)

                        }, failure: { (failureReason) in
                            print(failureReason)
                        })
                    }

Swift 4.2 및 Alamofire 이미지

라이브러리를 사용하는 것이 문제가 되지 않는다면, 당신은 그것을 할 수 있습니다.AlamofireImage내 샘플은 Github에서 온 것입니다.

자리 표시자 이미지 예:

let imageView = UIImageView(frame: frame)
let url = URL(string: "https://httpbin.org/image/png")!
let placeholderImage = UIImage(named: "placeholder")!
imageView.af_setImage(withURL: url, placeholderImage: placeholderImage)

그것은 이미지로 작업할 수 있는 많은 편리한 기능과 확장 기능을 가지고 있습니다.캐시에서 크기 조정 및 크기 조정, 심지어 이미지에 필터 적용에 이르기까지 다양한 작업을 참조하십시오.만약 당신의 앱에서 이미지가 중요하다면, 저는 이 프레임워크를 사용하여 당신의 시간을 절약하는 것을 제안합니다.

이미지를 파일로 다운로드하는 Swift 2.x 응답(이미지를 메모리에 저장하는 Leo Dabus의 응답과는 대조적).Leo Dabus의 답변과 Get the data from NSURLSession Download Task With Request from Completion handler의 답변을 기반으로 합니다.

    // Set download vars
    let downloadURL = NSURL() // URL to download from
    let localFilename = "foobar.png" // Filename for storing locally 

    // Create download request
    let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in
        guard location != nil && error == nil else {
            print("Error downloading message: \(error)")
            return
        }

        // If here, no errors so save message to permanent location
        let fileManager = NSFileManager.defaultManager()
        do {
            let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            let fileURL = documents.URLByAppendingPathComponent(localFilename)
            try fileManager.moveItemAtURL(location!, toURL: fileURL)
            self.doFileDownloaded(fileURL, localFilename: localFilename)
            print("Downloaded message @ \(localFilename)")
        } catch {
            print("Error downloading message: \(error)")
        }
    }

    // Start download
    print("Starting download @ \(downloadURL)")
    task.resume()


// Helper function called after file successfully downloaded
private func doFileDownloaded(fileURL: NSURL, localFilename: String) {

    // Do stuff with downloaded image

}

유일하게 부족한 것은 a입니다!

let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData!)

언급URL : https://stackoverflow.com/questions/24231680/loading-downloading-image-from-url-on-swift

반응형