URLを使って画像を表示する方法は?

というエラーが出ています: "致命的なエラー:Optional値のアンラップ中に予期せず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!)

が、データがnilの場合は処理しないように既に指示しているのですが。 リンクの問題ではありません。 また、"data"にも問題はありません。プリントしてみましたが、nilではありませんでした。

質問へのコメント (2)

エラーは、 imageURLがnilである可能性が最も高いです。 コードの別の場所に値を割り当てていますか、それとも実際のコードでは「@IBOutlet」ですか? 値を割り当てないと、nilになりますが、そのタイプの UIImageViewです。!は、「暗黙的にアンラップされたオプション」であることを意味します。つまり、コンパイラーは、nilであっても使用を停止しませんが、実行時にエラーが発生してクラッシュします。

コードの残りの部分は正しいです( の前に不足しているスペースを想定します。!=はコンパイルコードに含まれていないタイプミスです)。ただし、オプションを「nil」に対してチェックしてから、force-unwrap演算子を使用するのではなく、「if let」を使用してオプションをアンラップすることをお勧めします。

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

Swift 1.2ベータ版を使用している場合は、2つのifを組み合わせることができます。

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) }
解説 (4)

これが私のコードが役立つかもしれません。

スウィフト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」とその中への「任意の負荷を許可する」は、下の図のように値「はい」のブール値です。 。![ここに画像の説明を入力してください](http://i.stack.imgur.com/wcJrM.png。)

解説 (0)

ここでは、画像をダウンロードする際にクラッシュすることのない方法を紹介します。 現在、あなたは以下のコードを使用しています:

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

そして、あなたがそれを使うなら、あなたの無音クラッシュは解決されると確信しています。

解説 (1)

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"]];
解説 (0)

書いてみてください:

if data != nil {}

代わりに:

if data!= nil {}

コンパイラーは、感嘆符と操作を混同して、オプションの値を解凍する可能性があります。

解説 (2)

UIImageView+AFNetworkingを使用することにより、イメージビューに画像を設定することができます。

まず、UIImageView+AFNetworking objective cクラスをプロジェクトにドラッグし、プロジェクトのブリッジヘッダーファイルでUIImageView+AFNetworking.hクラスをインポートします。そして、この行を使用して、imageviewにプレースホルダを持つ画像を設定します。これにより、ビューに複数の画像を設定することができます。

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

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)

            }        
        }
解説 (1)

これがコードです。 これを使用して、クラスやその他のものを含める必要はありません。 この拡張機能を使用してください。 これは非常に高速です。

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()
    }
}
解説 (0)

Alamofire を使用していることはかなり大きな可能性があります。使用する場合は、次のように簡単です。

imageView.af_setImage(withURL: url)
解説 (0)

コードは正しいです。以下を使用してください。

if data != nil {

}
解説 (0)
NSURL(string: "") 

これはオプションの値を返します。 それの説明を見てください。 URLStringで初期化されたNSURLオブジェクト。 URL文字列が不正な形式の場合、nilを返します。

コードでは、「url」しようとしています。!`URLの値がなくなるとクラッシュします。

解説 (0)

問題は、viewDidLoadでimageURL UIImageViewがまだ設定されていない可能性があることです。 UIImageViewがnilの場合、オプションのチェーニングを使用します。

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

UIImageViewの画像をviewDidLayoutSubviews()に設定します。この時点で、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)

**メトード

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

}

使用方法について

    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
    }) 
解説 (0)
 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  **//
    }                                                                        
解説 (2)

URSessionとURLRequestを使用して画像をダウンロードし、jsonを解析するには、3.0をSwiftします。

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")
        }
    }
}
解説 (0)

Swift 4 :NSCacheを使用し、常にメインスレッドで実行される小さな画像(例:サムネイル)用のシンプルなローダー:

class ImageLoader {

  private static let cache = NSCache()

  class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {

      if let data = self.cache.object(forKey: url.absoluteString as NSString) {
        DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
        return
      }

      guard let data = NSData(contentsOf: url) else {
        DispatchQueue.main.async { completionHandler(nil) }
        return
      }

      self.cache.setObject(data, forKey: url.absoluteString as NSString)
      DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
    }
  }
}
解説 (0)