趣味プログラマによるOSS開発日誌

趣味で作っているOSSソフトウェアの紹介や関連技術の紹介、楽曲製作、Webデザイン勉強状況を紹介します。

Qiita投稿アプリ(9) GitHubへの公開

開発で気になっていた部分を作り終えて書くネタが無くなってきています。
・・・ネタ切れって辛いですね。
 
今回は開発が落ち着いてきて現在の開発物をGitHubに置いたので、その報告をします。
このブログの名前の通りOSSの開発日誌ということなので、私が作ったものは基本的にWeb上で公開しています。
今回開発しているアプリもその1つにしようと、GitHubに公開しました。


nutti/Doko-Demo-Qiita · GitHub

リリース前なのでmasterブランチは初期のままとなっています。
今回のアプリについて、branchを2つに分けてソース管理しています。
 
  • master
    アプリのバージョンを上げる時にpush

  • develop
    開発中に適度な間隔でpush、バックアップ的な役割
基本的にはdevelopでバージョン管理して、アプリが公開されたらmasterへmergeする感じです。
masterにpushされた時はバージョンも変わるので、tagを打つのと同時にGitHubのrelease機能を使って、GitHub内でリリースします。
 
公開するソースの範囲は、利用しているライブラリと自分で作成したソース一式です。
アプリで使用する画像ファイルや中間ファイルなど、PhoneGapが生成するファイルは対象外としています。
 
今回のアプリの場合、あまり公開するメリットが無いのかもしれませんが、公開することによって、実装仕方で参考になれたら良いなと思っています。
 
 

Qiita投稿アプリ開発(8) marked+highlight.jsで下書きの簡易プレビュー

先週末に実装した機能もこれで最後ですね。

面倒そうで一番開発に対して乗り気のなかった下書きのプレビューですが、もし自分がアプリを使う立場だったらと考えると、これは欲しいなと思いました。
投稿してから編集するのはおかしな話ですからね。
昔だったら妥協していていたと思いますが、最近ユーザに近いところで仕事をしているためか、多少は使う人を考えられるようになってきたのかもしれません。
 
作るとなれば実装の方針を決めないといけませんが、パーサの開発とかを一から作るのはやりたくないので、ライブラリを探すことにしました。
注目したのが、Qiitaの書式がMarkdown記法を採用していることと、そしてソースコードの部分がハイライトされてることです。
そこで「javascript markdown highlight」でググってみました。
そしたら以外にも簡単に見つかりました。
せっかくなので、ライブラリを簡単に紹介しておきますね。

marked

Markdown記法で書かれた文章をHTML形式に変換してくれるライブラリです。
ライブラリ本体は以下のリンクの先にあるmarked.jsです。
HTMLファイルにダウンロードしたJavascriptに追加することで、ライブラリが利用可能となります。
使い方も非常に簡単です。

highlight.js

こちらはソースコードに色付けを行うように文章を加工してくれるライブラリです。
ライブラリは以下のリンクから取得出来ます。
今回は多くのプログラミング言語に対応させたいので全て含めましたが、必要なプログラミング言語のみを指定することで、必要最低限の構成でライブラリを作成することも出来ます。
HTMLファイルにダウンロードしたJavascriptを追加することで利用可能になります。
こちらも使い方が非常に簡単で、以下のコードを実行するだけです。

下書きのプレビュー

markedとhighlight.jsというライブラリについて紹介しましたが、いかがでしょうか。
Qiitaの下書きをプレビューする機能を作るのが簡単そうに思えてきませんか?
それでさっくりと作ってみました。
そして動作させて見ました。動きました。
・・・はい。非常に簡単でしたね。
やはり先人達が作成したライブラリの力は偉大だったようです。
 
 
あっけなく実装出来てしまったので、あとは細かい動作の実装とデザインくらいしか残っていません。
ようやく完成が見えてきているので、そろそろスクリーンショットでも公開したいですね。
 

Qiita投稿アプリ開発(7) OAuth認証

InAppBrowserの問題をクリアし、OAuth認証の完成まであと少しという段階です。

