首页 文章

如何使用URL显示图像?

提问于
浏览
32

错误是:“致命错误:在解包可选值时意外发现nil”

我在ViewController中执行以下操作:

var imageURL:UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg")
    let data = NSData(contentsOfURL:url!)
    if data!= nil {
        imageURL.image = UIImage(data:data!)
    }
}

我真的不明白为什么它会报告错误

imageURL.image = UIImage(data:data!)

虽然数据为零,但我已经告诉它不要继续 . 这不是链接的问题 . “数据”也没有问题 . 我试着打印它,它不是零 .

15 回答

  • 1

    该错误很可能是 imageURL 为零 . 您是在代码中的其他位置为其分配值,还是在实际代码中实际为 @IBOutlet ?如果你没有为它赋值,它将是nil - 但它的 UIImageView! 的类型意味着它是"implicitly unwrapped optional",这意味着编译器赢得了't stop you using it even if it is nil, but will crash at runtime with the error you' .

    其余的代码是正确的(假设在 != 之前缺少空格是编译代码中没有的错误),但你最好使用 if let 解包你的选项而不是检查 nil 然后使用force-unwrap运算符:

    if let url = NSURL(string: "http://etc...") {
        if let data = NSData(contentsOfURL: url) {
            imageURL.image = UIImage(data: data)
        }        
    }
    

    如果您碰巧使用Swift 1.2测试版,可以将两个ifs组合在一起:

    if let url  = NSURL(string: "http://etc..."),
           data = NSData(contentsOfURL: url)
    {
            imageURL.image = UIImage(data: data)
    }
    

    或者,如果您愿意,请使用 flatMap

    imageURL.image =
        NSURL(string: "http://etc...")
        .flatMap { NSData(contentsOfURL: $0) }
        .flatMap { UIImage(data: $0) }
    
  • 2

    这是我的代码可能会帮助你

    斯威夫特2:

    extension UIImageView{
    
        func setImageFromURl(stringImageUrl url: String){
    
            if let url = NSURL(string: url) {
                if let data = NSData(contentsOfURL: url) {
                    self.image = UIImage(data: data)
                }        
            }
        }
    }
    

    斯威夫特3:

    extension UIImageView{
    
    func setImageFromURl(stringImageUrl url: String){
    
          if let url = NSURL(string: url) {
             if let data = NSData(contentsOf: url as URL) {
                self.image = UIImage(data: data as Data)
             }
          }
       }
    }
    

    用法

    let imgURL = "https://yourdomain.com/picturepath/picname.png" // or jpg
     self.myImage.setImageFromURl(stringImageUrl: imgURL)
    

    如果您使用HTTP连接而不是https,请不要忘记添加此项

    App Transport Security Settings 作为字典并进入 Allow Arbitrary Loads 作为布尔值 YES 如下图
    enter image description here

  • 3

    在这里,我有一种方法,在下载图像时,您不会遇到任何类型的崩溃 . 现在您正在使用以下代码:

    override func viewDidLoad() {
        super.viewDidLoad()
        let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg")
        let data = NSData(contentsOfURL:url!)
        if data!= nil {
            imageURL.image = UIImage(data:data!)
        }
    }
    

    现在用这个改变代码,如果你继续这种方法:

    override func viewDidLoad() {
        super.viewDidLoad()
        let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg")
        let data = NSData(contentsOfURL:url!) 
    
        // It is the best way to manage nil issue. 
        if data.length > 0 {
            imageURL.image = UIImage(data:data!)
        } else {
            // In this when data is nil or empty then we can assign a placeholder image 
            imageURL.image = UIImage(named: "placeholder.png")
        }
    }
    

    而且我相信如果您使用它,您的零崩溃将会得到解决 .

  • 2

    您可以使用SDWebImage从URL https://github.com/rs/SDWebImage显示图像

    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                          placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
    
  • 3

    试着写:

    if data != nil {}
    

    代替:

    if data!= nil {}
    

    编译器可能会将感叹号与操作混淆,以解开可选值 .

  • 2

    You can set image in image view by using UIImageView+AFNetworking

    首先,在项目中拖动UIImageView AFNetworking目标c类,并在项目的桥头文件中导入UIImageView AFNetworking.h类 . 并使用此行在imageview中使用占位符设置图像 . 通过这种方式,您可以在视图中设置多个图像而不会卡住 .

    yourImageview.setImageWithURL(NSURL(string: self.yourArray.objectAtIndex(indexPath.row).objectForKey("imageurl") as! String), placeholderImage: UIImage(named:"NoUserimage.png"))
    
  • 1

    Swift 3: (本例中的图像是64位二进制数据)

    if let url = NSURL(string: route) {
                if let imageData = NSData(contentsOf: url as URL) {
                    let str64 = imageData.base64EncodedData(options: .lineLength64Characters)
                    let data: NSData = NSData(base64Encoded: str64 , options: .ignoreUnknownCharacters)!
                    let dataImage = UIImage(data: data as Data)
    
                }        
            }
    
  • 57

    Swift 3.0用于下载图像并使用URLSession和URLRequest解析json .

    static func getRequest(_ urlString:String, completion:@escaping (Any?) -> ()) {
        guard let url = URL(string: urlString) else { return }
        let session = URLSession.shared
        let request = URLRequest(url: url)
    
        let task = session.dataTask(with: request, completionHandler: {
            (data, response, error) -> Void in
    
            if let data = data {
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: [])
                    completion(json)
                } catch {
                    print(error)
                }
            }
        })
        task.resume()
    }
    
    static func downloadImage(_ url: String, completion:@escaping(UIImage?)->()) {
        let aUrl = URL(string: url)
        DispatchQueue.global().async {
            do {
                let data = try? Data(contentsOf: aUrl!)
                completion(UIImage(data: data!))
            } catch {
                print("Unable to download image")
            }
        }
    }
    
  • 3

    你的代码是对的,只需使用:

    if data != nil {
    
    }
    
  • 6

    您使用 Alamofire 的可能性非常大,如果是这样,它很简单:

    imageView.af_setImage(withURL: url)
    
  • 4

    这是它的代码 . 我用过这个你不需要包含类或其他任何内容 . 只需使用此扩展程序 . 这非常快 .

    extension UIImageView {
        public func imageFromURL(urlString: String) {
    
            let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
            activityIndicator.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
            activityIndicator.startAnimating()
            if self.image == nil{
                self.addSubview(activityIndicator)
            }
    
            URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in
    
                if error != nil {
                    print(error ?? "No Error")
                    return
                }
                DispatchQueue.main.async(execute: { () -> Void in
                    let image = UIImage(data: data!)
                    activityIndicator.removeFromSuperview()
                    self.image = image
                })
    
            }).resume()
        }
    }
    
  • 15

    问题是在viewDidLoad中,imageURL UIImageView可能尚未设置 . 如果UIImageView为零,我会使用可选链接

    imageURL?.image = UIImage(data:data!)

    我在viewDidLayoutSubviews()处设置了UIImageView的图像,此时你确定已经设置了ViewController的出口 .

    我这样做的方式如下:

    @IBOutlet weak var imageURL: UIImageView!
    var data: NSData?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let url = NSURL(string:"http://cdn.businessoffashion.com/site/uploads/2014/09/Karl-Lagerfeld-Self-Portrait-Courtesy.jpg")
        data = NSData(contentsOfURL:url!)
        if data != nil {
            imageURL?.image = UIImage(data:data!)
        }
    }
    
    override func viewDidLayoutSubviews() {
        if data != nil {
            imageURL.image = UIImage(data:data!)
        }
    }
    
  • 0
    NSURL(string: "")
    

    这将返回一个可选值 . 看看它的描述 . 它说 An NSURL object initialized with URLString. If the URL string was malformed, returns nil.

    在您的代码中,您尝试 url! ,只要url的值为nil就会崩溃 .

  • 0

    Methode

    extension UIImage {
    
    /// Loads image asynchronously
    ///
    /// - Parameters:
    ///   - url: URL of the image to load
    ///   - callback: What to do with the image
    
    class func loadFromURL(url: NSURL, callback: (UIImage)->()) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
    
            let imageData = NSData(contentsOfURL: url)
            if let data = imageData {
                dispatch_async(dispatch_get_main_queue(), {
                    if let image = UIImage(data: data) {
                        callback(image)
                    }
                })
            }
        })
    }
    

    }

    Usage

    let logoUrl = ImageService().buildImageString((self.uiConfig?.headerImage)!, imageMode: .Uniform, size: self.headerImage.frame.size)
        UIImage.loadFromURL(logoUrl, callback: { (image: UIImage) -> () in
            self.headerImage.image = image
        })
    
  • 3
    let urlImg = NSURL(string:"https://firebasestorage.googleapis.com/v0/b/fanism-dccfe.appspot.com/o/Heros%2FIMG-20171116-WA0003.png?alt=media&token=b31a6d9e-cea6-422a-b198-82365abd845e")
    
        data = NSData.init(contentsOf: urlImg! as URL)
        if data != nil {
            imageView?.image = UIImage(data:data! as Data) //**Here imageView our ImageView outlet  **//
        }
    

相关问题