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

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

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

5926閲覧

Swift Type '' does not conform to protocol ''エラー

tomotomo104114

総合スコア15

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/03/10 00:04

編集2019/03/10 00:09

プログラミング歴2ヶ月独学150時間程度の初心者です。2日ハマってしまったので皆様のお力を貸して下さい。

現在、以下のような自作アプリ開発をしています。
「WEB APIで取得したデータをタプル配列で格納して、Table Viewで一覧表示する」

今回お聞きしたい内容は以下の2点。

  1. 必要なメソッドは追加しているが、Type '' does not conform to protocol ''となる原因
  2. tableView.dataSource = self でのUse of local variable 'tableView' before its declarationとなる原因

下に問題のコードを記載していますのでよろしくお願いします。

[経緯]

タプル配列で格納する所までは出来たのですが、題記のようなエラーが出てしましました。

Table VIewで表示するためにやったこと
0. calssにUITableViewDataSource追加
0. tableView.dataSource = self 追加
0. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return hogehoge.count
} 追加
0. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "hogehoge", for: indexPath)
cell.textLabel?.text = venueList[indexPath.row].name
return cell
} 追加

Table Viewを実装する際に必要なメソッドは追加できていると思っていたのですが、下記エラーが出てしまいました。
0. Type '' does not conform to protocol ''
0. Use of local variable 'tableView' before its declaration

[推測]

原因としては、これらのコードをviewDidLoad内に全てコードを書いていること?と推測しています。
画面を読み込んだ際にWEB API取得からデータ格納、Table View表示までやりたいので、viewDidLoad内に書いています。
ここも何かいい手がないか検討している所です。

長くなりましたが、改めて今回お聞きしたい内容は以下の2点です。

  1. 必要なメソッドは追加しているが、Type '' does not conform to protocol ''となる原因
  2. tableView.dataSource = self でのUse of local variable 'tableView' before its declarationとなる原因

どうぞよろしくお願いいたします。

Swift