しかし!
Qiitaの公式にOAuth認証の最後のアクセストークン取得のドキュメントが無いというとんでもない状況に遭遇です。
ドキュメントが無いといくら認証の手順を知っていてもお手上げですが、何とかなったので今回は苦労したQiitaのOAuth認証について振り返ってみます。
 

OAuth認証とは

OAuth認証は別に最近出来た認証方式ではなく、有名どころではfacebooktwittergoogleなどで採用されています。
アプリ連携しますかと聞かれるあれです。
OAuth認証を利用することで、認証のために必要なデータ量を最小限にできるので、情報漏洩しにくいので最近はBasic認証よりも使われることが多いらしいです。
 
QiitaもAPI v2からOAuth認証を採用し始めていて、

Qiita投稿アプリ開発(4) Qiita APIのバージョン - 趣味プログラマによるOSS開発日誌

の記事でも書いたとおり、QiitaでもOAuth認証を推奨しているそうです。
 

OAuth認証の流れ

まずOAuthって何ぞやということで、

OAuthプロトコルの中身をざっくり解説してみるよ - ( ꒪⌓꒪) ゆるよろ日記

を参考にOAuth認証についての勉強から始めました。
思ったより煩雑だなと感じつつ、最後まで流し読みし、なんとなく理解出来たところでQiitaのドキュメントを見ながら認証の手順確認します。
ざつくりと考えたのが以下の手順ですが、かなり省略しています。
今後Qiitaに手順をまとめる予定です。
  1. Qiitaでアプリケーションを登録し、生成されたClient IDとClient Secretを確認する
  2. https://qiita.com/api/v2/oauth/authorize?client_id=(Client ID)&scope=read_qiita+write_qiita&state=(任意の16進数)のURLを開く
  3. 認可された時に1.で登録したリダイレクト先のURLに飛ぶので、URLのクエリであるcodeの値を取得する
  4. Client ID, Client Secret, codeを使い、https://qiita.com/api/v2/access_tokensへPOST送信する
  5. POST送信が成功した時に得られるアクセストークンを保存する
  6. これ以降は、アクセストークンをHTTPリクエストヘッダに含めてQiita APIを叩くことで、Qiitaに対して様々な処理を行うことが可能

ドキュメントの不足

手順通り行けば良いのですが、たいてい何かしら問題が出るのは、開発では良くあることですね。
 
今回問題となったのは、Qiita APIのドキュメントに必要な情報が不足しているという何とも素晴らしいものでした。
Qiitaの公式ページにAPIのドキュメントが公開されていますが、v2についてはかなり断片化されていて、すでにここで初心者お断りな状態です。
特にアクセストークンを取得するところなんかは、送信する情報と受け取れる情報が書かれていない素晴らしい状態で、ドキュメントだけを見て実装することはほぼ不可能ですね。
以下の説明を見ていただければ、その素晴らしさが分かるのではないでしょうか。
GET /api/v2/oauth/authorize
アクセストークンを発行するには、アプリケーションのユーザに認可画面を表示する必要があります。ユーザがアプリケーションからのアクセスを認可すると、アプリケーション登録時に指定されたURLにリダイレクトされます。このとき、リダイレクト先のURLクエリにcodeが付与されます。また指定した場合は state も付与されます。アプリケーションでは、この code の値を利用して POST /api/v2/access_tokens にリクエストを送り、アクセストークンを発行します。
うーん、よくわからん。
手当たり次第確認するのも面倒だし、ここで諦めたくはなかったので、他にQiita APIを使ったプログラムがないか調べてみると、こんな記事がありました。

qiita-js/schema.yml at master · increments/qiita-js · GitHub

