【アプリ】Todayee Voice 1.0 をリリースしました

2016年11月7日月曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第8弾「Todayee Voice」をリリースしました。音声認識を使ってエバーノートへテキストを投稿できるアプリです。



まずは動画デモをどうぞ。


上記動画の音量が小さめですが実際に話しかけた内容が変換されていって最後に音声コマンドで送信されている様子がわかると思います。


アプリの起動直後からすぐに音声認識が開始されます。


中央の円は1分間のカウントダウンタイマーになっています
(音声認識の上限が1分なため)。



話しかけると音声が次々にテキストに変換されて行きます。
(青い文字が認識途中で、黒文字は確定済)

テキストへの変換が終わったら送信ボタンを押すだけです。
後述する音声コマンドを使うとボタンを押さずに送信することもできます。

音声認識


iOS10 から提供された音声認識の API を使用していて、これは Siri でも使われている技術です。この音声認識は次のような特徴があります。

 ・オンラインのみ利用可能
 ・最長1分で終了
 ・一定時間無音だと終了
 ・認識途中に文脈に合わせて変化
 ・Appleがサービス提供中のみ利用可能
 ・利用可能な言語は60以上

言語設定は現在のものが使われますが、設定画面で他の言語に設定することも可能です。


音声コマンド


Todayee Voice では独自に音声コマンドというものを用意しています。音声認識の最後に特定のフレーズを言うことで、何らかのアクションを起こすことができます。このフレーズと仕組みを音声コマンドと呼んでいます。現在は「送信」「終了」「停止」がサポートされています。

 「送信(そうしん)」... 音声認識を確定させ、テキストを送信します。
 「終了(しゅうりょう)」「停止(ていし)」... 音声認識を確定して、テキスト編集状態になります。

 ※コマンドの文字列自体はテキストには含まれません。

音声コマンドとして認識されるとコマンドの文字列が緑色に光、ピピッと音がします。時々うまく認識されないことがあります。多くの場合はネットワークの一時的遅延(もしくはAppleの音声認識サービスの遅延)が原因だと思われます。外での移動中などネットワークが安定しない場合に多く発生する可能性があります。※この点はまだ改良の余地があります。


特殊文字入力


句読点なども変換することができます。

 「かいぎょう」... ※改行が入る
 「まる」... 句点(。)
 「てん」... 読点(、)
 「はてな」... ?
 「かっこ」... (
 「かっことじ」... )
 「かぎかっこ」... 「
 「かぎかっことじ」... 」



Todayee 共通機能


Todayee Voice は、Todayee(トゥデー) という名前の付く複数のアプリシリーズの1つです。一番の特徴は Todayeeシリーズからの投稿がすべて 毎日1つのノートへまとまる点です。Voiceから投稿したノートに、写真や音声を追記していくといったことができます。さらに複数のデバイスからの投稿も同様にまとめることができます(同一のエバーノートアカウントを使用した場合)。
下の図は Place と Pics からの投稿が1つのノートにまとまっている例です。

投稿は時刻で自動的にソートされます。


他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました
【アプリ】Todayee Extension 1.0 をリリースしました(無料)
【アプリ】Todayee Place 1.0 をリリースしました(無料)
【アプリ】Todayee Pisc 1.0 をリリースしました
【アプリ】Todayee Rec 1.0 をリリースしました


開発メモ


音声認識 API がやってきた


iOS 10 から音声認識の API(SFSpeechRecognizer)が開発者に提供されるようになった。音声認識の機能自体は古くから存在したが、これまで開発者には公開されてこなかった。今年の WWDC の iOS10 発表で Siri の一部機能解放と共に音声認識 APIの発表があって、ついに一般のアプリに組み込めるチャンスがやってきた。このニュースを聞いた時から何かのアプリで音声入力インターフェイスを搭載したいと考えていた。

iOS 9 以前の Appleの音声認識技術はお世辞にも高いとは言えなかった。Siriに話しかけても誤変換が多くイライラした人も多かったと思う。その点ライバルの Googleの音声認識の方が数段優れていた印象があって、小さな声で不明瞭に話しかけてもかなりの精度で変換してくれてた。それでも iOS10 になってからようやく Appleでも音声認識技術に進歩が見られてきて、以前と比べると明らかに認識精度が良くなった。まだ誤変換は多いけれど前ほどではなくなっている。少なくとも適切な音量ではっきりと話しかければまずまずの高い精度でテキストに変換してくれるようになった(なんだこりゃ、ってのも未だにあるが...)。まだ物足りない点はあるものの今回のアプリのような私的なメモ用途では徐々に実用的なレベルになってきたと感じる。そんなこともあって Todayeeシリーズの一つとして今回開発することにしてみた。



SFSpeechRecognizer


サンプルコード(多くは元ネタがAppleのやつ)が出回っているので実装自体は難しくない。API自体もシンプル。音声入力のために AVAudioEngine を入れるところが慣れないとわかりづらいくらいか。コールバックの処理はクロージャは使わずデリゲート(SFSpeechRecognitionTaskDelegate)を使った。そのほうが細かい制御ができるため。

この API は現状だとデフォルトで認識途中の文字列を返してくれるが(shouldReportPartialResults=true)、この時点ではまだ確定してなくて、話しかけていくうちに文脈に合わせて刻々と結果の文字列が変わっていく。この間は SFTranscription.segments: [SFTranscriptionSegment]  には十分な情報は入らない。ここに SFTranscriptionSegmentに substringや confidence などが入ってくるのは最後に確定した後(デリゲートだと speechRecognitionTask(task: didFinishSuccessfully:) 、クロージャでも同様の動き)。認識途中は話しかけた全内容が暫定的な文字列として渡ってくるだけ。

イメージ)こんな感じ

人間:「今日は」
暫定結果:「強は」
人間:「とても」
暫定結果:「今日はとても」
人間:「よい天気だった」
暫定結果:「今日はとてもよい」
暫定結果:「今日はとてもよい天気」
暫定結果:「今日はとてもよい天気だった」
確定:「今日はとてもよい天気だった」

開発者的には文節あるいは単語・句単位の情報が途中経過でも得られれば良いのだがそれはもらえない。毎回その時点での暫定の全文が渡される。

この点がインタラクティブに音声認識を扱いたいアプリにはイマイチなところ。ユーザと対話的に細かい制御をするには文字列処理で対応する必要がある。例えば、ユーザが発音した内容を単語・句として取り扱うには前回の文字列と今回の文字列を比較してその差分を取る。また取り消しの APIは今のところ提供されていないので、誤変換があってもそれを認識途中にインタラクティブに直すことが難しい。現状でも音声認識中にユーザが直前の単語・句を取り消すボタンを押すといったことは実装可能だが、アプリ側でできるのは文字位置を使うくらいしか方法が無いので最終的な認識結果が当初と変わるとうまく扱えない(文字位置がずれてしまうので)。認識中にインタラクティブに手を加えて行くには、変換途中と変換確定後を通じて単語や句をトラッキングできる仕組みが必要。いまはこれが無い。この点が現時点での APIの応用範囲を限定的にしてしまっていると感じた。


イメージ

人間:「今日は」
暫定結果:「京は」
人間:間違ってるじゃん。リテイク(仮)ボタンをポチして、再発音
人間:「今日は」
暫定結果:「京は今日は」
アプリ文字列:「今日は」(とりあえず開始のインデックスを +2としよう)
人間:「良い天気だ」
暫定結果:「京は今日は良い天気だ」
アプリ文字列:「今日は良い天気だ」
確定:「今日は今日はとてもよい天気だった」 ← 認識結果を最後に変えてしまった
アプリ文字列:「は今日はとてもよい天気だった」 あれ?


というわけで、iOS11ではこのあたりの改良を希望。


音声コマンド



これも音声認識APIを応用する上でやってみたかったことの一つ。実装してみると意外に楽しくてついついこの為に使ってしまったことも。単純なんだけどプチ未来感が感じられる機能。

この音声コマンドの実装は、大げさな仕組みは無くて実現方法はいたって簡単。コマンド(単語:例えば「送信」)の前後の空白時間を測ることで認識している。

(前回の認識)<-- t1 --> 「送信」 <-- t2--->

前回認識から t1秒すぎて、「送信」が認識され、さらにその後に t2秒の空白があったら「送信」をコマンドとして認識する。今後 APIの利用が進むともっと良い方法が出てくると思う(期待)。



あとがき


Voiceを作ってからというもののエバーノートへの投稿が格段に増えた。何かあれば起動して音声でつぶやく。手入力から音声入力への転換は思った以上に投稿のスタイルを変えるかもしれない。




アプリの入手は下記からどうぞ。







【アプリ】Todayee Voice 1.0 をリリースしました

| Published in | 0 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第8弾「Todayee Voice」をリリースしました。音声認識を使ってエバーノートへテキストを投稿できるアプリです。



まずは動画デモをどうぞ。


音量が小さめですが実際に話しかけた内容が変換されていって最後に音声コマンドで送信されている様子がわかると思います。


アプリの起動直後からすぐに音声認識が開始されます。


中央の円は1分間のカウントダウンタイマーになっています
(音声認識の上限が1分なため)。



話しかけると音声が次々にテキストに変換されて行きます。
(青い文字が認識途中で、黒文字は確定済)

テキストへの変換が終わったら送信ボタンを押すだけです。
後述する音声コマンドを使うとボタンを押さずに送信することもできます。

音声認識


iOS10 から提供された音声認識の API を使用していて、これは Siri でも使われている技術です。この音声認識は次のような特徴があります。

 ・オンラインのみ利用可能
 ・最長1分で終了
 ・一定時間無音だと終了
 ・認識途中に文脈に合わせて変化
 ・Appleがサービス提供中のみ利用可能
 ・利用可能な言語は60以上

言語設定は現在のものが使われますが、設定画面で他の言語に設定することも可能です。


音声コマンド


Todayee Voice では独自に音声コマンドというものを用意しています。音声認識の最後に特定のフレーズを言うことで、何らかのアクションを起こすことができます。このフレーズと仕組みを音声コマンドと呼んでいます。現在は「送信」「終了」「停止」がサポートされています。

 「送信(そうしん)」... 音声認識を確定させ、テキストを送信します。
 「終了(しゅうりょう)」「停止(ていし)」... 音声認識を確定して、テキスト編集状態になります。

 ※コマンドの文字列自体はテキストには含まれません。

音声コマンドとして認識されるとコマンドの文字列が緑色に光、ピピッと音がします。時々うまく認識されないことがあります。多くの場合はネットワークの一時的遅延(もしくはAppleの音声認識サービスの遅延)が原因だと思われます。外での移動中などネットワークが安定しない場合に多く発生する可能性があります。※この点はまだ改良の余地があります。


特殊文字入力


句読点なども変換することができます。

 「かいぎょう」... ※改行が入る
 「まる」... 句点(。)
 「てん」... 読点(、)
 「はてな」... ?
 「かっこ」... (
 「かっことじ」... )
 「かぎかっこ」... 「
 「かぎかっことじ」... 」



Todayee 共通機能


Todayee Voice は、Todayee(トゥデー) という名前の付く複数のアプリシリーズの1つです。一番の特徴は Todayeeシリーズからの投稿がすべて 毎日1つのノートへまとまる点です。Voiceから投稿したノートに、写真や音声を追記していくといったことができます。さらに複数のデバイスからの投稿も同様にまとめることができます(同一のエバーノートアカウントを使用した場合)。
下の図は Place と Pics からの投稿が1つのノートにまとまっている例です。

投稿は時刻で自動的にソートされます。


他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました
【アプリ】Todayee Extension 1.0 をリリースしました(無料)
【アプリ】Todayee Place 1.0 をリリースしました(無料)
【アプリ】Todayee Pisc 1.0 をリリースしました
【アプリ】Todayee Rec 1.0 をリリースしました


開発メモ


音声認識 API がやってきた


iOS 10 から音声認識の API(SFSpeechRecognizer)が開発者に提供されるようになった。音声認識の機能自体は古くから存在したが、これまで開発者には公開されてこなかった。今年の WWDC の iOS10 発表で Siri の一部機能解放と共に音声認識 APIの発表があって、ついに一般のアプリに組み込めるチャンスがやってきた。このニュースを聞いた時から何かのアプリで音声入力インターフェイスを搭載したいと考えていた。

iOS 9 以前の Appleの音声認識技術はお世辞にも高いとは言えなかった。Siriに話しかけても誤変換が多くイライラした人も多かったと思う。その点ライバルの Googleの音声認識の方が数段優れていた印象があって、小さな声で不明瞭に話しかけてもかなりの精度で変換してくれてた。それでも iOS10 になってからようやく Appleでも音声認識技術に進歩が見られてきて、以前と比べると明らかに認識精度が良くなった。まだ誤変換は多いけれど前ほどではなくなっている。少なくとも適切な音量ではっきりと話しかければまずまずの高い精度でテキストに変換してくれるようになった(なんだこりゃ、ってのも未だにあるが...)。まだ物足りない点はあるものの今回のアプリのような私的なメモ用途では徐々に実用的なレベルになってきたと感じる。そんなこともあって Todayeeシリーズの一つとして今回開発することにしてみた。



SFSpeechRecognizer


サンプルコード(多くは元ネタがAppleのやつ)が出回っているので実装自体は難しくない。API自体もシンプル。音声入力のために AVAudioEngine を入れるところが慣れないとわかりづらいくらいか。コールバックの処理はクロージャは使わずデリゲート(SFSpeechRecognitionTaskDelegate)を使った。そのほうが細かい制御ができるため。

この API は現状だとデフォルトで認識途中の文字列を返してくれるが(shouldReportPartialResults=true)、この時点ではまだ確定してなくて、話しかけていくうちに文脈に合わせて刻々と結果の文字列が変わっていく。この間は SFTranscription.segments: [SFTranscriptionSegment]  には十分な情報は入らない。ここに SFTranscriptionSegmentに substringや confidence などが入ってくるのは最後に確定した後(デリゲートだと speechRecognitionTask(task: didFinishSuccessfully:) 、クロージャでも同様の動き)。認識途中は話しかけた全内容が暫定的な文字列として渡ってくるだけ。

イメージ)こんな感じ

人間:「今日は」
暫定結果:「強は」
人間:「とても」
暫定結果:「今日はとても」
人間:「よい天気だった」
暫定結果:「今日はとてもよい」
暫定結果:「今日はとてもよい天気」
暫定結果:「今日はとてもよい天気だった」
確定:「今日はとてもよい天気だった」

開発者的には文節あるいは単語・句単位の情報が途中経過でも得られれば良いのだがそれはもらえない。毎回その時点での暫定の全文が渡される。

この点がインタラクティブに音声認識を扱いたいアプリにはイマイチなところ。ユーザと対話的に細かい制御をするには文字列処理で対応する必要がある。例えば、ユーザが発音した内容を単語・句として取り扱うには前回の文字列と今回の文字列を比較してその差分を取る。また取り消しの APIは今のところ提供されていないので、誤変換があってもそれを認識途中にインタラクティブに直すことが難しい。現状でも音声認識中にユーザが直前の単語・句を取り消すボタンを押すといったことは実装可能だが、アプリ側でできるのは文字位置を使うくらいしか方法が無いので最終的な認識結果が当初と変わるとうまく扱えない(文字位置がずれてしまうので)。認識中にインタラクティブに手を加えて行くには、変換途中と変換確定後を通じて単語や句をトラッキングできる仕組みが必要。いまはこれが無い。この点が現時点での APIの応用範囲を限定的にしてしまっていると感じた。


イメージ

人間:「今日は」
暫定結果:「京は」
人間:間違ってるじゃん。リテイク(仮)ボタンをポチして、再発音
人間:「今日は」
暫定結果:「京は今日は」
アプリ文字列:「今日は」(とりあえず開始のインデックスを +2としよう)
人間:「良い天気だ」
暫定結果:「京は今日は良い天気だ」
アプリ文字列:「今日は良い天気だ」
確定:「今日は今日はとてもよい天気だった」 ← 認識結果を最後に変えてしまった
アプリ文字列:「は今日はとてもよい天気だった」 あれ?


というわけで、iOS11ではこのあたりの改良を希望 =3


音声コマンド



これも音声認識APIを応用する上でやってみたかったことの一つ。実装してみると意外に楽しくてついついこの為に使ってしまったことも、単純なんだけどプチ未来感が感じられる機能。

この音声コマンドの実装は、大げさな仕組みは無くて実現方法はいたって簡単。コマンド(単語:例えば「送信」)の前後の空白時間を測ることで認識している。

(前回の認識)<-- t1 --> 「送信」 <-- t2--->

前回認識から t1秒すぎて、「送信」が認識され、さらにその後に t2秒の空白があったら「送信」をコマンドとして認識する。今後 APIの利用が進むともっと良い方法が出てくると思う(期待)。



あとがき


Voiceを作ってからというもののエバーノートへの投稿が格段に増えた。何かあれば起動して音声でつぶやく。手入力から音声入力への転換は思った以上に投稿のスタイルを変えるかもしれない。




アプリの入手は下記からどうぞ。







【アプリ】Todayee Rec 1.0 をリリースしました

2016年10月11日火曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第7弾「Todayee Rec」をリリースしました。音声を録音してエバーノートへ投稿できるアプリです。





11〜44kHz、モノラル/ステレオ、最大15分まで録音して送付が可能です。



再生もできます。


録音した音声はテキストを付けてエバーノートへ投稿できます。
エバーノートでの見え方はこんな感じ(PC版エバーノート)。
上から入力したテキスト、音声データ、下の薄い文字は録音時刻・時間とサンプリング周波数にチャンネル数。

設定画面はこう。



Todayeeの特徴である複数アプリ・デバイスからの投稿を1つのノートへまとめる機能も、もちろん健在です。
Todayee は複数のアプリ、複数のデバイスからの投稿をすべて1つのノートにまとめることができます。例えば下の図は Place と Pics からの投稿が1つのノートにまとまっている例です。

投稿は時刻で自動的にソートされます。


他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました
【アプリ】Todayee Extension 1.0 をリリースしました(無料)
【アプリ】Todayee Place 1.0 をリリースしました(無料)
【アプリ】Todayee Pisc 1.0 をリリースしました

開発メモ


グラフ


録音と再生は AVRecorderと AVPlayerという便利クラスがあるのであっという間にできた。問題はグラフ。ボタンと文字だけだと寂しいので音圧グラフは入れたかった。良いライブラリがあれば使おうと思ったが見つからなかったので結局作った。

