How to load image in swift using Alamofire

后端 未结 9 904
醉话见心
醉话见心 2020-12-13 13:16

I have a collection view controller, which load image Async by URL. (Something like Instegram) I am looking for the best way to implement the part of the loading image. plea

相关标签:
9条回答
  • 2020-12-13 13:35

    Actually there are multiple ways to load your image from URL using Alamofire. and this is a way that i've developed and i'm using it already in one of my Swift projects. This way i'm loading the images Asyncrounsly and display them into UITableView and from performance wise it's fine and there is no blocking while scrolling UITableView because it's care about cashing the images loaded.

    First you have to create a GET request using Alamofire to download the image, and you have to use Request+AlamofireImage from AlamofireImage Library so you have to

    import AlamofireImage
    

    And then in

        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    

    }

    you have to call your image download request like this:

             //Download image
            // We should perform this in a background thread
            Alamofire.request(.GET, deshItem.dish_imageUrl!)
                .responseImage { response in
                    debugPrint(response)
    
                    print(response.request)
                    print(response.response)
                    debugPrint(response.result)
    
                    if let image = response.result.value {
                        print("image downloaded: \(image)")
    
                        // Store the commit date in to our cache
                        self.ImageCache[dishName!] = image
    
                        // Update the cell
                        dispatch_async(dispatch_get_main_queue(), {
                            if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                                    let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
                                    dishImageView.image = image
    
                            }
                        })
    
                    }
            }
    

    For Image Caching i've created a dictionary that will contain image for every cell or item(String), So this way of caching images will avoid the locking that appear while scrolling.

    Complete Sample code:

    import AlamofireImage
    
    class MainFeedTableViewController: UITableViewController, FloatRatingViewDelegate {
    
    var ImageCache = [String:UIImage]()
    
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MainFeedCellID", forIndexPath: indexPath)
    
        // Configure the cell...
    
        let dishName = deshItem.dish_name
    
        //This is a workaround to cash the image and improve the performance while user scrolling UITableView.
        // If this image is already cached, don't re-download
        if let dishImage = ImageCache[dishName!] {
                    let dishImageView:UIImageView = cell.viewWithTag(104) as! UIImageView
                    dishImageView.image = dishImage
        }
        else {
            //Download image
            // We should perform this in a background thread
            Alamofire.request(.GET, deshItem.dish_imageUrl!)
                .responseImage { response in
                    debugPrint(response)
    
                    print(response.request)
                    print(response.response)
                    debugPrint(response.result)
    
                    if let image = response.result.value {
                        print("image downloaded: \(image)")
    
                        // Store the commit date in to our cache
                        self.ImageCache[dishName!] = image
    
                        // Update the cell
                        dispatch_async(dispatch_get_main_queue(), {
                            if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
                                    let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
                                    dishImageView.image = image
    
                            }
                        })
    
                    }
            }
    
        }
    
    
    
        return cell
    }
    
    0 讨论(0)
  • 2020-12-13 13:35

    I have developed a small and straightforward CocoaPods library to work with Alamofire and Images.

    CocoaPods is a great way of addressing your library dependencies needs. It is easy to install once, and easy to add and update dependencies to your projects.

    The library is open source and can be found at https://github.com/gchiacchio/AlamoImage

    It has great documentation with examples, so you will be enjoying it in minutes.

    I have it working in a couple of project myself, including collection views and scrolling.

    0 讨论(0)
  • 2020-12-13 13:38

    Here's an approach using RxAlamofire:

    import Alamofire
    import RxAlamofire
    
    extension UIImageView {
        public func imageFromUrl(urlString: String) {
            requestData(.GET, urlString)
                .observeOn(MainScheduler.instance)
                .subscribeNext { self.image = UIImage(data: $0.1) }
        }
    }
    
    0 讨论(0)
  • 2020-12-13 13:48

    I created a Swift version of UIImageView+AFNetworking here : Github.
    You don't have to use AFNetworking (and a bridging header) or Alamofire in your project. Just add the file to your project and use it.


    Example usage:

    myImageView.setImageWithUrl(imageUrl, placeHolderImage: somePlaceHolderImage)
    
    0 讨论(0)
  • 2020-12-13 13:53

    Taken from Alamofire/README.md

    "In order to keep Alamofire focused specifically on core networking implementations, additional component libraries have been created by the Alamofire Software Foundation to bring additional functionality to the Alamofire ecosystem.

    AlamofireImage - An image library including image response serializers, UIImage and UIImageView extensions, custom image filters, an auto-purging in-memory cache and a priority-based image downloading system."

    https://github.com/Alamofire/AlamofireImage

    0 讨论(0)
  • 2020-12-13 13:57

    As authors mention in Alamofire README.md:

    When should I use AFNetworking?

    • UIKit extensions, such as asynchronously loading images to UIImageView

    So answer to your question :

    So is AFNetworking is better for this task?

    Yes!

    But if still want to use vanilla Alamofire project, you can fetch image this way:

       Alamofire.request(.GET, "https://robohash.org/123.png").response { (request, response, data, error) in
            self.myImageView.image = UIImage(data: data, scale:1)
        }
    

    P.S.

    But if you just want to load image (of course async) - you don't need to use Alamofire or AFNetworking at all. Just add this small extension in your code:

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

    And use it:

    myImageView.imageFromUrl("https://robohash.org/123.png")
    
    0 讨论(0)
提交回复
热议问题