プチコンmkII プログラム PBR (Petit Book Reader) 用 Mac 版補助ツール ConvertPTC 公開

プログラミングコンテスト 第二回 プチコン大喜利 審査結果発表」
http://smileboom.com/special/ptcm2/co_contest/

第二回 プチコン大喜利の審査結果が発表されました。早速、QR コードを読み取りました。特に Gust Notch? さん作

★プロ生ちゃん特別賞★
PBR (Petit Book Reader)
作/ Gust Notch? さん
GN_PBR
GN_MKBL
青空文庫リーダー

の deflate アルゴリズム実装には驚きました。

最近 Twiitter などで公開されている QR コードを追いかけていませんが、それでも自分の作りかけのプログラムも含めると約360本ほどあります。どんなプログラムがあるのか、ほとんど忘れてしまいました。それで、Mac のメモに Twitter などの発言をプログラムごとにまとめてあります。これを PBR (Petit Book Reader) で読めたら便利だと思い、早速試してみました。

(Twitter の発言を公開するわけにはいかないので、ここでは OOGIRI_B.txt を使用しています。テキストファイル OOGIRI_B.txt は、第二回 プチコン大喜利の結果をまとめたものです。QRコードのファイル名、プログラム名も書いてあります。どんなプログラムがあったか確認するのに便利です。後ほど紹介するアプリ ConvertPTC に含まれています。PTC ファイル化されているので、Windows ユーザーでも利用できます。 )

テキストファイル OOGIRI_B.txt を文字コード : ‘日本語 (Shift JIS)’、改行コード : ‘Windows CR LF’ で保存し、ターミナル上で gzip コマンドを使って

~ $ cd Desktop/ConvertPTC
~/Desktop/ConvertPTC $ gzip -c OOGIRI_B.txt > OOGIRI_B.gz
~/Desktop/ConvertPTC $ 

上記のように GZIP 圧縮ファイル OOGIRI_B.gz を作成しました。

はずかしいのですが、最初は圧縮書庫形式を TAR 形式 + GZIP 形式

 $ cd ~/Desktop/ConvertPTC/
~/Desktop/ConvertPTC $ tar czvf OOGIRI_B.tar.gz OOGIRI_B.txt
a OOGIRI_B.txt
~/Desktop/ConvertPTC $ 

のように tar.gz に圧縮していました。また、圧縮したアーカイブ・ファイルを展開するには

GZIP 圧縮ファイルの展開

~/Desktop/ConvertPTC $ gzip -dc OOGIRI_B.gz > OOGIRI_B.txt
~/Desktop/ConvertPTC $ 

TAR 形式 + GZIP 形式の展開

~/Desktop/ConvertPTC $ tar xzvf OOGIRI_B.tar.gz
x ./._OOGIRI_B.txt
x OOGIRI_B.txt
~/Desktop/ConvertPTC $ 

以上のコマンドでできます。

後は、PBR (Petit Book Reader) のマニュアルに説明されている通り、

プチコン MkII 開発支援ツール DSPCBMP
http://www.aogondo.net/PetitCom/DSPCBMP/

DSPCBMP を使って PTCファイルに変換しました。ところが Mac と Windows 間でファイルをやり取りしているせいか正しく変換されていないようです。(私の使用方法に問題があるのかもしれません。)

そこで、Ruby で PTC ファイルに変換するプログラムを作ってみたのですが、私の技術力不足でなかなか思った通りの動作をしてくれません。それで思いきって Mac 用の PTC 変換プログラムを作ってみました。折角なので、テキストファイルをドラッグ・ドロップするだけで GZIP 圧縮し、PTC ファイル化するようにしました。十分な動作確認をしていないので注意してください。

下記 URL で公開します。

Gust Notch? さん作 PBR (Petit Book Reader) で読むことができる
GRP 形式  PTC ファイルを Mac 上で作成する
プログラム ConvertPTC。
http://kyoshiaki.sakura.ne.jp/osx/Sample/ConvertPTC.zip

注意) GRP: OOGIRI_B を GN_PBR で読み込む時、エラーが出ます。GN_PBR を修正する必要があります。 上記 URL の ConvertPTC.zip に含まれる ReadMe を参照してください。Windows ユーザーにも ReadMe を読めるように PDF 形式で保存した ReadMe も同封しておきました。

詳しくは、

【使用方法】
5) プログラム GN_PBR を修正。

を参照してください。

