質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.10%

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 79

diamons

score 7

ビルド自体はできるのですがシミュレータ内で検索をすると<<<<>>>>の部分でタイトルのエラーが出てうまく動いてくれません。どこかでnilが悪さしてる事はわかるのですが解決法がわからないのでわかるかたがいらっしゃいましたらぜひ教えていただけたらと思います。

//
//  ViewController.swift
//  MyOkashi
//
//  Created by aaaaa on 2020/06/24.
//  Copyright © 2020 aaaaa. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UISearchBarDelegate, UITableViewDataSource {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        //Search Bar のdelegate通知先を設定
        searchText.delegate = self
        //入力のヒントとなる、プレースホルダーを設定
        searchText.placeholder = "お菓子の名前を入力してください"
        //TableViewのdataSourceを設定
        tableView.dataSource = self

    }


    @IBOutlet weak var searchText: UISearchBar!

    @IBOutlet weak var tableView: UITableView!

    //お菓子のリスト(タプル配列)
    var okashiList : [(name:String , maker:String , link:URL , image:URL)] = []


    //検索ボタンをクリック時
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        //キーボードを閉じる
        view.endEditing(true)

        if let searchWord = searchBar.text {
            //デバックエリアに出力
            print(searchWord)
            //入力されていたらお菓子を検索
            searchOkashi(keyword: searchWord)
        }
    }
    //JSONのitem内のデータ構造
    struct ItemJson : Codable {
        //お菓子の名称
        let name: String?
        //メーカー
        let maker : String?
        //掲載URL
        let url : URL?
        //画像URL
        let image : URL?

    }

    //JSONのデータ構造
    struct ResultJson : Codable {
        //複数要素
        let item :[ItemJson]?
    }
    //searchOkashiメソッド
    //第一引数 : keyword  検索したいワード
    func searchOkashi(keyword : String){
        //お菓子の検索キーワードをURLエンコードする
        guard let keyword_encode = keyword.addingPercentEncoding(withAllowedCharacters:  .urlQueryAllowed) else {
            return
        }


        // リクエストURLの組み立て
        guard let req_url = URL(string: "https://sysbird.jp/toriko/api/?apikey=guest&format=json&keyword=\(keyword_encode)&max=10&order=r") else {
            return
        }
        print(req_url)

        //リクエストに必要な情報を生成
        let req = URLRequest(url: req_url)
        //データ転送を管理するためのセッションを生成
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
        //リクエストをタスクとして登録
        let task = session.dataTask(with: req, completionHandler: {
            (data , response , error) in
            //セッションを終了
            session.finishTasksAndInvalidate()
            // do try catch エラーハンドリング
            do {
                //JSONDecoderのインスタンス取得
            let decoder = JSONDecoder()
                //受け取ったJSONデータをパース(解析)して格納
        <<<<<<let json = try decoder.decode(ResultJson.self,from:data!)>>>>>>

                //お菓子の情報が取得できているか確認
                if let items = json.item {
                    //お菓子のリストを初期化
                    self.okashiList.removeAll()
                    //取得しているお菓子の数だけ処理
                    for item in items {
                        //お菓子の名称、メーカー名、掲載URL, 画像URLをアンラップ
                        if let name = item.name , let maker = item.maker , let link = item.url , let image = item.image{
                            //一つのお菓子をタプルでまとめて管理
                            let okashi = (name,maker,link,image)
                            //お菓子の配列へ追加
                            self.okashiList.append(okashi)
                        }
                    }
                    if let okashidbg = self.okashiList.first{
                        print("----------------")
                        print("okashiList[0] = \(okashidbg)")
                    }
                }
            } catch {
                //エラー処理
                print("エラーが出ました")
            }

            })
        //ダウンロードの開始
        task.resume()

    }
 //cellの総数を返すdatasourceメソッド必ず記述する必要があります
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //お菓子リストの総数
        return okashiList.count
    }
    //cell に値を設定するdatasourceメソッド。必ず記述する必要があります。
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       //今回表示を行うCellオブジェクト(1行)を取得する
        let cell = tableView.dequeueReusableCell(withIdentifier: "okashicell", for: indexPath)
        //お菓子のタイトル設定
        cell.textLabel?.text = okashiList[indexPath.row].name
        //お菓子画像を取得
        if let imageData = try? Data(contentsOf: okashiList[indexPath.row].image){
            //正常に取得できた場合には、UIimageで画像オブジェクトを生成してcellにお菓子画像を設定。
            cell.imageView?.image = UIImage(data:imageData)
        }
        //設定ずみのCellオブジェクトを画面に反映。
        return cell
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

「たった2日でマスターできる iPhone アプリ開発集中講座」のコードだという前提で回答いたします。

実行時、デバッグエリアに

2020-06-30 16:22:45.851675+0900 274033_MyOkashi[45374:5927598] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

から始まる一連のエラーメッセージが出ていると思います。このメッセージにも書かれている通り、HTTP通信を行う場合には、Info.plistという名前のファイルで設定を行う必要があります。

書籍だと397ページあたりに記述されていますが、「ATSの設定を変更」というところの処理まで行ったあと実行しなければ実行時エラーとなります。

ちなみに、書籍のコードだとエラー処理が行われていないため実行時エラーとなっていますが、きちんとエラー処理を行えば実行時エラーで落ちることはないかと思います(これは書籍の問題ですが)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/30 16:47

    まさにその本です!
    ATSの設定変更してもエラーが治らなかったのですがいちど追加した設定を消してやり直したらできました!ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる