2017-02-20 24 views
-1

SwiftyJsonで返される特定の値を決定することに本当に問題があります。うまくいけば、誰かが私にこれを説明するのを助けることができる。SwiftyJsonでの正確なキーの一致

JSONレスポンスから受け取った任意の単語に「apple」という所定の単語が一致するかどうかを確認したいと思います。

一致するものがある場合、メッセージが表示され、ユーザは次のレベルに進むことを選択するか、ユーザがホーム画面に戻ります。

一致するものがない場合、メッセージが表示され、ユーザーは再生を続行するか、再生をキャンセルする必要があります。

さまざまなレベルのゲームで複数の単語を使用したいと思います。

レベル1:受信したJSON応答のいずれかに「apple」を一致させます。

レベル2:受信したJSON応答のいずれかに「コンピュータ」を一致させます。

レベル3:受け取ったJSONレスポンスのいずれかに、「電話」、「電話」、「iPhone」、「Android」、またはこれらのいずれかまたはすべてを一致させます。

基本的にすべてのJSONレスポンスを取得できますが、特定の事前定義されたJSONレスポンスが返されているかどうかを判断するための設定方法を見つけるのは難しいです。私はすべてのJSONレスポンス

// Use SwiftyJSON to parse results 
     let json = JSON(data: dataToParse) 
     let errorObj: JSON = json["error"] 

// Parse the response 
      print(json) 
      let responses: JSON = json["responses"][0] 

       // Get label annotations 
      let labelAnnotations: JSON = responses["labelAnnotations"] 
      let numLabels: Int = labelAnnotations.count 
      var labels: Array<String> = [] 
      if numLabels > 0 { 
       var labelResultsText:String = "Labels found: " 
       for index in 0..<numLabels { 
        let label = labelAnnotations[index]["description"].stringValue 
        labels.append(label) 
       } 
       for label in labels { 
        // if it's not the last item add a comma 
        if labels[labels.count - 1] != label { 
         labelResultsText += "\(label), " 
        } else { 
         labelResultsText += "\(label)" 
        } 
       } 
       self.labelResults.text = labelResultsText 
      } else { 
       self.labelResults.text = "No labels found" 
      } 

を表示するように

JSONレスポンス

{ 
    "responses" : [ 
    { 
     "labelAnnotations" : [ 
     { 
      "mid" : "\/m\/01m2v", 
      "score" : 0.9245476, 
      "description" : "computer keyboard" 
     }, 
     { 
      "mid" : "\/m\/01c648", 
      "score" : 0.7945268, 
      "description" : "laptop" 
     }, 
     { 
      "mid" : "\/m\/01mfj", 
      "score" : 0.74227184, 
      "description" : "computer hardware" 
     }, 
     { 
      "mid" : "\/m\/0541p", 
      "score" : 0.7062791, 
      "description" : "multimedia" 
     }, 
     { 
      "mid" : "\/m\/07c1v", 
      "score" : 0.7039645, 
      "description" : "technology" 
     }, 
     { 
      "mid" : "\/m\/03gq5hm", 
      "score" : 0.69323385, 
      "description" : "font" 
     }, 
     { 
      "mid" : "\/m\/0bs7_0t", 
      "score" : 0.6724673, 
      "description" : "electronic device" 
     }, 
     { 
      "mid" : "\/m\/01vdm0", 
      "score" : 0.66489816, 
      "description" : "electronic keyboard" 
     }, 
     { 
      "mid" : "\/m\/0121tl", 
      "score" : 0.60392517, 
      "description" : "electronic instrument" 
     }, 
     { 
      "mid" : "\/m\/0h8n5_7", 
      "score" : 0.5834592, 
      "description" : "laptop replacement keyboard" 
     } 
     ] 
    } 
    ] 
} 

CODE別のポストではなく、無駄:(週間どこでも見ている

EDIT

私は明らかに自分自身の質問に答えることができませんが、私はそれがよりよい解決策だと思って編集を投稿しますが、@ pierceは1つの単語にはかなりまともです。ゲーム設定アプリケーションには適用できませんでした。その後、レベルの状態を処理するための機能、

そして最後に作成した

func checkAnnotations(annotations: [Annotation]) -> Bool { 
    var isMatched = false 

    let searchWords = self.words 
    for searchWord in searchWords { 
     for annotation in annotations { 
      if searchWord == annotation.descriptionString { 
       isMatched = true 
       break 
      } 
     } 

     if isMatched { 
      break 
     } 
    } 

    return isMatched 
} 

だから、私は、新しいNSObjectのを作成し、その後

static var _words: [[String]] = [

["apple", computer", "beer"]] 

を作成しましたView ControllerのJSONレスポンスと比較して前進dレベルが一致した場合

  // Get JSON key value 
      let labelAnnotations = responses["labelAnnotations"].arrayValue 
      let annotationObjects: [Annotation] = labelAnnotations.flatMap({ annotationDictionary in 
       if let mid = annotationDictionary["mid"].string, 
       let score = annotationDictionary["score"].double, 
        let description = annotationDictionary["description"].string { 
        let annotation = Annotation(mid: mid, score: score, descriptionString: description) 
        return annotation 
       } 

       return nil 
      }) 

      //print(annotationObjects) 

      let searchString = LevelState.shared.words[0] 
      print("Level \(LevelState.shared.level), looking for: \(searchString)") 

      var isMatched = LevelState.shared.checkAnnotations(annotations: annotationObjects) 
      if isMatched { 
       LevelState.shared.advance() 
      } 

      let alertTitle = isMatched ? "Congrats! You got \(searchString)" : "Keep looking for \(searchString)" 

      //let translationResult = "Translated: \(levelDescription) to \(translatedText)" 

      let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert) 
      alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) 
      self.present(alertController, animated: true, completion: nil) 

      } 

     self.prepareForNewLevel() 
     }) 
    } 