文章ファイルリスト MEM: BOOKLIST を編集すると PBR (Petit Book Reader) GN_PBRの 起動画面で、文書タイトルをタッチするだけで読み込むことができます。その方法も、上記 URL の ConvertPTC.zip に含まれる ReadMe

【Tips】
4) 文書ファイルリスト
GN_MKBL 

に解説してあります。

プログラミングコンテスト 第二回 プチコン大喜利 審査結果発表」
http://smileboom.com/special/ptcm2/co_contest/
技術賞
一分間戦争
作/ Ackieee さん
OMWAR
PDF 書類 manual-omwar.pdf
http://smileboom.com/special/ptcm2/co_contest/media/manual-omwar.pdf

に熱中しています。なかなか手強いですね。

プチコン 3号(仮称)
http://smileboom.com/special/ptcm2/html_third.php

ニンテンドー3DSプチコンが発表されました。近日発売だそうです。楽しみですね。

拙作 iPhone 用 RSS リーダー iYKRSS、iPad 用 RSS リーダー iYKRSSHD 無料公開、 iOS 用 Twitter アプリ作成方法

ちょっと宣伝です。拙作 RSS リーダー iYKRSS を iPhone 5 スクリーンで表示できるようにしました。また、iPadRSS リーダー iYKRSSHD を Retina ディスプレイに対応しました。

あらかじめ登録された芸能人ブログリストから RSS フィードを簡単に選ぶことができるので、RSS リーダーを使ったことがない初心者にもお勧めです。

iYKRSS、iYKRSSHD 共に無料です。ただし、iYKRSSHD は、9月になると 85 円に戻ります。iPhoneiPod touchiPad を持ってる人は、良かったら試しにダウンロードしてみてください。

使い方がわからない人は、気軽にコメントに書き込んでください。返事は、遅れるかもしれないのでご了承ください。

iYKRSS version 1.0.4
http://appstore.com/yoshiakikoyama/iykrss

iYKRSSHD version 1.0.2
http://appstore.com/yoshiakikoyama/iykrsshd

随分遅れましたが、前回、予告した iOS 用 Twitter アプリ作成方法を説明したいと思います。私自身、良く理解していない部分もあるので、間違いもあるかもしれません。

基本的に、下記 URL の REST API v1.1 を

REST API v1.1 Resources | Twitter Developers
https://dev.twitter.com/docs/api/1.1

使って Twitter のタイムライン情報などを取得します。REST API v1.1 を前回説明した GET、POST で送信するのですが、

Authorizing a request | Twitter Developers
https://dev.twitter.com/docs/auth/authorizing-request

上記、URL の

POST /1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog",
oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb",
oauth_version="1.0"
Content-Length: 76
Host: api.twitter.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

のように、認証情報 (上の Authorization: OAuth の部分) が必要です。OAuth を使って取得する必要があります。

しかし、iOS の場合、

 Using Reverse Auth | Twitter Developers
https://dev.twitter.com/docs/ios/using-reverse-auth

Reverse Auth を使って OAuth の情報を取得できます。取得の仕方は、

 seancook/TWReverseAuthExample · GitHub
https://github.com/seancook/TWReverseAuthExample

を参考にした拙作サンプル

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

に含まれています。 KeyDefines.h の

#define TWITTER_CONSUMER_KEY    @""
#define TWITTER_CONSUMER_SECRET @""

を設定してください。Consumer key、Consumer secret を使うには、

Twitter Developers
https://dev.twitter.com/

にログインして、自分のアイコンをクリックして表示されるメニューから ‘My applications’ を選び、’Create a new application’ ボタンをクリックして My application を作成する必要があります。

Sign in with your Twitter account | Twitter Developers
https://dev.twitter.com/apps

作成した application を選べば、Consumer key、Consumer secret は表示されます。

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

の TSViewController.m の Reverse Auth を呼び出している部分は、

TSViewController.m

