如何从我通过API调用获取的URL加载图像

时间:2015-12-31 07:01:28

标签: ios swift uiimageview uicollectionview ios9

我想使用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

中显示这些图像

UPDATE ::使用注释代码变得奇怪的问题我在viewdidload中调用我的webservice

override func viewDidLoad() {
    super.viewDidLoad()

    webimages()

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

并开始调用webservice

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

4 个答案:

答案 0 :(得分:2)

您正在将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 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的代码中发生了什么:)

修复您的崩溃问题,这不是您原始问题的一部分,而是您创建的另一个问题,将部分中的项目的计数返回到您的图像数组的计数,并在检索到数据后重新加载集合视图:

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课程的学分:Daniel Sattler

特别感谢:CouchDeveloper

答案 1 :(得分:0)

您可以轻松地从该网址下载图片并将其设置为图片视图的图片,

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

将ImageLoader类添加到项目中并修改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
}

这是一个异步图像加载类,因此如果您反对使用任何第三方库或类,UI不会冻结或给您任何其他问题,请手动执行@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

答案 2 :(得分:0)

您可以按照以下方式扩展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"])

答案 3 :(得分:0)

  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)
        }
    }