我想从我的应用程序中的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
}

在objective - 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一起工作,我该如何解决这个问题。


当前回答

干净的方式:

extension URL {
    var favIcon16: UIImage? { getFav(ofSize: .s) }
    var favIcon32: UIImage? { getFav(ofSize: .m) }
    var favIcon64: UIImage? { getFav(ofSize: .l) }
    var favIcon128: UIImage? { getFav(ofSize: .xl) }
    var favIcon256: UIImage? { getFav(ofSize: .xxl) }
    var favIcon512: UIImage? { getFav(ofSize: .xxxl) }

    private func getFav(ofSize s: FavSize) -> UIImage? {
        guard UIApplication.shared.canOpenURL(self),
              let favUrl = URL(string: "https://www.google.com/s2/favicons?sz=\(s.rawValue)&domain=\(self.absoluteURL)"),
              let data = try? Data(contentsOf: favUrl)
        else { return nil }
        return UIImage(data: data)
 }
    private enum FavSize: Int, CaseIterable { case s = 16, m = 32, l = 64, xl = 128, xxl = 256, xxxl = 512 }
}

和用法:

let myUrl = URL(string: "http://facebook.com")
myImgView.image = myUrl.favIcon16

其他回答

在使用SwiftUI时,SDWebImageSwiftUI是最好的选择。

通过XCode的Swift Package Manager添加依赖:https://github.com/SDWebImage/SDWebImageSwiftUI.git

然后使用WebImage()而不是Image()

WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))

这是从URL加载/下载图像的工作代码。NSCache自动和显示占位符图像下载和加载实际图像(Swift 4 | Swift 5代码)。

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 }

您可以使用pod SDWebImage来实现相同的功能。它很容易使用。你可以在SDWebImage这里获得文档

下面是示例代码

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

斯威夫特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)

你需要做的是:

UIImage(data: data)

在Swift中,他们已经用规则构造函数取代了大多数Objective C工厂方法。

See:

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