- (void)awakeFromNib {
__unsafe_unretained TSViewController *me = self;
_accountStore = [[ACAccountStore alloc] init];
_apiManager = [[TWAPIManager alloc] init];
ACAccountType *twitterType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
_accounts = [_accountStore accountsWithAccountType:twitterType];
_account = [_accounts objectAtIndex:0];
NSLog(@"%@", _account);
NSLog(@"identifier: %@", _account.identifier);
NSLog(@"username: %@", _account.username);
if ([TWITTER_CONSUMER_KEY isEqualToString:@""]) {
NSLog(@"TWITTER_CONSUMER_KEY=\"\"");
[self requestApiTimeline:self];
//        [self requestApi:me];
} else {
[_apiManager performReverseAuthForAccount:_account withHandler:^(NSData *responseData, NSError *error) {
if (responseData) {
NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *parts = [responseStr componentsSeparatedByString:@"&"];
me.reverseAuth = [NSMutableDictionary dictionary];
//            NSLog(@"%@", responseStr);
for (NSString *line in parts) {
NSArray *array = [line componentsSeparatedByString:@"="];
[me.reverseAuth setObject:array[1] forKey:array[0]];
}
//            NSLog(@"%@", me.reverseAuth);
//
[me requestApi:me];
//                [me requestRawApi:me];
}
}];
}
}