まず音圧を格納する Floatの配列を作っておく(配列は先頭位置を変数で管理するいわゆるリングバッファとして実装しておく)。AVRecorder(もしくは AVPlayer)の peakPowerから NSTimerを使って定期的に値を取得してこの配列へ入れておく。次に専用のビューを作り、配列の中身を取り出して順番に取り出してプロットする。最後にその点の間を線で結べばできあがり。グラフはこんな感じ。
なんとなくそれっぽくなった (´・ω・`) 点と点はそのまま結ぶと山に角が立ってギザギザになる。滑らかにつながるように UIBezerPathの addQuadCurveを使って曲線を描てある。




(地獄の)Swift3対応


それよりも一番手間がかかったのは Swift3対応。とにかくこれには難儀した。前作の Picsのリリースができた直後の9月終わりから Todayee全体の Swift3対応に取り掛かった。その時には Recもほぼできていたが、Swift3対応してからリリースすると決めてひたすら Swfit3対応に励んでいた。

Swift3はそれまでの Swift2とはライブラリ体系が変わったことに伴い、文法はそれほど変わっていないにもかかわらず、移行作業がかなり面倒だった。現在のSwiftは仕組み上同じバージョンの Swiftで書かれたプログラムで統一する必要がある。例えば Swift2系で書かれたライブラリを使っている場合、自分のプログラムだけ Swift3で書く、ということができない。この場合、ライブラリを 3へ上げるか自分のプログラムを 2で書く必要がある。Todayeeの場合は半分以上が自作のライブラリで、その多くが Objective-Cで書かれていた。Objective-C製のライブラリは Swiftのバージョンの制約を受けないためそのまま変更無しで利用することができた。問題なのは比較的最近 Swift2で書いた自作ライブラリ群。今後を考えて Swift3での開発を(固く)決めていたので、ここから自作ライブラリを一つ一つ Swift3へバージョンアップする作業に入った。なお幸いなことに自作以外の外部のライブラリで Swiftを使っているものは、作者が比較的早期に Swift3対応してくれていたので自分でそれらに手をいれるという事態は免れた。これはラッキー。

自作ライブラリの書き換えができたら、次はそれらを CocoaPodsで Todayeeへ組み込む作業。これがまたよくわからないエラーが色々出て悩まされた。一歩進んではエラーが出て止まるという、まるで地雷原を進む気分。この地雷原を辛抱強く一歩一歩進み、問題を潰して行くとようやくライブラリの組み込みに成功するところまできた。でも、まだこれでは終わらない。

ここまで来てからようやく Todayee本体の Swift3対応。最初に 100近くのエラーが出ると目眩がしてクラクラしてきた。。コンバートをフル活用して一つ一つ確認しつつ手で潰していく。そんなこんなでようやく全部エラーが消えた。最後には Todayee Text が実機で動き出した。やった =3が、しかしそこで作業はまだ終わらない。

ビルドができて動くようになっても今度は動作上の互換性のチェックが残っている。いろいろ触って適当にボタンをタップするとクラッシュ。いろんなところでクラッシュ。もうやってられん。しかし仕方ない。今度は実機を握って一つ一つ問題を潰していく。

そんなこんなでようやく Todayee Text が問題なく動き始める。ここまで来ると山を超えた感じ。こうなると嬉しさよりも徒労感が強いんだが。。。

その後 Photo, Silent, .... とシリーズの一つ一つのアプリについて、ソースの書き換えと動作確認を繰り返した。そして先週末にようやく全部終わった。終わったー!
区切りがついて Recも動くようになったのでリリースにこぎつけることができた。

移行中は別のアプリ(EverGear)の対応もやっていたので、それを除くと正味1週間くらいか。あとから見るとこんなものだが、先が見えない作業は結構ストレスだった。それでもこのタイミングでやってしまえてよかった。今後は新しいアプリに専念できる。





あとがき


Recは比較的短期間でできた。実装自体は正味1週間くらいで、その後のデザインや効果音付けやパラメータの調整に少々時間がかかった印象がある。だから Rec自体は苦労した感じはしない。それよりも途中に入った Swift3対応がとにかく疲れた。Todayeeはそれでもまだ小さな規模なアプリだからこの程度で済んだけど、いっぱしのアプリだとこんなものでは済まなくて死ぬだろうな。。
ところで並行して手を入れていた EverGearは Objective-Cで書かれていて、こちらは Xcode8でまったく修正無しでビルド&動作した。TodayeeのSwift3移行はいったいなんだったのか。。。

_人人人人人人人人人人人人人人人人人_
>     Objective-C 最強!     <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄




さて次のアプリは Todayee Voice (シリーズ8作目)を予定しています。
10月下旬から11月上旬のリリースを目指して鋭意開発中です。
このアプリから iOS10以上対応になります。
(その点と名前から内容を想像してみてください。アレです。)


他も順次開発予定中です。年内目標を立てていてシリーズ10作を考えています。行けるかな。

お楽しみに =3



アプリの入手は下記からどうぞ。






【アプリ】Todayee Pisc 1.0 をリリースしました

2016年9月27日火曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第6弾「Todayee Pics」をリリースしました。カメラロール内の写真をエバーノートへ投稿できるアプリです。

【リリース記念】期間限定無料ダウンロード提供中です(2016/09/27時点)




最大100枚までの写真をアップロードすることができます。

デフォルトでは当日のノートにすべての写真が追記されるようになっています。


ビューアモードで写真をめくって選択することもできます。

1日分の写真は日付右のボタンでワンタッチ選択できます。


一度投稿した写真は薄めに表示されます。



エバーノートでの見え方はこのようになります。
Todayeeの引用形式で写真の日時と場所が入ります。
(日時の形式は設定画面でカスタマイズできます)


投稿には2つのモードがあって切り替えることができます。

デフォルトは「本日のノートへ投稿」。これを切り替えて「撮影日のノートへ投稿」を選ぶと、その説明の通り過去の該当日時のノートに追記されます(ノートがなければ作成されます)。例えば 9/1, 9/2, 9/5 の写真を選択して投稿すると、9/1, 9/2, 9/5 のノートにそれぞれ追記されます。同じ日に複数の写真があればもちろんその当日のノートにすべてまとめられます。「撮影日のノートへ投稿」だと引用ではなく他のカメラなどと同じように撮影時刻の位置に追記されます。




Todayeeの特徴である複数アプリ・デバイスからの投稿を1つのノートへまとめる機能も、もちろん健在です。
Todayee は複数のアプリ、複数のデバイスからの投稿をすべて1つのノートにまとめることができます。例えば下の図は Place と Pics からの投稿が1つのノートにまとまっている例です。

投稿は時刻で自動的にソートされます。


他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました
【アプリ】Todayee Extension 1.0 をリリースしました(無料)
【アプリ】Todayee Place 1.0 をリリースしました(無料)


開発メモ


写真選択


以前 PicsEver というアプリを作る為に開発したライブラリ(LKImagePickerController)を利用したので写真選択UIの実装は楽だった。 Todayeeの UIにうまく溶け込ませる為に色の設定や一部の UI変更を行ったぐらい。この点、自作のライブラリはカスタマイズが容易なのがいい。オレオレ仕様が容易に作れるのが最大のメリットか(その分面倒さもあるが)。ライブラリの利用とTodyeeプラットフォーム上での開発とあいまってUIに関する実質的なコーディングは少なかったと思う。ライブラリの利用はこれで2回目なので元は取れたかな。ただこのライブラリのモデルライブラリ(LKAssetsLibrary)は ALAssetsLibraryを使っているのでどこかで PHPhotoLibraryへ書き換えねば。

Evernote API の壁


Picsを作る前からずっと課題だったのが Evernote API の制限。1時間当たりの呼び出し回数には上限があって、それを超えるとすべての API呼び出しがエラーになる。こうなると時刻が変わるまで待つしかない(今が 15:34なら 16時まで待つ。16時になると回数が一旦リセット)。感覚的にはこの呼び出し回数は以前に比べてだいぶ改善したように思える。ただそれでも Todayeeの性質上(*)、100枚の写真を送るにはこの上限は少ないので何らかの対策を行う必要があった。
(*) Todayeeは追記を行う為に投稿を行う前に最低1回は前回のノートを呼び出す必要がある。

そこで今回は Todayeeプラットフォームの投稿処理に大幅に手を入れて、同じ日の複数の投稿を1回の処理(API呼び出しは2〜3回)で行うようにした。少々やっかいな修正ではあったが、そのかいあって1日のノートへ 100枚の写真を投稿するのは余裕でできるようになった。いろいろな試行錯誤の結果、現在は同日の投稿を最大4つまとめて送信するようになっている。この修正は今回の Picsだけでなく他の Todayeeアプリでも今後のバージョンアップ後に同じ恩恵を受けられるようになる(プラットフォームバージョン 1.2以上)。なお APIの呼び出し上限はなくなったわけではないので、同じ時間内で繰り返し大量の送信を行ったり、複数の日への投稿を繰り返すとこの上限でエラーになることはある。実用上は問題無いと思われるが、もしこれが出たら次の時まで待つ必要がある。






あとがき


ようやくこれで基本機能(テキスト、カメラ、写真取り込み)が揃った。前述の通り UIはライブラリを使えば比較的簡単に実装できるとわかっていたが、Evernote API 呼び出し制限の件がやっかいでずっと後回しにしていた。今回これを回避するうまい実装ができたことで Picsがリリースできたのはもちろん、これまでと今後の Todayeeアプリの性能の底上げができたのは結果として良かった。


Todayeeシリーズはこれからも毎月を目処に新作を提供して行きます。

・Rec(鋭意開発中)... こんな感じ↓
来月出します。お楽しみに。

他も順次開発予定中です。
・Video
・Viewer


お楽しみに =3



アプリの入手は下記からどうぞ。





【アプリ】Todayee Place 1.0 をリリースしました(無料)

2016年8月26日金曜日 | Published in | 1 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第5弾「Todayee Place」をリリースしました。無料です。



iOS標準のマップを利用したアプリで、表示しているマップ画像をそのままエバーノートへ投稿することができます。



この状態で投稿するとこうなります。


3Dにも対応していてこんな投稿もできます。

場所の検索にも対応。



検索結果を投稿すると住所や、サイトがあればそのURLが引用形式で投稿されます。


Todayeeの特徴である複数アプリ・デバイスからの投稿を1つのノートへまとめる機能も、もちろん健在です。

他の Todayeeシリーズのアプリと一緒に使っていけます。下は Place と Photo からの投稿が1つのノートにまとまっている例です。




他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました
【アプリ】Todayee Extension 1.0 をリリースしました(無料)

開発メモ


MKMapView のスナップショット


MKMapSnapshotter という名前のまんまの便利なクラスがあるのでこれを使った。ただし Annotationは含まれないので、これは最後に UIImageで合成してやる。地図上のAnnotation位置(緯度経度)と UIImage上の位置(x,y)を合わせる必要があるが、その用途の為のメソッド pointForCoordinate() を使えば容易に変換できて位置決めできる。スナップショットのオプションは MKMapSnapshotOptionsという関係クラスで定義しておくが、これには cameraプロパティもあって、これを使うと 3D表示した状態のスナップショットが撮れる。


MAP画像の投稿


Placeは技術的な課題はまったく無いと言ってよく、それよりも一番心配だったのは MKMapViewのスナップショットをエバーノートへ投稿するアプリが審査に通るかという点。もしかしたら審査が通らずアプリがお蔵入りになる可能性に怯えつつ、とにかく審査に出してみないことには進まないと考えて開発してきた。そのため最初のバージョンはできるだけシンプルにして審査の状況確認だけを取ることを念頭にスピードを重視した、と当初は考えていたけれどそんな風にはうまくは進まない。作っているとどうしても色々盛り込みたくなるし、あまりにショボいのは気が引けるし、ということで結局通常どおりの開発にはなってしまった。。それでも Todayeeプラットフォーム上での開発なので1ヶ月と短めではあったけど。審査に向けては 1.エバーノート投稿画像には著作権リンクを付与、2.アプリ説明には標準APIを使っていることを強調、と少しでもリジェクトを避ける努力もした。そのかいあってか(?)審査自体は2日で通過、本日無事にリリースできた。これにはホッとした。


場所検索


当初 Yahoo! ローカルサーチAPIを検証していたが、Google Place API を試したところ検索結果はこちらの方が良い感じがしたので切り替えた。検索結果は若干謎な感じも残ってはいるが日本以外も対応しているので使い勝手は良い。検索結果に出てくるアイコンはいつもの icon8 から調達した。Place API ではアイコン画像も提供されているのだが、これはデザインがイマイチなので面倒でもカテゴリ(typeと呼ばれる)毎に一つ一つ自分でアイコンをピックアップして割り当てた。

Place API は諸事情から iOSライブラリを使わず WebAPIを使っている。そのため JSONのパースとモデルクラスの用意が必要になった。このあたりは Unbox というライブラリを使った。変なクセもなく使い勝手は良かったと思う。

JohnSundell/Unbox


データ用のクラスは JSONExport という Mac用のアプリを使った。

Ahmed-Ali/JSONExport

これは便利。ただし用意されいてるテンプレートの用途は限られているので Unboxで使うためには生成されたクラスをちまちま書き換えていく必要はあった(それでも1から作るよりはぜんぜん楽)。




あとがき


エバーノートに記録を残す上でずっと作りたかったアプリだったのでリリースできたのはうれしい。元々は地図だけの Map と場所情報の Placeと別々のアプリの開発を進めていたのだけど、Placeは結局地図が必要になるしMapは地図だけだと機能がショボいので最終的には統合して Placeになった。結果としては良かったかと思う。今後は Flyoverにも対応してみたい。

Todayeeシリーズはこれからも毎月を目処に新作を提供して行きます。お楽しみに。

今後考えているもの
・Pics
・Rec
・Video
・Viewer



アプリの入手は下記からどうぞ。無料です。





【アプリ】Todayee Silent 1.0.1 バージョンアップ

2016年7月29日金曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Todayeeシリーズのカメラアプリ Todayee silent をアップデートしました。

変更の大きな点は、非マナーモードでシャッター音が鳴るところ。最初のバージョンでは完全無音で審査が通ったが2回目ではダメだった(PLA 3.3.8 というやつに引っかかった。これは被写体に撮影していることを知らせる条項)。単純にシャッター音を復活させるとこのアプリの存在意義が無くなってしまうため、少し悩んだあげく非マナーモードのみ 単純に AVAudioPlayerでシャッター音の .aif ファイルを再生するようにしてみた。その結果、無事に通過。実際にはもう一点指摘があって、スクリーンショットに入れていたテキストの「無音」を消すようにとの指導もあった。そこは別のテキストで置き換えた。そんなこんなで、ここ数日で3回ほど申請と却下を繰り返したあげくようやく今朝リリースできた。

ということで当初特徴としていた「無音」という文字は意図的に消している。一応、音量を絞るか、マナーモードにすれば音は鳴らなくなるので希望する方はそれを使って下さい。くれぐれも悪いことには使わないようお願いします(ちなみにカメラを上に向けると撮影できなくなってる)。

関連ブログ

【アプリ】Todayee Extension 1.0 をリリースしました(無料)

2016年7月28日木曜日 | Published in | 1 コメント

このエントリーをはてなブックマークに追加

Todayee シリーズ第4弾「Todayee Extension」をリリースしました。無料です。



iOSのシェア機能を利用してEvernoteへ投稿を行うアプリです。他のアプリで↑ボタンを押すと Todayeeアイコンが出てきます。


これをタップするとダイアログが表示され投稿することができます。


シェアボタン利用が中心なのでアプリ自体は設定画面のみ。


テキスト・URL・画像(1枚)が投稿可能です。カメラロールの写真はもちろん、SafariやRSSリーダー、メッセージなどで気になる情報があった時のURLの簡易クリップアプリとしても使えます。

投稿したテキストは左に線が表示される引用スタイルとなります。またURLは「リンク」という文字のリンクとなります。
以下、投稿例です。




Todayeeの特徴である複数アプリ・デバイスからの投稿を1つのノートへまとめる機能も、もちろん健在です。

他の Todayeeシリーズのアプリと一緒に使っていけます。


他の Todayeeアプリの記事

【アプリ】Todayee Text / Photo 1.0 をリリースしました
【アプリ】Todayee Silent 1.0 をリリースしました

開発メモ

ExetnsionからのEvernote投稿


初の Share Extension 開発は何箇所かでハマった。最初は Evernoteの投稿。Extensionを使う場面で認証させるわけにはいかないので、先に本体(Containing App)で認証した後にそれをExtension側で使うようにする必要がある。ただ本体アプリとExtensionは別々のアプリとして動作するのでそのままでは認証情報はもちろん、設定情報(NSUserDefaults)が両アプリ間で共有できない。幸い Evernoteの SDKには KeyChainグループを指定できるメソッド(ENSession.setSecurityApplicationGroupIdentifier)が用意されていたので、両アプリで共通のグループを設定することで認証情報を共有することができた。

Keychain Sharing


NSUserDefaults


NSUserDefaultsには NSUserDefaults(suiteName: name) というコンストラクタがあって、ここに両アプリで共通の文字列を入れておくと Containing App と Extension の間でデフォルト設定を共有することができるようになる。

なお前提として App Groups を1つ作っておいて、本体(Containing App)とExtension 両方で使えるようにしておく必要がある。



画像の NSExtensionItem


他のアプリ(Host App)から渡されるデータは NSExtensionContext を経由して取得することができる。面倒なのはデータの渡し方が元アプリによってまちまちなこと。例えば確認できているだけで画像の渡し方は3通りあった。
NSExtensionItem の実体:
・UIImage
・NSURL(file://で始まる画像の置き場所)
・NSData
これらはすべてデータのタイプが kUTTypeImageなので、実行時に NSExtensionItem の型を判定してそれぞれ処理してやる必要がある。アプリによっては UIImageを渡し、さらに kUTTypeURL で別に file://なNSURLを渡してくるものもあった(これはどうかと思うが)。


Extension で UIAlertController / ViewController


Extensionでは実行中に普通にUIAlertControllerが使える。Todayee Exntesionではエラーや注意メッセージを出すのに使っている。注意点はメインスレッドで呼び出すところ。
                    dispatch_async(dispatch_get_main_queue(), {
                        let controller = UIAlertController(title: ...
                        controller.addAction(UIAlertAction(title: ...

                        self.presentViewController(controller, animated: true, completion: nil)
                    })

同様に必要なら ViewControllerを作り画面を覆うような UIも作れる(同じくメインスレッドで)。Evernote投稿中に少し時間がかかりその間画面が固まってしまうので、このアプリでは ActivityIndicatorを表示するのに使っている。


起動後に説明画面


ネット上の情報で Extensionメインのアプリの場合、本体に操作方法の説明が無いとリジェクトされるとのことだったので、起動直後にヘルプのページを表示するようにした。


ビルドエラー


Extension にはいくつか制約があって、その中の一つに UIApplication の使用禁止がある。これが困るのは Extension でサードパーティのライブラリを使っていて、かつそれが UIApplicationを使っているケース。こんなエラーが出る。


このエラーを回避する為には、使っているライブラリのビルド設定で " Require Only App-Extension-Safe API" を YES → NO に変えてやれば大丈夫。


アップロードエラー


最後にハマったのが AppStoreへのアップロード。Xcodeのオーガナイザでいつものようにアップロードするとエラー。

リトライということなので、数日時間を開けてなんども実行。が、同じエラー。これはおかしいと思い調べたところ App Uploaderを使うと良いとの情報があったので使ってみた。ちなみに App Uploaderは Xcode7のメニューから呼び出す(知らんかった)。

App Loaderを使うともう少しマシなメッセージが出てきた。

調べると Extensionや Frameworkで CocoaPodsを使う時の既知の問題らしく、対処としては Extensionフォルダ内にできる Frameworksフォルダをビルドの最後に削除すること。※最後のWARNINGは Containing App と Extensionの Build番号(BundleVersion)が一致しない為のメッセージ。

そこで下記をExtension側の Build Phase の Run Scriptへ追記して実行したところ確かにエラーが減った。

が、まだ最後の1つが消えない。

スクリプトに ls > /tmp/ls.txt など追加して状況を調べるがディレクトリはあっていて Frameworksは存在する(ので、rm -frで削除されるはず)。原因は結局わからず時間ももったいないので、今回は自分で消すことにした。オーガナイザから作成した Archiveビルドをファインダで表示し、Extension配下の Frameworksを手で削除した。それをアップロードしたところ無事に完了。うまくいったので、まあこれでいいや。


あとがき



申請まで持っていくのに結構苦労させられたアプリだったが、申請自体は一発で通った。これはちょっとうれしい。今回もTodayeeプラットフォームがベースにあったのと、アプリの機能自体は少なかったので短期間で開発できたと思う。自分自身SafariやRSSリーダのURLを投稿するのに結構重宝している。

今後検討中のアプリ
・Place
・Pics
・Map
・Voice
・Viewer



アプリの入手は下記からどうぞ。無料です。





人気の投稿(過去 30日間)