ドキュメントを作る前段階のものと思えますが、requireにアクセストークンの取得に必要となりそうものが書いてありました。
    links:
    - description: 与えられた認証情報をもとに新しいアクセストークンを発行します。
      title: create_access_token
      method: POST
      href: "/api/v2/access_tokens"
      rel: create
      schema:
        properties:
          client_id:
            "$ref": "#/properties/access_token/properties/client_id"
          client_secret:
            description: 登録されたAPIクライアントを認証するための文字列です。
            type: string
            pattern: "^[0-9a-f]{40}$"
            example: 01fc259c31fe39e72c8ef911c3432a33d51e9337ff34c4fac86c491a0d37251f
          code:
            description: リダイレクト時に付与される、アクセストークンと交換するための文字列です。
            type: string
            pattern: "^[0-9a-f]{40}$"
            example: fefef5f067171f247fb415e38cb0631797b82f4141dcdee66db846c3ade57a03
        required:
        - client_id
        - client_secret
        - code
これをベースに以下のコードを試したところ、OKが出たのでアクセストークンを得るために送信するデータは間違っていないようです。

PhoneGap Get OAuth's access token in Qiita


さらに今回はこれだけではありませんでした。
こちらはもっと素晴らしく、取得したデータからアクセストークンを取り出す方法がドキュメントに書かれていませんでした。
アプリケーションでは、この code の値を利用して POST /api/v2/access_tokens にリクエストを送り、アクセストークンを発行します。
見てください!
このシンプルイズベストな記事を!
この情報だけで実装出来る人は開発者か超能力者か運が良い人でしょう。
 
私はどれにも当てはまらないので、先ほどのドキュメントの下書きらしきものを再び見て見ました。
すると以下のように書かれていました。
properties:
  access_token:
    title: アクセストークン
    description: APIリクエスト時に認証を行うためのアクセストークンを表します。
    properties:
      client_id:
        type: string
        description: 登録されたAPIクライアントを特定するためのIDです。40桁の16進数で表現されます。
        pattern: "^[0-9a-f]{40}$"
        example: a91f0396a0968ff593eafdd194e3d17d32c41b1da7b25e873b42e9058058cd9d
      scopes:
        type: array
        description: このアクセストークンに許された操作内容を表します。文字列の配列で表現されます。
        items:
          type: string
          example: 'read_qiita'
      token:
        type: string
        description: アクセストークンを表現する文字列です。40桁の16進数で表現されます。
        pattern: "^[0-9a-f]{40}$"
        example: ea5d0a593b2655e9568f144fb1826342292f5c6b7d406fda00577b8d1530d8a5
tokenというのがアクセストークンらしさを出しています。
そこでこのトークンを使って、以下のコードで投稿一覧を取得してみると・・・取得出来ました!
一時はどうなることかと思いましたが、情熱が通じたのでしょうか。
なんとかなるものですね。
 
いろいろと大変でしたが、アクセストークンが得られた時は、独学でプログラミングを勉強して動作した時の嬉しさを久々に味わえた気がします。
そして、今回の件でドキュメントが重要だと改めて感じました。
特にAPIでドキュメントが無い状態というのは、APIが無いのと同じであることと同じですね。
 
折角なので今回の話題をQiitaに投稿し、ドキュメントが不十分であることをサポートにも伝えておきましょうかね。
 

Qiita投稿アプリ開発(6) InAppBrowserの不具合?

休日は趣味のDTMとアプリ開発に明け暮れていました。

ちなみに、Qiita投稿アプリ開発の進捗はかなり順調です。

OAuthの認証は無事実装でき、本来なら作る予定のなかった下書きのプレビュー機能まで完成しました。
休日にやったことを1回の 記事で書くのにはあまりに多すぎるのでので、ポイントごとに分けて書いていきます。

OAuth認証

最初のポイントは前々から気にしていたOAuth認証の実装です。
OAuth認証の実装は初めてだと前の記事で書きましたが、実は知らず知らずのうちに過去に行っていたことを調査するうちにわかってきました。
昔実装した時は、OAuthの認証自体知りませんでしたが・・・。


PhoneGapからDatabase.comに接続する - 趣味プログラマによるOSS開発日誌

