2017-11-15 13 views
0

一般:私は、ユーザーが選択したものに応じていくつかのplistのいくつかのアイテムを含むコレクションビューアプリケーションを持っています。 plistは、各配列の中に複数の文字列を持つ複数の配列を含む配列です。Swift: '[Any]'型の値を指定した型 'NSString'に変換できません。

問題:私のコレクション(またはplist)を検索するための検索バーをインプリメントすると、チュートリアルの後にこのエラーが発生します。

この検索バーコードは、plistの別の配列内の配列内の文字列ではなく文字列を検索するためのものです。だから私はエラーとコードを修正するための助けを探しています。

エラー:

Cannot convert value of type '[Any]' to specified type 'NSString'

これは、エラーの原因となってどのようなコードです。 plistのための検索バーのための私のコードの

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 

    filtered = car.filter({ (text) -> Bool in 
     let tmp: NSString = text // <-- ** Error is here ** 
     let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive) 
     return range.location != NSNotFound 
    }) 

    if(filtered.count == 0){ 
     searchActive = false; 
    } else { 
     searchActive = true; 
    } 

    self.finalCollectView.reloadData() 
} 

休憩

func createSearchBar() { 

    let mySearchBar = UISearchBar() 
    mySearchBar.showsCancelButton = false 
    mySearchBar.placeholder = "Search" 
    mySearchBar.delegate = self 
    mySearchBar.alpha = 1 
    mySearchBar.tintColor = UIColor.black 
    mySearchBar.searchFieldBackgroundPositionAdjustment = UIOffset(horizontal: 5, vertical: 0) 

    self.navigationItem.titleView = mySearchBar 
} 

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { 
    searchActive = true; 
} 

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) { 
    searchActive = false; 
} 

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { 
    searchActive = false; 
} 

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 
    searchActive = false; 
} 

コード

検索バーが最初を検索する必要が
<plist> 
    <array> 
     <array> 
      <string>Name1</string> 
      <string>Description</string> 
     </array> 
     <array> 
      <string>Name2</string> 
      <string>Description</string> 
     </array> 
     <array> 
      <string>Name3</string> 
      <string>Description</string> 
     </array> 
    </array> 
</plist> 

ようなplistがどのように見えるか
var filtered = [[Any]]() 
var searchActive: Bool = false 
var car = [[Any]]() 
@IBOutlet weak var finalCollectView: UICollectionView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.finalCollectView.delegate = self 
    self.finalCollectView.dataSource = self 

    readList(titlePlist: "car") 
} 

func readList(titlePlist: String) { 

    let url = Bundle.main.url(forResource: titlePlist, withExtension: "plist")! 
    do { 
     let data = try Data(contentsOf:url) 
     let sections = try PropertyListSerialization.propertyList(from: data, format: nil) as! [[Any]] 

     car = sections 

    } catch { 
     print("This error must never occur: Reading plist", error) 
    } 

各配列の文字列。ありがとうございました!

答えて

1

にフィルタリングを変更しますので、このコードは、配列の最初の文字列をフィルタリングします

filtered = car.filter({ (anArray) -> Bool in 
    guard let firstString = (anArray.first as? String) else{ 
     return false 
    } 
    let tmp: NSString = firstString as NSString 
    let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive) 
    return range.location != NSNotFound 
}) 
+0

?検索バーに入力すると、名前に応じて項目が表示されますか? – BroSimple

+0

@BroSimpleはい正しいです。 –

+0

私はコードを試してみましたが、検索するために何を入力しても、plistの最初の項目だけが表示されています。また、アイテムに何も含まれていないのでzzzzzと入力すると、検索ですべてのアイテムが表示され、フィルタリングされません。特定の文字は最初の項目を示していても、より多くの項目を表示します。 – BroSimple

1

carの内側の配列の最初の要素だけを検索する場合は、最初の要素を取得するのにflatMapを使用する必要があります。また、filterの内部にキャストすることを避けるために、要素をすぐにNSStringにキャストする必要があります。

filtered = car.flatMap({$0.first as? NSString})filter({ (text) -> Bool in... 

ただし、データ構造の選択はかなり奇妙です。 carをと宣言するのはなぜですか?Stringが含まれていて、内部配列が明らかに配列ではなく辞書であるように見える場合はどうでしょうか?私はcar[[String:String]]と宣言して、それに応じて.plistファイルを変更することをお勧めします。あなたのfunc searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)

関連する問題