ドコモの「しゃべってコンシェル」や Appleの「Siri」のようなサービスが誰でも作れる！？今度はドコモが提供する「知識Q&A」APIを試してみた！


## 概要

[前回の記事](http://qiita.com/asakahara/items/3c582d4073fa67ca599a)では「雑談対話」APIの利用方法を紹介しました。
同じタイミングで「知識Q&A」APIの利用申請をしたのですが、
特に連絡もないまま気づいたときには利用できるようになっていたのでご紹介します。
ちなみに「知識Q&A」APIは質問文をテキストで受け付け、回答を返却するAPIです。
サイトには「質問は話しかけるような自然な文章を入力できます。回答はズバリの回答候補を返却します。」という説明がありますが、ズバリな回答が返ってくることは中々ないので、辛抱強く聞いてあげてくださいw

このAPIに加え今回は`AVSpeechSynthesizer`, `AVSpeechUtterance`を使用したテキストの読み上げ機能を追加することでよりSiriっぽくしたいと思います。

## 今回作ったアプリのイメージ

アプリのスクリーンショットです。

![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/30826/5f11e33d-6105-63e9-f41d-88c2def7ee6b.png "screenshot.png")

## 導入手順

ライブラリの導入については[前回の記事](http://qiita.com/asakahara/items/3c582d4073fa67ca599a)を参照してください。

追加の手順として音声の読み上げ機能を使用するために`AVFoundation.framework`をターゲットに追加します。

## APIの使い方

ここも前回と同様にAFNetworkingを利用しますが、今回はPOSTではなくGETでリクエストします。

``` リクエストURL
https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask/?APIKEY=xxxxxxxx
```
qパラメータに「○○は誰」「○○は何ですか」といった、自然な文章をテキストで入力してください。
リクエスト時は、リクエストURLをUTF-8でエンコードする必要がありますが、`AFNetworking`を使用している場合は自動でエンコードしてくれます。

``` パラメータの例
{
 　"q":"明日の東京の天気は何ですか？",
}
```

`AFNetworking`での実装例です。

```objc
static const NSString * API_KEY = @“xxxxxxx”;

- (void)fetchQARequest:(NSString *)question completionHandler:(void (^)(NSDictionary *result, NSError *error)) completionHandler
{
    AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
    
    // パラメータの設定
    NSDictionary* param = @{@"q" : question};
    [manager GET:[NSString stringWithFormat:
                   @"https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask/?APIKEY=%@", API_KEY]
        parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
            
        NSLog(@"response: %@", responseObject);
        
        if (completionHandler) {
            completionHandler(responseObject, nil);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        
        NSLog(@"Error: %@", error);
        
        if (completionHandler) {
            completionHandler(nil, error);
        }
    }];
}
```

リクエストが成功すると下記のようなjson形式のレスポンスが返却されます。

``` レスポンスサンプル
{
　{"code":"S020010","message":{"textForDisplay":"インターネットで調べたところ、もしかすると晴時々曇です。","textForSpeech":"インターネットで調べたところ、もしかするとハレトキドキクモリです。"},"answers":[{"rank":"1","answerText":"晴時々曇","linkText":"リアルタイム検索｜dメニュー","linkUrl":"http://realtime.search.smt.docomo.ne.jp/knfnt.html?IE=UTF-8&id_list=414032698269638656&kw=%E6%98%8E%E6%97%A5%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A9%E6%B0%97"},{"rank":"2","answerText":"西高東低","linkText":"リアルタイム検索｜dメニュー","linkUrl":"http://realtime.search.smt.docomo.ne.jp/knfnt.html?IE=UTF-8&id_list=414379070420299777&kw=%E6%98%8E%E6%97%A5%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A9%E6%B0%97"},{"rank":"3","answerText":"晴","linkText":"リアルタイム検索｜dメニュー","linkUrl":"http://realtime.search.smt.docomo.ne.jp/knfnt.html?IE=UTF-8&id_list=414304487646322688&kw=%E6%98%8E%E6%97%A5%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A9%E6%B0%97"},{"rank":"4","answerText":"曇","linkText":"リアルタイム検索｜dメニュー","linkUrl":"http://realtime.search.smt.docomo.ne.jp/knfnt.html?IE=UTF-8&id_list=414304487646322688&kw=%E6%98%8E%E6%97%A5%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A9%E6%B0%97"},{"rank":"5","answerText":"雲","linkText":"リアルタイム検索｜dメニュー","linkUrl":"http://realtime.search.smt.docomo.ne.jp/knfnt.html?IE=UTF-8&id_list=414058749746110464&kw=%E6%98%8E%E6%97%A5%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A9%E6%B0%97"}]}
}
```

### テキストの読み上げ方法

テキストの読み上げは非常に簡単です。
テキストの読み上げを行いたいソースコードに`AVFoundation/AVFoundation.h` をインポートします。
あとは下記のように`AVSpeechSynthesizer`, `AVSpeechUtterance`を使用して実装してください。


```objc
// AVSpeechSynthesizerの初期化
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
// 読み上げるテキストの設定
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:message];
// 読み上げる言語の設定
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"ja-JP"];
// 声の高さを設定（0.5〜2.0）
utterance.pitchMultiplier = 1.0;
// 読み上げ開始
[synthesizer speakUtterance:utterance];
```

## 最後に

テキストを読み上げるようにすることでよりSiriっぽくなったのではないかと思います。
いろいろ可能性を感じる機能なので、ぜひトライしておもしろいアプリ作りの参考にされてみてはと思います。

今回作成したサンプルのソースコードもアップしておきます。

https://github.com/asakahara/ASAppLikeSiri2