それでこれを参考にすれば良いのではないかと実装を始めたのですが、見事に別のところでハマりました。
OAuth認証実装の大まかな流れは、以下のようにしています。
  1. Qiitaの設定画面から、「アプリケーション」-「登録中のアプリケーション」と進んで、以下を入力。
    • アプリケーションの名前
    • アプリケーションの説明
    • WebサイトのURL
    • リダイレクト先のURL
  2. InAppBrowserをインストール・設定
  3. Qiitaのドキュメントに従い、InAppBrowserを用いてアプリの認可画面を開く
  4. InAppBrowserに、アプリが認可された時のイベントを捕捉するように設定
  5. イベントを捕捉したら、InAppBrowserで開いたアプリの認可画面を閉じる
  6. イベント捕捉時に得られた情報を利用し、アクセストークンを取得する

問題箇所

今回問題が生じたのは手順5.で、イベントを捕捉できないという問題でした。
ここのイベントというのは、アプリが認可された時のイベントです。
イベントの捕捉設定のソースコードですが、具体的には以下のコードで行います。
ユーザーがアプリを認可すると、手順1.で設定したredirect URLに飛ばされるため、ページ遷移が開始された時のイベントを取得し、遷移先のURLがredirect URLのものかを確認しています。
URLが遷移先のものであれば、ユーザが認可したことを示しているため、手順6.に移るという流れです。

InAppBrowserの問題

今回問題となったのは、まさしくこのイベント取得でした。
認可してredirect URLに移動しても、InAppBrowserで開いたページが閉じないのです。
色々デバッグをしてみると、イベントを取得した時の処理が行われていないことがわかりました。
イベントには、loadstart, loadstop, loaderrorなと様々なものがあるのですが、どのイベントも取得できない状態です。
そこで同様の問題がないかググって調べていたところ、PhoneGapはバージョンアップした後が不安定らしく、あまり良くない噂があるそうです。
もしかしたら、ということでInAppBrowserのイベントが正常に行えていたバージョンを見てみます。
正しく動作していたバージョン: 0.5.4
現在のバージョン: 0.6.0
はい、見事に違いますね。
メジャーバージョンが変更されているのでそれなりに大きな変更があったのかもしれません。
 
そんなわけで、バージョン0.5.4のInAppBrowserをインストールして動作確認することにしました。
昔のバージョンのプラグインのインストール方法はQiitaにまとめていますので、参考にしてみてください。


[PhoneGap] 古いバージョンのプラグインをインストールする方法 - Qiita

プラグインをインストールして、ビルドしてシミュレータ起動して、認可画面でアプリを認可すると・・・何の問題もなく動作しました!
PhoneGapのバージョンにまつわる問題はまだまだ残っているようですね。
今後PhoneGapを使っていくにあたり、PhoneGapやプラグインのバージョンに気をつけて開発を行う必要がありそうです。
 

参考情報

Qiita投稿アプリ開発(5) テスト投稿した記事の扱い

今回は開発とはあまり関係のない話題ですが・・・

 
デバッグなど、アプリを開発している時にテスト用の投稿を行うことは良くあることだと思います。
テスト用の投稿にはたいてい、testとかhogeといった内容だけで意味のない投稿となるのが普通ですね。
そのような投稿を公開したままにするのは問題で、たいていはテストが完了した時点で削除もしくは非公開にするべきです。
 
私もQiitaにテスト用の投稿をいくつか行い、アプリの開発に役立てていたのですが、それなりに長い期間公開されていたため、Qiitaから以下のようなメールが届きました。
 

f:id:nuttinutti:20150220214713p:plain

 
要約すると、テスト用の投稿と判断したから限定共有投稿にするよといった内容です。
Qiitaにはtestというタグがあり、そのタグに紐付けしたからかもしれませんが、Qiitaのサービス自体が無利益な投稿を非公開にしてくれるのは非常に良いことだと思います。
少し調べてみると、テスト用の投稿以外として不適切な表現があった場合についても削除の対象となるようです。
 
自動で行っているのか、人手で行っているのかは分かりませんが、本来欲しくない情報がユーザに表示されないように運営されてるようで、ますますQiitaを好きになりました。
よりたくさんの人にQiitaを使ってもらえるよう、早くアプリを完成させたいですね。
 

Qiita投稿アプリ開発(4) Qiita APIのバージョン

Qiitaで利用可能なAPIには、v1とv2の2つのバージョンがあります。

