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

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

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

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Xcode

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

Swift

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

Q&A

解決済

1回答

2248閲覧

Xcodeエラー「Reference to generic type 'Dictionary' requires arguments in <...>」

japan_

総合スコア1

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/10/27 08:23

概要

初心者です。
XMLファイルを読み込んで、TableViewに表示させたく
こちらを参考にしました。

4時間ほど粘りましたが、全く解決策がわかりません。

発生している問題・エラーメッセージ

//各エレメント用の変数
var posts:[Dictionary]!

postsをDictionary型にすると

Reference to generic type 'Dictionary' requires arguments in <...>

と出ます。

該当のソースコード

//XMLのフィード取得用URL let feedUrl : NSURL = NSURL(string:"xxxxx.xml")! //XMLの現在要素名を入れる変数 var currentElementName : String! //取得する要素名(とりはじめの要素) let itemElementName : String = "item" //取得する要素名の決定(item要素の下にあるもの) let nameElementName : String = "name" let makerElementName : String = "maker" let priceElementName : String = "price" let typeElementName : String = "type" let urlElementName : String = "url" let imageElementName : String = "image" //MARK: didload override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self posts = [] } override func viewDidAppear(_ animated: Bool) { //NSXMLParserクラスのインスタンスを準備 let parser : XMLParser = XMLParser(contentsOf: feedUrl as URL)! if parser != nil { // XMLParserDelegateをセット parser.delegate = self; parser.parse() //print("parser.parse") } else { // パースに失敗した時 print("failed to parse XML") } } //XMLを読み込み開始 func parserDidStartDocument(_ parser: XMLParser) { //print("parserDidStartDocument") } //XMLの読み込み終了 func parserDidEndDocument(_ parser: XMLParser!) { print("reload table") self.tableView.reloadData() //TableViewをReload } //各エレメントの中の要素を見つけた場合のメソッド func parser(_ parser: XMLParser, foundCharacters string: String){ if self.element.isEqual(self.nameElementName) { self.name.append( strip(str:string) ) } if self.element.isEqual(self.makerElementName) { self.maker.append( strip(str:string) ) } if self.element.isEqual(self.priceElementName) { self.price.append( strip(str:string) ) } if self.element.isEqual(self.typeElementName) { self.type.append( strip(str:string) ) } if self.element.isEqual(self.urlElementName) { self.url.append( strip(str:string) ) } if self.element.isEqual(self.imageElementName) { self.image.append( strip(str:string) ) } } //改行と半角スペースの除去 func strip(str: String) -> String { var strBr: String var strSp: String //改行除去 strBr = str.replacingOccurrences(of:"\n", with: "") //半角スペース除去 strSp = strBr.replacingOccurrences(of:" ", with: "") return strSp } //エレメントの読み込みが終了 func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if (elementName as NSString).isEqual(to: self.itemElementName) { //各メンバ変数がnilでなければメンバ変数elementsへ「キー」と「値」のペアを格納 if !self.name.isEqual(nil) { self.elements[nameElementName] = self.name } if !self.maker.isEqual(nil) { self.elements[makerElementName] = self.maker } if !self.price.isEqual(nil) { self.elements[priceElementName] = self.price } if !self.type.isEqual(nil) { self.elements[typeElementName] = self.type } if !self.url.isEqual(nil) { self.elements[urlElementName] = self.url } if !self.image.isEqual(nil) { self.elements[imageElementName] = self.image } self.posts.append(self.elements) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //セルの数 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if posts.count > 0{ return posts.count } return 10 //最初もしくはXMLが読み込まなれなかった場合は10行 } // sectionの数を決める func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } //TableViewのセルの設定 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) let imageView = cell.contentView.viewWithTag(1) as! UIImageView imageView.image = nil //イメージ初期化 let label = cell.contentView.viewWithTag(2) as! UILabel //イメージ読み込みのインジケータ let indicator = cell.contentView.viewWithTag(3) as! UIActivityIndicatorView indicator.startAnimating() indicator.isHidden = true //要素を読みこんだpostsがあれば if(posts.count>0){ if let name = posts[indexPath.row]["name"] { label.text = name as? String } else { label.text = "" } //画像の読み込み(Optionalの型のnil判定がうまく行かず2段確認になってしまった) if let imageURL:String = posts[indexPath.row]["image"] { if(!imageURL.isEmpty){ indicator.isHidden = false //画像の非同期ダウンロード(ただしキャッシュされないので、キャッシュの実装が必要) let catPictureURL = URL(string: imageURL) let session = URLSession(configuration: .default) let downloadPicTask = session.dataTask(with: catPictureURL!) { (data, response, error) in // The download has finished. indicator.isHidden = true if let e = error { print("Error downloading cat picture: (e)") } else { if let res = response as? HTTPURLResponse { print("Downloaded cat picture with response code (res.statusCode)") if let imageData = data { imageView.image = UIImage(data: imageData) } else { print("Couldn't get image: Image is nil") } } else { print("Couldn't get response code for some reason") } } } downloadPicTask.resume() } }else{ //画像がない場合 } } return cell } }

今回該当しないと思われる箇所は省略しました。

試したこと

Dictionary型をググり、キーと値が必要と調べ、

var posts:[Dictionary<String, Any>]

ではClass 'ViewController' has no initializersとエラー

var posts:[Dictionary] = [:]

ではCannot convert value of type '[AnyHashable : Any]' to specified type '[Dictionary<Key, Value>]'とエラーになります。

なぜエラーになるのか分からず仮説も建てられません、どうかよろしくお願いします。

補足情報

xcode Version 14.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

Swift

1var posts:[Dictionary<String, Any>]

ではClass ViewController has no initializers とエラー

クラスのプロパティは、インスタンスが作られた時点で初期化が完了、もしくはイニシャライザで初期化する必要がありますが、その処理がないためエラーが出ています。

Swift

1var posts:[Dictionary] = [:]

ではCannot convert value of type [AnyHashable : Any] to specified type '[Dictionary<Key, Value>]'とエラーになります。

これだと、Dictionary という型は指定しても、keyvalue の具体的な型を指定していないことが原因の一つとなります。

もう一つは、初期化の形式が辞書の配列になっていない、という点です。

全体をきちんとチェックしたわけではないため、あくまでも推論が含まれますが、

Swift

1var posts:[Dictionary<String, Any>] = [[:]]

と具体的な型を指定した上で、初期化(空の Dictionary(辞書) である [:] が入った Array (配列)なので、[[:]]となる)すればいいかとおもいます。

上記の書き方は糖衣構文(シンタックスシュガー)を用いれば

Swift

1var posts:[[String: Any]] = [[:]]

とも記述は可能です。

逆に、糖衣構文を一切使わないで記述すれば

Swift

1var posts:Array<Dictionary<String, Any>> = [[:]]

という記述でも同じです(まだまだパターンはありますが)。

投稿2020/10/27 09:13

編集2020/10/27 09:13
TsukubaDepot

総合スコア5086

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

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

japan_

2020/10/27 09:38

回答ありがとうございます。 無事実行することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問