+1

私はいくつかのことについて少しはっきりしていません。まず、 'labels'配列のすべてのエントリにコンマを追加するのはなぜですか?次に、 'labels'を' JSON'の 'description'に設定するように見えます。もしあなたがそれらの値をユーザが入力した単語と比較する必要があれば、あなたのためにフィルタリングするでしょうか? 'let matches = labels.filter {$ 0.contains(user_entered_word)}' – Pierce

+0

カンマは、複数のJSON応答が返された場合にのみ使用されます。もし私が一つの希望する言葉をあらかじめ定義しているのであれば、それは明らかに必要ではありません。私が他の例で見たように "フィルター"を使うことができれば、私のコードでそれを設定する方法がわからない:/ 1分私は本当にJsonを理解しているように感じる、次の分それを解析することによって完全に混乱します。 @ピアース – pythlang

+0

私はあなたのために以下の答えを追加しました。希望を助けてくれる – Pierce

答えて

0

最初のこと - 各説明の末尾にカンマを追加する理由がわかりません。私は本当に不必要なことです。あなたは配列内の要素を分けることについて混乱していますか?実際のStringはこれを必要としないため、配列の要素(つまりlet array = ["a", "b", "c"])を手作業で書き出す場合のみです。

このlabelsの配列のプロパティを設定すると、Stringの配列になります。あなたが経て、あなたJSONからすべてのdescription値を追加したら

var labels: Array<String> = [] 

、あなたはそれを操作することができます。

func findMatches(_ userEntry: String) -> [String] { 

    return labels.filter { $0.contains(userEntry) } 

} 

は今、あなたはユーザーエントリのいくつかの並べ替えを処理するために、上記の方法を使用することができます。

if numLabels > 0 { 

    for index in 0..<numLabels { 
     let label = labelAnnotations[index]["description"].stringValue 
     labels.append(label) 
    } 

} 

は今、あなたは、いくつかのユーザが入力した単語に基づいてString秒のフィルタ配列を返すメソッドを作成することができます、あなたはtextFieldという名前UITextFieldからテキストを持っていたと言うように:

// Return the filtered matches based on the textField text (unless nil) 
let matches = findMatches(textField.text ?? "") 

// Print the number of matches, and also show the matches 
print("Found \(matches.count) matches to user input\r\(matches)") 

今、あなたは012を開催labelsを持っていた場合あなたは何のために上findMatches方法を使用することができます」 -

Found 4 matches to user input 
["a", "aa", "ba", "apple"] 

EDITは:、とはuserEntryは「」、あなたはコンソールウィンドウにこのプリントアウト見たいだけの手紙だった上記のコードを実行しました一致するようにあらかじめ決められた言葉でやろうとしています。あなたが何をしようとしているのかよくわからないが、いくつかの方法がある。あなたはそれをループその後

let words = ["word", "verb", "noun", "adverb"] 

ができ、あなただけをチェックしたい場合は、それぞれ1

for word in words { 

    let matches = findMatches(word) 
    if matches.count > 0 { 
     print("Found \(matches.count) matches to \(word)\r\(matches)") 
    } else { 
     // Do whatever you want when there are no matches 
     print("No matches found") 
    } 

} 

をチェック:まず、あなたが配列としてチェックしたい所定の単語の配列を持っていたと言います具体的な回答をしてください:

func checkWord(word: String, noMatchResponse: String) { 

    let matches = findMatches(word) 
    if matches.count > 0 { 
     print("Found \(matches.count) matches to \(word)\r\(matches)") 
    } else { 
     // Do whatever with the no match response 
     print(noMatchResponse) 
    } 

} 

これを実装できる方法はたくさんあります。また、switchステートメントを使用して、あらかじめ決められた単語ごとに異なるcaseステートメントを使用することもできます。それはあなた次第であり、ゲームをどのようにデザインしたいのですか?

+0

@pythlang - ああ大丈夫です。物事を正しく機能させるために、私はあなたが印刷を計画しているときにそのようなことをすることをお勧めします。 – Pierce

+0

素晴らしい、私はこれを試してみます。 "ラベルが見つかりました:stem、table、hand、apple"のような長い文章で結果が返されるだけなので、各説明の末尾にカンマを追加すると、カンマを付ける必要がありますかなり悪い見えます: "ラベルが見つかりました:ステムテーブルハンドリンゴ"。カンマで追記するのは余計で、とにかく ".count"で終わるのであれば、いつでも削除できると思います。ユーザー入力はありません。あらかじめ定義されている単語は、ゲームの進捗状況に関して自分でハードコードされています。どのように見えるだろうか? @Pierce – pythlang

+0

@pythlang - これはまったく同じように見えますが、textFieldのテキストを使用していた部分にあらかじめ定義された単語を置き換えることができます: 'let matches = findMatches(" your_predefined_word ")' – Pierce

関連する問題