2017-12-06 12 views
0

オプションの要素がありますが、その要素をテーブルビューに表示するときにエラーが発生しています。参考までに、この要素はJSON APIフィードから取得した画像です。私はそれを使用して要素をアンラップすることを理解しています!それは良いアイデアではありませんが、xcodeが私に示唆していることです。私がその提案に従うと、アプリケーションがクラッシュし、が「オプション値をアンラッピングしている間に予期せず見つからない」と表示されます。誰かがURLから画像を表示する方法を知っていますか?ここに私がこれまで持っているコードがあります。オプション要素をアンラッピングするときのエラー

struct PlayerStats:Decodable { 
    let personaname: String? 
    let score: Double? 
    let solo_competitive_rank: Int? 
    let avatar: String? 
} 

問題はcellForRowAt funcの「avatar」要素にあります。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "rankCell") as? RankTableViewCell else { return UITableViewCell() } 
    cell.nameLabel.text = rank[indexPath.row].personaname 

    if let imageURL = URL(string: rank[indexPath.row].avatar) { 
     DispatchQueue.global().async { 
      let data = try? Data(contentsOf: imageURL) 
      if let data = data { 
      guard let avatar = UIImage(data: data) else { return } 
       DispatchQueue.main.async { 
        cell.avatarImage.image = avatar 
       } 
      } 
     } 
    } 

    return cell 
} 
+1

'Data(contentsOf:imageURL)'をディスパッチしてもメインスレッドをブロックすることはありませんが、インターネットからのコンテンツのダウンロードには 'Data'のイニシャライザを使用すべきではありません。この初期化子は、ネットワークのURLではなく、__local__ファイルのURLからコンテンツをロードする場合にのみ使用してください。 –

+0

私を訂正していただきありがとうございます。私はこれまで知っていた材料からこの知識を逸脱しているだけなので、私はこの問題を知らなかった。 –

+1

* "これはxcodeが私に何を示唆しているか" * - 私はこのサイトのSwift質問の半分がXcodeのこの素敵な "機能"によって引き起こされたと考えています。私は本当にいつかアップルがこれを変えてくれることを願っています – rmaddy

答えて

1

avatarnilの場合、コードがクラッシュします。あなたが代わりにURLに直接avatarをデコードする2つの段階

if let avatar = rank[indexPath.row].avatar, 
    let imageURL = URL(string: avatar) { ... 

にURLを作成する必要があり、JSONDecoderはその

let avatar: URL? 

は、その後、あなたは、コード

if let imageURL = rank[indexPath.row].avatar { 

を短縮することができそして、あなたが強くありDávidが述べたように同期のData(contentsOf: APIを使用することをお勧めしません。非同期で使用するURLSession

1

オプションのavatarプロパティを安全にアンラップする必要があるという点以外は、コードにいくつかの概念的な問題があります。

まず、tableView(_:cellForRowAt:)の内部では非同期操作を実行しないでください。これは同期メソッドなので、UITableViewCellが返され、ネットワークURLから画像をダウンロードできるようになります。非同期操作の実行が終了すると、別の関数でイメージのダウンロードを実行し、テーブルビュー(または少なくとも対応する行/セクション)を再ロードする必要があります。

第2に、イニシャライザData(contentsOf:)をインターネットからダウンロードするのに使用しないでください。 Data(contentsOf: imageURL)を送信しても、メインスレッドをブロックすることはなく、データの初期化子をインターネットからのコンテンツのダウンロードに使用しないでください。このイニシャライザは、ネットワークURLではなく、ローカルファイルURLからコンテンツをロードする場合にのみ使用してください。

関連する問題