iOS: load an image from url

前端 未结 9 1346
生来不讨喜
生来不讨喜 2020-12-02 14:06

I need to load an image from a url and set it inside an UIImageView; the problem is that I don\'t know the exact size of the image, then how can I show the image correctly?<

相关标签:
9条回答
  • 2020-12-02 14:38

    Swift safe code version:

    private func loadImage(from url:URL) -> UIImage? {
        let imageData: Data
        
        do {
            imageData = try Data(contentsOf: url)
        } catch {
            return nil
        }
        
        return UIImage(data: imageData)
    }
    
    private func loadImage(from urlString:String) -> UIImage? {
        guard let url = URL(string: urlString) else {
            return nil
        }
        
        return self.loadImage(from: url)
    }
    

    Be in mind that this code is not thread safe, you should run it on a background thread. For example:

    DispatchQueue.global().async {
        let image = UIImage(fromFile: "http://xpto.com/image.png")
        
        // And then you should update UI on main thread.
        // If you have an UIImageView outlet you can update its image this way:
        DispatchQueue.main.async {
            imageView.image = image
            imageView.contentMode = .scaleAspectFit
        }
    }
    
    0 讨论(0)
  • 2020-12-02 14:39

    One common mistake in displaying an image downloaded from json or a url is the problem of queues. ALL UI-related things need to be done in the main queue, so if you forgot this, even perfect code (above answers are good) won't display your image on occasion. To call the mainQueue, use code like this, and note that calling main queue might need to be done seperately in the called imageDisplay function:

    dispatch_async(dispatch_get_main_queue(), ^{
    
        self.nameLabel.text = self.pokemon.name;
    
        [self displayImage];  //CALLS FUNCTION
        self.abilitiesTextView.text = @"loves SwiftUI";
    });
    
    - (void)displayImage {            
    
        NSString *imageURLString = [NSString stringWithFormat: self.pokemon.sprite];
        NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageURLString]];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.spriteImageView.image = [UIImage  imageWithData: imageData];
        });
    
        // NOTE: important for newer versions of XCode/Obj-C...
        //[imageData release];   With ARC ("automated release..."), release method is forbidden, it's already done for you.
    }
    
    0 讨论(0)
  • 2020-12-02 14:40

    IN SWIFT 3.0

    The main thread must be always remain free so it serves the user interface and user interactions.

    class ViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    private func fetchImage() {
        let imageURL = URL(string: "https://i.stack.imgur.com/9z6nS.png")
        var image: UIImage?
        if let url = imageURL {
            //All network operations has to run on different thread(not on main thread).
            DispatchQueue.global(qos: .userInitiated).async {
                let imageData = NSData(contentsOf: url)
                //All UI operations has to run on main thread.
                DispatchQueue.main.async {
                    if imageData != nil {
                        image = UIImage(data: imageData as! Data)
                        self.imageView.image = image
                        self.imageView.sizeToFit()
                    } else {
                        image = nil
                    }
                }
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchImage()
    }
    
    }
    
    0 讨论(0)
  • 2020-12-02 14:46

    To download Asynchronous image with Kingfisher library you can follow this step,url :https://github.com/onevcat/Kingfisher:

     func imageFromUrl(_ urlString: String) {
            if let url = URL(string: urlString) {
                ImageDownloader.default.downloadImage(with: url, options: [], progressBlock: nil) {
                    (image, error, url, data) in
                    DispatchQueue.main.async {
                        self.imageView.image = image
                    }
                }
            }
        }
    

    You can also download image with default URLSession.shared.dataTask

     func imageFromUrl(_ urlString: String) {
            if let url = URL(string: urlString) {
                let request = URLRequest(url: url)
                URLSession.shared.dataTask(with: request) {(data,response,error) in
                    if let imageData = data as Data? {
                        if let img = UIImage(data: imageData){
                           DispatchQueue.main.async {
                           self.imageView.image = img
                           }
                        }
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-02 14:50

    Just use the size property of UIImage, for example:

    NSURL *url = [NSURL URLWithString:path];
    NSData *data = [NSData dataWithContentsOfURL:url];
    UIImage *img = [[UIImage alloc] initWithData:data];
    CGSize size = img.size;
    
    0 讨论(0)
  • In swift regarding using optionals:

    var url:NSURL? = NSURL(string: imageString)
    var data:NSData? = NSData(contentsOfURL : url!)
    var image = UIImage(data : data!)
    
    0 讨论(0)
提交回复
热议问题