[_apiManager performReverseAuthForAccount:_account withHandler:^(NSData *responseData, NSError *error) { です。

_apiManager に引数、ACAccount *account と最終的に呼ばれるブロックを渡し、performReverseAuthForAccount: withHandler: メソッドを呼ぶと

Using Reverse Auth | Twitter Developers
https://dev.twitter.com/docs/ios/using-reverse-auth

の最後にある下部

oauth_token=2311112785-EXKeLV5ezo3HHIaIf1T3ffeww0mR5dfYXKZjjRy0&oauth_token_secret=KYxxxxx3U4Fxrxva3BGD92--12ehEzFwQ&user_id=38895958&screen_name=theseancook

のような、oauth_token、oauth_token_secret、user_id、screen_name を NSData *responseData で返してくれます。ここで重要なのは、user_id を返してくれることです。実は、Reverse Auth を使わなくても、タイムラインを表示することができます。

    if ([TWITTER_CONSUMER_KEY isEqualToString:@""]) {
NSLog(@"TWITTER_CONSUMER_KEY=\"\"");
[self requestApiTimeline:self];
//        [self requestApi:me];

上の部分が TWITTER_CONSUMER_KEY が設定されていない場合、Reverse Auth を使わないでタイムラインを表示しています。

ただし、他の REST API v1.1 を使用するためには user_id が必要になってきます。

後は、簡単です。アップルが用意したフレームワークの SLReuest を使って Twitter API v1.1 を呼び出す汎用 API

- (void)performTwitterRequestAccount:(ACAccount *)account Method:(SLRequestMethod)method URL:(NSURL *)url parameters:(NSDictionary *)dict completion:(TwitterRequestHandler)completion

です。

- (void)requestApi:(id)sender {
//    url = [NSURL URLWithString:@"http://192.168.1.6:9090/1.1/lists/list.json"];
url = [NSURL URLWithString:@"https://api.twitter.com/1.1/lists/list.json"];
//    dict = @{@"user_id" : @"00000000"}; // user_id を設定してください
dict = @{@"user_id" : [self.reverseAuth objectForKey:@"user_id"]}; // TWITTER_CONSUMER_KEY を設定していないと使えません。
[self performTwitterRequestAccount:_account Method:SLRequestMethodGET URL:url parameters:dict completion:^(NSArray *json, NSURLResponse *response, NSError *error) {
NSLog(@"===< List >===");
//      NSLog(@"%@", json);
for (NSDictionary *list in json) {
NSString *text = [NSString stringWithFormat:@"<%@>\n  list_id:%@\n  slug:%@",[list  objectForKey:@"uri"],[list  objectForKey:@"id"],[list  objectForKey:@"slug"]];
NSLog(@"%@", text);
}
}];

で、- (void)performTwitterRequestAccount:(ACAccount *)account Method:(SLRequestMethod)method URL:(NSURL *)url parameters:(NSDictionary *)dict completion:(TwitterRequestHandler)completion を呼び出しているのがわかると思います。この場合、自分のリストを表示しています。

 url = [NSURL URLWithString:@"http://192.168.1.6:9090/1.1/lists/list.json"];

を有効にして、前回の GET、POST のように SLRequest がどんなデータをサーバーに送信しているのか確認することができます。

まず、ターミナルで

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

に含まれる server.rb を実行します。その後、TSTwitter.xcodeproj を開き、ツールバー上 Run ボタンをクリックします。画面が現れプログラムが起動し終えたら、Stop ボタンを押します。ターミナル上に実際の SLRequst がサーバーに送るデータが下図のように表示されます。

上図より、

Authorizing a request | Twitter Developers
https://dev.twitter.com/docs/auth/authorizing-request

上記 URL の

POST /1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog",
oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb",
oauth_version="1.0"
Content-Length: 76
Host: api.twitter.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

と似ているのが理解できると思います。SLRequest を使わずに NSMutableURLRequest で実現したのが

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

に含まれているソース

TSSignedRequest.h
TSSignedRequest.m

の TSSignedRequest

- (void)performTSTwitterRequestMethod:(TSSignedRequestMethod)method URL:(NSURL *)url parameters:(NSDictionary *)dict completion:(TSTwitterRequestHandler)completion {
- (void)requestRawApi:(id)sender {
- (void)performTSTwitterRequestMethod:(TSSignedRequestMethod)method URL:(NSURL *)url parameters:(NSDictionary *)dict completion:(TSTwitterRequestHandler)completion {

です。SLRequest と似ているので注意してください。TSSignedRequest を通常使う必要はありません。Twitter API の動作を確認するために、実験的に作ってみただけです。SLRequest を使ってください。

SLRequest を使うだけなら、Reverse Auth が必要ないと思うかもしれません。以前は ACAccount *account から user_id を取り出すことができたのですが、現在、Reverse Auth を使って user_id を取り出すしか方法がありません。

Twitter API v1.1 を試すには、Mac App StoreTwitter、ターミナル上で curl を使う方法があります。

Mac 上で動作する本家 Twitter アプリは、Mac App Store にあります。

Twitter
http://appstore.com/mac/twitterinc/twitter

上記 URL をクリックすれば表示されます。

Twitter をクリックして実行し、メニュー/Twitter/環境設定… を選び、ツールバーから ‘開発者’ を選択します。コンシュマーキー、アクセストークンを入力し、認証ボタンをクリックすると開発者メニューが有効になります。

試しに、メニュー/開発/コンソール を選び、ホームタイムラインを表示してみたのが下図です。

curl を使って試す方法は、まず、

Twitter Developers
https://dev.twitter.com/

にログインします。

REST API v1.1 Resources | Twitter Developers
https://dev.twitter.com/docs/api/1.1

を開き、呼びたい REST Api をクリックします。ここでは、GET statuses/home_timeline にします。
右側、OAuth tool で ‘Select one of your Apps’ から自分のアプリケーションを選びます。その後、Generate OAuth signature ボタンをクリックします。

表示されたページの Request URI: が正しく設定されているか確かめます。 Request query: に設定したいパラメーターを入力します。ここでは、count=2 と入力します。

この後、ページの一番下の See Oauth signature for this request ボタンをクリックします。

表示されたページの OAuth Signing Results に cURL command と名前の項目があります。右横にパラメーターがセットされた curl コマンドが表示されています。それをコピーして、ターミナルにペーストし実行すれば、生の JSON データを取得することができます。

自作 iOS 用 Twitter アプリ サンプル TSTwitter 公開、シンプルな Ruby 製 HTTP サーバーを使った GET、POST 解析。

iOS 用 Twitter アプリの作成方法について書こうと思っていたのですが、あまり時間がとれなかったので次回にしたいと思います。サンプルは、先に公開しておきます。

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

Twitter REST v1.1 API をコールし、結果を Xcode のコンソールに表示する簡単なプログラムです。( Social.framework を使用しているので iOS 6.0 以上で動作します。 )

xAuth、Apple 純正ソーシャルネットワークフレームワークの SLRequest、NSURLRequest で直接呼び出す TSSignedRequest など Twitter REST API をいろいろな方法で呼び出せるので便利です。初心者にも実用的なプログラムが組めるので、楽しめると思います。UITableView を使って本格的な Twitter アプリに仕立てるのも面白いと思います。

詳細は、次回に。

今回は、手始めとして REST の動作を学ぶため、 GET、POST の違いを解説します。

Ruby で簡単な HTTP サーバーを作り、Safari でアクセスし、表示されたフォームから GET と POST を使ってサーバーにデータを送信します。送られてきた生のデーターを表示してみます。

自作 iOS 用 Twitter アプリ サンプル TSTwitter
http://kyoshiaki.sakura.ne.jp/osx/Sample/Twitter.zip

GET、POST を使用する HTTP サーバーは、上記サンプルに含まれている server_get.rb、server_post.rb です。
server_get.rb は、Safari がアクセスすると HTML書式

<form method="get" action=".">
<p>Name:<br><input type="text" name="name" size="50"></p>
<p>Message:<br>
<textarea name="message" cols="50" rows="5"></textarea></p>
<p><input type="submit" value="Send"></p>
</form>

を送信します。

<form method="get" action=".">

の method を下記のように post に変更したものが

<form method="post" action=".">

server_post.rb です。

server_get.rb と server_post.rb の使用方法は、同じなので server_get.rb で説明します。

まず最初に、メニュー/アップルマーク/システム環境設定… を選び、’システム環境設定’ を開きます。
インターネットとワイヤレス/ネットワークをクリックします。

IP アドレスを確認します。ここでは、192.168.1.6 に設定されています。

テキストエディタXcode で server_get.rb ファイルを開きます。(Finder 上、またはドッグの中の Xcode アイコンにファイルをドラッグ・ドロップすれば開くことができます。)

# 5行目の
server = TCPServer.new('192.168.1.6', 9090);

上の ‘192.168.1.6’ の部分を確認した IP アドレスに置き換えてください。IP アドレスが 192.168.1.2 なら

server = TCPServer.new('192.168.1.2', 9090);

です。

/アプリケーション/ユーティリティ/ターミナル.app を起動し、server_get.rb があるパスまで移動し、./server_get.rb を実行して、HTTP サーバーを起動します。

~ $ cd Desktop/Twitter/
~/Desktop/Twitter $ ls
TSTwitter	server.rb	server_get.rb	server_post.rb
~/Desktop/Twitter $ ./server_get.rb
GET
Listening on port 9090

Safari で先程指定した IP アドレス、http://192.168.1.6:9090 にアクセスします。下図のように表示されます。フォームに Name: Yoshiaki、Message: Hello! と入力して ‘Send’ ボタンをクリックします。

Safari 実行画面

サーバーからの返答がないので、送信が止まりません。それで Safari の URL フィールド右端の ‘x’ ボタンをクリックして中止します。すると、ターミナル側に Safari から送信された生データーが次のように表示されます。(実際のデータには、文字列両端のダブルクォーテーション ( ” ) は含まれていません。)

~/Desktop/Twitter $ ./server_get.rb
GET
Listening on port 9090
"GET /?name=Yoshiaki&message=Hello%21 HTTP/1.1\r\n"
"Host: 192.168.1.6:9090\r\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.29.13 (KHTML, like Gecko) Version/6.0.4 Safari/536.29.13\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Referer: http://192.168.1.6:9090/\r\n"
"Accept-Language: ja-jp\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Connection: keep-alive\r\n"
"\r\n"

Listening on port 9090 の次の行、 GET に表示されるのが URL とパラメーターです。? はパラメーターの開始を表し、& は区切り文字です。

"GET /?name=Yoshiaki&message=Hello%21 HTTP/1.1\r\n"

上部分より、 Safari のフォームで入力された値、name が Yoshiaki、message が Hello%21 というパラメーターで送信されたことがわかります。%21は ! 文字の URL エンコードです。 HTML の

<input type="text" name="name" size="50"></p>
<textarea name="message" cols="50" rows="5"></textarea></p>

より、input の name=”name” と textarea の name=”message” が入力された値の名前です。

フォームを Safari が解釈して、サーバーにデータを送っています。フォームは複雑な表記ですが、送信するデータは name=Yoshiaki&message=Hello%21と単純です。
server_get.rb を終了するには、ターミナル上で CTRL + C キーを押してください。

POST を利用した server_post.rb で同じように試してみると

~/Desktop/Twitter $ ./server_post.rb
POST
Listening on port 9090
"POST / HTTP/1.1\r\n"
"Host: 192.168.1.6:9090\r\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.29.13 (KHTML, like Gecko) Version/6.0.4 Safari/536.29.13\r\n"
"Content-Length: 30\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Origin: http://192.168.1.6:9090\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Referer: http://192.168.1.6:9090/\r\n"
"Accept-Language: ja-jp\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Connection: keep-alive\r\n"
"\r\n"
"name=Yoshiaki&message=Hello%21"

上のように表示されます。GET と違ってパラメーターは、ヘッダの後、ボディーに付加されます。

"name=Yoshiaki&message=Hello%21"

の部分です。GET、POST の違いがはっきりわかると思います。サーバーに送られるパラメーターは同じです。

次回、紹介しますが、同封の server.rb を使って、Apple 純正ソーシャルネットワークフレームワークの SLRequest がどんなデーターをサーバーに送信するか、覗き見ると面白いかもしれません。