これまでドキュメントの分かりやすさからv1を利用していたのですが、v2とどちらを利用したら良いか迷っていました。

そこで別件でも聞きたいことがあったので、思い切ってQiitaのサポートに聞いてみました。
すると1日後には返信があり、今後v1への機能追加は行わないということを非常に丁寧に教えていただきました。

今後v1のサポートが無くなることはあり得ますし、機能追加がないので下書きに関するAPIが追加された時に使えないのは困ります。
実際v1では、Qiitaへのアクセス権をユーザが自分で設定する必要があり、ユーザにとっては非常に手間のかかるものとなってしまいます。
さらに、TwitterGitHubのアカウントと共通した場合の認証が出来ません。
実際、Qiita関連のiPhoneアプリでも認証できないものがいくつかあります。
GitHubと共通アカウントとして使っている私にとってこのアプリが使えなくなるのは本末転倒ですので、v2への移行を決めました。

v2へ移行するために、v1で実装した時と同じくまずは認証部分の実装を行うことから始めました。
v2の認証には2種類あり、v1と同じくユーザ自身がアクセス権を設定する方法と、OAuth認証を用いた方法があります。

ユーザ自身がアクセス権を設定する方法では、Qiitaでアクセス権を発行することにより得られた、アクセストークンをアプリに入力してもらう必要があります。
開発者にとっては実装が楽で良いのですが、ユーザにとっては何の脈略もない英数字の羅列を数十文字分入力する必要があり、考えただけでも面倒です。

それに対してOAuth認証は簡単で、Qiitaで使用しているユーザ名やパスワードさえ入力すればユーザの認証が行えます。
また、GitHubTwitterとアカウントを連携させた場合についても対応が容易です。
ただし開発者にとっては負担が増えるのが問題です。

結局どちらの方法にするかですが、自分自身がこのアプリを使うことを考えた結果、OAuth認証とすることにしました。
しかしここで問題が発生します。
PhoneGapにおけるOAuth認証のやり方に対して、全く検討がつきません。
さらにネットにも情報が少ないので、試行錯誤しながらやるしかなさそうです。
まずはOAuthのJavascriptでの実装方法から勉強する必要がありそうですね。

文章力を向上させるために始めたこと

最近どうやったら文章力、特に技術的文章力(テクニカルライティング)が向上するか悩んでいます。

わかりやすく書いたつもりの資料を相手に見せると、まったく理解できないというフィードバックをもらうことが多く、改善が必要だなと思うようになりました。
また私が参考にしている、How To Become A Hacker: Japaneseにも以下のような記述があり、文章能力がハッカーの資質の1つとして書かれていますので、改善しないことなんて考えられません。
 
改善すると決まればさっそく取りかかりたいところですが、私の経験上アウトプットに対して何かしらのフィードバックがないと続かないことがわかっています
そこで、文章力の向上にブログとQiitaを活用できるのではないかと考えました。
 
ブログであればアクセス数がフィードバックになると思いますが、はてなブログはそれ以上にフィードバックを得る機会が多いと感じます。
はてなダイアリーから続く、はてなブックマークはてなスターブログの読者が非常に魅力的ですね。
さらにはてなブログからは、記事のtwitterへのツイート数など記事がSNSに投稿された数をより詳しく知ることができるようになり、フィードバック好きな人を意識してサービス展開してるのではないかと考えてしまうくらいです。
 
QiitaはQiitaとブログの使い分け方を考えてみた - 趣味プログラマによるOSS開発日誌で書いたように、ブログ以上にプログラミングに携わっている人にとってアウトプットしたものに対してフィードバックを得やすい場所だと思います。
記事に対するアクセス数もフィードバックの1つとしてありますが、何よりストック数が増えることで、全ての投稿に対するストック数を足したContribution数が増えることが非常に楽しいです。
 
Qiitaでは少し専門寄りな文章、ブログでは一般的な文章という感じで読者対象がそれぞれ異なるため、読み手を意識して書く習慣がつきやすそうです。
最初のうちは効果がわからないと思いますが、継続してこれらの場でアウトプットするようにしていきたいですね!