ツイートを動画コメント風に表示するMacアプリ「ついこめ」をリリースしました


どんなアプリ?

  • Twitterの検索結果を、ニコニコ動画の様なコメント形式で表示するアプリです。
  • 勉強会等でのプレゼンテーションのとき、スライドにTwitterのコメントを流したり、動画を見るときにコメントを表示する、などに使用してみてください。

ダウンロードはこちら

紹介記事

開発期間ときっかけ

技術的な話

コメントの表示位置

  • コメントの表示位置(y座標)を完全にランダムにすると、整合性がなく見づらくなります。
    • また往々にしてテキスト同士が重なってしまいます。
  • そこで本アプリでは少しだけ工夫をしています。
  • まず画面サイズ÷テキストの高さ(1行分)を計算し、下記のように仮想的にスペースを分割します。
    • この計算は、文字の大きさやウィンドウの大きさが変わるごとに再度行います。
  • 後は仮想スペースの位置にランダムな順番にテキストを表示しています。
  • また複数行のツイートの場合、テキストが上に見切れてしまう場合があるので、その際は見切れた高さ分を下に移動させています。

  • ただしこれではテキストが重なる問題点は完全に解決されません。複数行のツイートの場合があるからですね。
  • 本家のニコニコ動画でどうやっているのかと調べてみた所、平行四辺形として捉えて計算しているそうです。
    • ニコニコ動画の仕組み - J-Stage
    • 具体的な実装に落とし込むのが難しそうなので、今回は見送っています。
    • ニコニコ動画を見ていると、コメントが少ない場合は上部中心に表示されるようになっていたりして、この辺のロジックは改善の余地がまだまだありそうです。

コメントのアニメーション

概要

  • コメントをスライドさせるためにはCoreAnimationを使用しています。
  • 開始前と開始後の状態、また時間を設定するだけでアニメーションを簡単に表現できます。
  • またアニメーションの完了時に呼ばれるメソッドが用意されているので、そちらでテキストオブジェクトの開放を行っています。
    • CAAnimationDelegateanimationDidStop
  • 注意点としては、macOS 10.13CoreAnimationがうまく表示されません。

参考

実装例

func shoeTextField(_ text: String) {
    // テキストフィールドの作成
    let textField = NSTextField(labelWithString: text)
    textField.translatesAutoresizingMaskIntoConstraints = false
    textField.sizeToFit()
    textField.wantsLayer = true  // CoreAnimationを有効にする

    // NSTextFieldの実体は見えない場所(Viewの下側)に配置している
    textField.frame.origin = NSPoint(x: view.frame.width, y: -textField.frame.height)
    view.addSubview(textField)


    // アニメーションの設定
    let movingHorizontallyAnimation = CABasicAnimation(keyPath: "position")  // positionに関してアニメーションを行う
    let yPosition = view.frame.height / 2 - textField.frame.height / 2       // 画面の中央の位置
    movingHorizontallyAnimation.fromValue      = NSPoint(x: self.view.frame.width , y: yPosition)  // 開始状態を設定
    movingHorizontallyAnimation.toValue        = NSPoint(x: -textField.frame.width, y: yPosition)  // 終了状態を設定
    movingHorizontallyAnimation.duration       = 5.0  // アニメーションの時間
    movingHorizontallyAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    textField.layer?.add(movingHorizontallyAnimation, forKey: nil)
}

Twitter APIの上限

概要

  • Twitter APIの検索リクエストの上限は下記の通りです(15分毎の値)
    • ユーザ認証型なので、180回/15分 -> 1回/5秒ですね

  • 正直に5秒ごとに取得を行い、ツイート時刻の差に応じて表示をしようとすると、画面に空白期間が生じてしまいます。
  • そこで取得するツイートを下記のように振り分けて、画面を5秒間保たせるようにしています。
    • 例:10ツイート取得した場合、0.5秒ごとに1ツイートを表示する

参考

設定画面に関して

概要

サンプルのメッセージを表示する

  • 設定画面を表示している際、常時サンプルのメッセージを表示するようにしています。
    • 検索結果がない場合に、設定値の変更が確認できないと不便だからです。
  • 細かい所かもしれませんが、使い勝手は良くなっていると思います。

移動時間変更時に画面をリロードする

  • 移動する速度はテキストの長さによって変化するので、設定値を変更した際に違いが分かりにくいです。
  • そのためテキストの移動時間を変更した際には、特別に画面を一度きれいにして、改めてテキストを表示するようにしています。

使用した外部ライブラリ

  • 外部ライブラリはCarthageで管理をしています。
    • SwifterCocoapodsに対応していなかった(できるという記事も見ましたがGitHub上には記載なしでした)ためです。
  • kishikawakatsumi/KeychainAccess
    • キーチェーンをUserDefaults感覚で使えるライブラリ。
    • TwitterAPI用のトークン情報を、セキュリティのためキーチェーンに保存しています。
  • mattdonnelly/Swifter
    • TwitterAPIを使用する際の認証・情報取得はこちらを介して行っています。
    • TwitterAPIの公式にて、Swiftのライブラリとして紹介されていたのでこちらを採用しました。

競合アプリを調べてみました

  • 世の中同じアイディアを考える人は多いもので、結構な数が見つかりました。
  • ただモックレベルの記事が多く、アプリとしてリリースしているものは少なかったです。
  • また(旬が過ぎているのか)長期間更新されず使用できなくなっているものも少なくありません。
  • 少し前にTwitterのライブラリに変更もあったことも影響しているのかもしれませんね。
  • また検索に引っかかるmacOSアプリは大体Electronで作成されています。(ネイティブでmacOSアプリ開発している人が少なくて寂しいですね…)
  • 本アプリの差別化の要素としては、画面をコメント部分とリスト部分の2つを用意している所かなと思います。

Twitter検索型と部屋型

概要

  • プレゼンテーションに聴衆のコメントを表示するツールは、下記の二通りに分類することが出来ます。
    • Twitter検索型:Twitterでの検索結果を表示する
    • 部屋型:発表者のスライド上にコメントを送るための、専用の部屋をWEBページ上に用意して、そこで入力されたコメントを表示する

Twitter検索型

  • 利点
    • 聴衆はTwitter(浸透度が高い)に投稿すればいいので、ハードルが低いです。
    • 聴衆はTwitterに投稿するだけでメッセージを送ることができます
      • 聴衆は勉強会に参加しているという記録が残せます
      • 勉強会や発表内容の宣伝になります
  • 欠点
    • 誰でも書き込めるので、質が悪い・もしくは不適切なツイートが流れる恐れがあります

部屋型

  • 利点
    • その場にいる人のみが書き込めるので、コメントの質が保つことができます
    • Twitterにコメントを残さずに済みます。(Twitterにコメントを残したい人もいるだろうし、人によるかな?)
  • 欠点
    • 聴衆に専用のWEBサイトにアクセスさせるのが、ややハードルが高そうです。

競合アプリと技術記事

最後に

  • Swiftの学習の一環として本アプリを作成しましたが、なかなか良い出来になったと思います。
  • 「プログラムを学習する際は何か作ってみるといい」というのはよく言われる話ですが、実際にその通りだなと思いました。
    • モックレベルでもいいですが、アプリレベルにしようとすると、得られる知見も大きいと思いました。
    • UXに気を遣う必要がありますし、些細な妥協もしにくいです。
    • ただし、その分の労力もかかるのでモチベーションが大切ですね。
  • 感想・要望等がありましたら、記事へのコメントやTwitterまで連絡をもらえると嬉しいです!