如何从 url 加载我通过 API 调用获得的图像

How to load image from url which I got via API calling

我想使用 UICollectionView 来显示图像,我正在通过 api 调用获取图像。

问题:所以我通过 api 调用获取图像路径,所以如何将它显示到 UICollectionView??

这是我的代码::

  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
    let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell

    cell.imagev.image = dic["image"] as? UIImage
    return cell
}

这是我的 api 回复

(
    {
    image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/esquire.jpg";
    slug = esquire;
},
    {
    image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/forbes.jpg";
    slug = forbes;
},
    {
    image = "http://radio.spainmedia.es/wp-content/uploads/2015/12/tapas.jpg";
    slug = tapas;
}
)

那么如何在我的 UICollectionView

中显示这些图像

更新::在使用注释代码时遇到奇怪的问题时,我在 viewdidload 中调用我的网络服务

override func viewDidLoad() {
    super.viewDidLoad()

    webimages()

    // Do any additional setup after loading the view, typically from a nib.
}

并开始调用网络服务

func webimages()
{

let url = "http://radio.spainmedia.es/podcasts/"

    request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (response:Response<AnyObject, NSError>) -> Void in


           print(response.result.value)

            self.imagearray = (response.result.value) as! NSMutableArray
            print(self.imagearray)


    }

}

但是在请求它之后突然转到 cellForItemAtIndexPath 所以我的 "imagearray" 在那里找到了 nil。然后它返回到 webimages() 并给我 api 响应。

那我该如何解决呢?

we have array of string we are passing single string here so can you please tell me that what is the solution

我们有字符串数组,我们在这里传递单个字符串,所以你能告诉我解决方案是什么吗

enter image description here

非常简单,您可以从 url 下载图像并将其设置为图像视图的图像,

试试这个,https://github.com/natelyman/SwiftImageLoader

将 ImageLoader class 添加到您的项目并修改 collectionview 数据源,如下所示,

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary
let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell

//cell.imagev.image = dic["image"] as? UIImage

ImageLoader.sharedLoader.imageForUrl(dic["image"], completionHandler:    {(image: UIImage?, url: String) in
     cell.imagev.image = image
})

return cell
}

这是一个异步图像加载 class 所以 UI 不会冻结或给你任何其他问题如果你反对使用任何第三方库或 classes 请这样做手动作为@NSNoob 的回答。

其他好的图像加载库是,

https://github.com/nicklockwood/AsyncImageView

https://github.com/onevcat/Kingfisher

https://github.com/MengTo/Spring/blob/master/Spring/AsyncImageView.swift

https://github.com/anas10/AsyncImageView-Swift

您正在将 URL 字符串设置为 UIImage。您首先必须先从 URL 检索图像。使用以下方法快速补救:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
    if imagearray.count > 0 
    {
       let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary

       let imgURL: NSString = dic!["image"] as! NSString //Get URL string
       let url = NSURL.URLWithString(imgURL); //Create URL
       var err: NSError?
       var imageData :NSData = NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)! //Fetch Image Data
       var cellImage = UIImage(data:imageData) //Create UIImage from Image data
       cell.imagev.image = cellImage //Set image
    }

    return cell
}

请注意,这是在同步调用中获取图像 URL 的内容,这样会冻结您的 UI 直到下载完成。此外,这不会缓存图像,因此当您滚动并重新创建单元格时,图像将被一遍又一遍地下载。为避免这种情况,我建议缓存 .

为了获得更好的结果,这是异步加载图像的方式,不会冻结 UI 并缓存图像以避免网络负载。

您首先必须像这样创建一个 class:

class ImageLoader {

var cache = NSCache() //Create cache

class var sharedLoader : ImageLoader {
    struct Static {
        static let instance : ImageLoader = ImageLoader()
    }
    return Static.instance
}

func imageForUrl(urlString: String , indexPathArg:NSIndexPath!, completionHandler:(image: UIImage?, url: String,indexPathResponse:NSIndexPath?) -> ()) {

    let currentIndexPath: NSIndexPath! = indexPathArg.mutableCopy() as! NSIndexPath

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in

        let data: NSData? = self.cache.objectForKey(urlString) as? NSData
        //Check if image data for this URL already exists in Cache
        if let goodData = data {
            //data exists, no need to download it again. Just send it
            let image = UIImage(data: goodData)
            dispatch_async(dispatch_get_main_queue(), {() in
                completionHandler(image: image, url: urlString,indexPathResponse: currentIndexPath)
            })
            return
        }
        //Data does not exist, We have to download it
        let downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!,completionHandler: { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
            if (error != nil) {
                //Download failed
                completionHandler(image: nil, url: urlString, indexPathResponse: currentIndexPath)
                return
            }

            if data != nil {
                //Download successful,Lets save this downloaded data to our Cache and send it forward as UIImage
                let image = UIImage(data: data!)
                self.cache.setObject(data!, forKey: urlString)
                dispatch_async(dispatch_get_main_queue(), {() in
                    completionHandler(image: image, url: urlString, indexPathResponse: currentIndexPath)
                })
                return
            }

        })
        downloadTask.resume()
    })

}
}

然后您必须像这样修改您的 collectionview 委托:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell :imagecell = collectionView.dequeueReusableCellWithReuseIdentifier("imagecell", forIndexPath: indexPath) as! imagecell
    if imagearray.count > 0 
    {
       let dic = imagearray .objectAtIndex(indexPath.row) as! NSDictionary

       let imgURL: NSString = dic!["image"] as! NSString//Get URL string
       ImageLoader.sharedLoader.imageForUrl(imgURL as String,indexPathArg: indexPath, completionHandler:{(image: UIImage?, url: String, indexPathResponse: NSIndexPath?) in


        let indexArr:NSArray = collectionView!.indexPathsForVisibleItems()

        if indexArr.containsObject(indexPathResponse!)
        {
            cell.imagev.image = image //Set image
        }

    })
    }


    return cell
}

现在它将异步加载您的图像,并且仅在必要时才下载。巨大的成功! (引用波拉特的话)。我已经添加了注释,以便您可以理解我的代码和 Daniel 的代码中发生了什么:)

要解决您的崩溃问题,这不是您最初问题的一部分,而是您创建的另一个问题,Return 部分中的项目计数将作为图像数组的计数,并在您拥有后重新加载集合视图检索到您的数据:

func webimages()
{

let url = "http://radio.spainmedia.es/podcasts/"

    request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (response:Response<AnyObject, NSError>) -> Void in


           print(response.result.value)

            self.imagearray = (response.result.value) as! NSMutableArray
            print(self.imagearray)
            //Reload Collection view
            self.collectionView?.reloadData()

    }

}


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return imagearray.count
}

Imageloader 的学分 class:Daniel Sattler

特别感谢:CouchDeveloper

您可以按如下方式扩展 UIImageView -

extension UIImageView {
    public func imageFromU(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)
                }
            }
        }
    }
}

然后在任何 UIImageView 中,您将有一个非常简单的辅助方法,如下所示 -

yourImageView.imageFromURL("https://yoururl.com/image.png")

在你的情况下

cell.imagev.image.imageFromURL(dic["image"])
  if let url = NSURL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
        if let data = NSData(contentsOfURL: url){
            imageURL!.contentMode = UIViewContentMode.ScaleAspectFit
            imageURL!.image = UIImage(data: data)
        }
    }