1 2// Foursquare APIを利用したTweet機能実装 3 4import UIKit 5import FoursquareAPIClient 6import Social 7 8class SettingViewController: UIViewController,UITableViewDataSource { 9 10 //,UITableViewDelegate { 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 // Do any additional setup after loading the view. 16 17 //Use of local variable 'tableView' before its declaration 18 tableView.dataSource = self 19 20 //viewDidLoadにコード書いて画面起動時に実行する 21 //Foursquare APIを利用してリクエストURLからJSONコードを生成し格納する機能を実装 22 23 //認証KeyであるIDとSecretの宣言 24 let clientId = "hoge" 25 let clientSecret = "hoge" 26 27 // 現在位置を東京駅に指定 28 // to do GPSから現在位置を取得する 29 let currentLocation_latitude = 35.681236 30 let currentLocation_longitude = 139.767125 31 32 //緯度経度からvenue検索するreq_URL作成するfunc 33 //venue search, 検索数=5、範囲を指定 34 //guard letもdo catch 構文と同じ考えか。サンプルアプリはデコード作業していたのでエラー回避無理になるのか。 35 36 guard let req_url = URL (string : "https://api.foursquare.com/v2/venues/search?v=20180228&ll=(currentLocation_latitude),(currentLocation_longitude)&intent=checkin&limit=5&radius=4000&client_id=(clientId)&client_secret=(clientSecret)") 37 else { 38 return 39 } 40 41 //req_URLのデバック 42 print(req_url) 43 44 45 //以下で、req_urlにアクセスし構造体にレスポンスデータを格納する処理を行う 46 //取得したレスポンスデータ(JSON)を記録する構造体を宣言 47 48 //ItemJson構造体に以下のレスポンスデータを格納 49 struct ItemJson : Codable { //Codable : JSONを変換にした時に、一括して変数にデータを格納するプロトコル 50 let response : JsonResponse? 51 } 52 53 struct JsonResponse : Codable { 54 let venues : [JsonVenues] 55 } 56 57 //JSONデータがオブジェクトだったのに配列で宣言していたので格納エラーになっていた 58 struct JsonVenues : Codable { 59 let name : String? 60 let location : Jsonlocation? 61 } 62 63 struct Jsonlocation : Codable { 64 let city : String? 65 let state : String? 66 let country : String? 67 } 68 69 // structの配列化 venuesで配列型の宣言しているので 多分不要 70 //struct ResultJson : Codable { 71 // let item : [ItemJson]? 72 //} 73 74 //レスポンスデータのリスト(タプル配列) 75 var venueList : [(name:String, city:String, state:String, country:String)] = [] 76 77 //req_urlをロードするプロトコルを宣言 78 let req = URLRequest(url:req_url) 79 80 //リクエストのデータ転送方法の複雑なコードをひとまとめにしているクラス ら し い 81 let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) 82 83 //ダウンロード先URL:req、data格納、通信状態データ格納、エラー内容格納 84 let task = session.dataTask(with: req, completionHandler: { 85 (data, response, error) in 86 87 session.finishTasksAndInvalidate() 88 89 // パースの際にエラーになった場合の例外処理でdo catch 90 //コード内でプログラムが完結しないのでエラーチェックができない+外部と通信しているのでエラー条件が多すぎてif分では回避できない 91 //そこでこのdo catch構文  92 do { 93 94 //JSONをデコードするためのオブジェクトを作成 95 let decoder = JSONDecoder() 96 97 //受け取ったJSONデータをパースして格納 98 //decode(ResultJson)からdecode(ItemJson)にしたら上手くいった 99 100 let json = try decoder.decode(ItemJson.self, from: data!) 101 102 //デバック用 103 print (json) 104 105 if let Venues = json.response?.venues { 106 107 //検索結果のタプル配列を初期化 108 venueList.removeAll() 109 110 for venues in Venues { 111 112 if let name = venues.name, 113 let city = venues.location?.city, 114 let state = venues.location?.state, 115 let country = venues.location?.country { 116 117 let tupleVenue = (name,city, state, country) 118 119 venueList.append(tupleVenue) 120 } 121 122 } 123 124 125 self.tableView.reloadData() 126 127 if let tupleVenuedbg = venueList.first { 128 print ("-------------------------------") 129 print ("venueList[0] = (tupleVenuedbg)") 130 } 131 132 } 133 134 135 } catch { 136 print("エラーが発生しました") 137 } 138 139 }) 140 141 //ダウンロード開始 142 task.resume() 143 144 //------------------------------------------------------------------------------- 145 //ここで宣言しているが、エラー Type 'SettingViewController' does not conform to protocol 'UITableViewDataSource' 146 147 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 148 return venueList.count 149 } 150 151 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 152 153 let cell = tableView.dequeueReusableCell(withIdentifier: "venueCell", for: indexPath) 154 155 cell.textLabel?.text = venueList[indexPath.row].name 156 157 return cell 158 } 159 160 } //viewDidLoad end 161 162 //storyboardとViewControllerでtableViewを関連付け 163 @IBOutlet weak var tableView: UITableView! 164 165 166 167 168 169} //class end 170

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

viewDidLoad内で以下を宣言してるのが悪いと思います。
viewDidLoadの外に移動するのに合わせてvenueListもメンバ変数にする必要がありますね。

Swift

1 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 2 return venueList.count 3 } 4 5 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 6 7 let cell = tableView.dequeueReusableCell(withIdentifier: "venueCell", for: indexPath) 8 9 cell.textLabel?.text = venueList[indexPath.row].name 10 11 return cell 12 }

投稿2019/03/10 01:48

nakasho_dev

総合スコア2655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomotomo104114

2019/03/10 02:26

nakasho_dev様 ご教授頂きありがとうございます! やはり、viewdidload内に書いたのが原因でしたか。何となくでも推測があっていたのである意味嬉しかったです笑。 さて、教えて頂いたようにまずは外に出す所から再挑戦してみます。 今回は基礎力が足りなく、funcについての知識が足らなかったことが原因と思うので合わせてそこらへんの知識も深めたいと思います。 進めていく中でエラーがまた出ると思うので、その時はお時間がある時にお付き合い頂ければ幸いです。 今回はありがどうございます。
tomotomo104114

2019/03/14 12:21

nakasho_dev様 無事に題記の件が解決することが出来ました。ありがとうございました。 自分なりに原因を分析してみたのですが、 1. tableViewを利用するので、dateSource必須メソッド2つを記載する必要がある 2. func viewDidLoad() {   func 1 func 2 } とメソッド内メソッドを宣言していたのが失敗?ここが合っているか疑問です。 3.2の必須メソッドを外に出す必要があるが、そうするとタプル配列がスコープ外にあるのでタプル配列をメンバー変数にしてやる こんな感じで解決しました。今回学んだのは、変数にはスコープが存在するということでした。 参考書をベースに作っているのでスコープを意識しなくても物が作れてしまうのでいい気づきになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問