Hatena::ブログ(Diary)

中継地点 RSSフィード

2012-03-16

緊急時に10秒でマルチ送信できる無料アプリ「生存連絡」をリリースしました

東日本大震災から1年が経ちました。あらためてお亡くなりになられた方々のご冥福をお祈り申し上げます。

当日、私は仙台市で務めていた会社のビル8階で地震に見舞われたのですが、今までに体験したことのないような状況でおそらく一生忘れることはないと思います。2分近い揺れの中で机の下に潜り死を意識した瞬間もあるくらいでしたので、1階に避難する際にもかなり動揺していたことを覚えています。自分の安全を確保してまず行うことは家族の安否連絡なのですが当然のように電話は通じませんでした。ネット回線はまだ可能な状態でしたのでとりあえずはTwitterFacebookに自分が無事であるメッセージを残したのですが、動揺と地面の揺れで上手く操作が行えなかったことを記憶しています。

最近また地震がちょくちょくあり全体的に防災意識が高まっていると思いますので、今回「緊急異常事態時にすぐさまにメッセージを送信できるように」というiPhoneアプリを無料でリリースしました。事前に送信先・連絡先を設定しておき、緊急時にメッセージを送信するというアプリなのですが、慌てていても10秒以内にメール、SMSメッセージ、TwitterFacebookに同時送信することができます。



生存連絡

f:id:h_mori:20120316100953p:image:medium:left


インストール (無料)





災害の時の安否連絡は電話よりもインターネットを利用した伝達手段が確実ですが、落ち着いてメッセージを入力したりするのは困難です。東日本大震災の発生直後では「連絡先が直ぐに出てこない」「気が動転して上手く操作できない」などの声が聞かれました。このアプリでは送信先を事前に登録してメッセージを選択するだけの簡単操作でわずか10秒で生存連絡などが送信できます。

災害を事前に備えましょう。

=主な機能=

・文章選択によるメッセージ作成機能

・メッセージのマルチポスト送信機能

・現在地発信機能

=送信先媒体=

・Email

ショートメール

Twitter

Facebook

インストール後は最初に送信先の設定を行なってください。


スクリーンショット

f:id:h_mori:20120316100954p:image:w240:left

f:id:h_mori:20120316100955p:image:w240:left

f:id:h_mori:20120316100956p:image:w240



実際に使われるような状況は起きてほしくないと心から願ってるのですが、このアプリインストールして設定することで安心が得られるのなら幸いです。

2012-02-28

ATND暦のソースコードを公開しました

ATND暦のアップデート版がApple審査が無事通過し公開されました。だいぶバグも落ち着き安定したので晴れてver1.0としました。今回のアップデートはWeb版のATNDカレンダーと同じく7日数以上続くイベントを表示しないようにしました。日数はオプションで変更が可能です。

ダウンロードはこちらから

ATND暦 ver1.0

http://itunes.apple.com/jp/app/id469446797?mt=8



ATND暦のソースコード公開

ver1.0の公開に合わせてATND暦のソースコードGithubに公開しました。

扱いやすいようにBSDライセンスとしています。コピーレフト条項はありません。ご自由に利用ください。起動アイコン(icon.png)についてはCCライセンスver3.0の表示のみとしています。

https://github.com/hmori/atndcal


何度かリファクタを続けてるので、そんなに酷いコードではないと思います。色々なWebサービスにアクセスしたり様々な機能を盛り込んでいるので参考になるかと思います。もし、何かあればフィードバックいただければ幸いです。


実装機能
サードパーティ
    • TapkuLibrary
    • json-framework
    • RegexLiteKit
    • FacebookLibrary
    • EvernoteLibrary

注意点
  • iOS4.0以上をターゲットとしています。
  • Xcode4以上で作成しましたので、Xcode3では動かないかもしれません。
  • 外部サービスのWeb APIのキーはダミーに変更しています (atndcal-exclusive-Prefix.pch)

そのうち、今後も技術的なネタをこの中のソースコードから紹介していきます。

余裕があれば。

2011-11-07

Evernoteクリッピングの実装手順

今回、ATND暦 ver0.9.2でEvernoteへのクリッピング機能を追加しました。実は、以前SOICHAで実装したことがあるので今回は2度目になります。

当時はCocoa用のソースがiPhone用にカスタマイズされてなく改変しながら組み込んだのですが、最新バージョンではiPhone用にも使えるようになっていて、サンプルコードも用意されているので更に簡単になったように思います。

今回はEvernote API ver 1.19を利用したEvernoteクリッピングの実装手順について書きます。



APIキーの取得

EvernoteデベロッパーサイトよりAPI Keyを申請します。

http://www.evernote.com/about/developer/api/

f:id:h_mori:20111106220807p:image

Evernote name」はEvernoteのアカウント名を入力します。APIキーはこのアカウント名になるので個人と切り離したい場合は別にEvernoteアカウントを取得してから行なったほうがいいかもしれません。

「Organization」は会社等の組織に属していない場合は自分の名前を入力します。

Application Typeは iPhoneアプリですので「Client Application」を選択します。

「Application Details」はAPIの使い道を記載しますが、適当に「I will develop my iphone application evernote integration. I will make an application.」くらいに書いておけばいいと思います。

後は、License Agreementに同意してSUBMITします。

暫くすると、登録したメールに Consumer Key と Consumer Secret が届くので保管しておいてください。

尚、この手順で登録したKeyはあくまでsandboxサーバ上でのみ有効で、本番サーバでは有効になっていません。


Evernote API SDKのサンプルを動かしてみる

EvernoteデベロッパーサイトよりSDKをダウンロードします。

f:id:h_mori:20111106221101p:image

中に様々なプラットフォームのソースが梱包されていますが、iPhoneの場合はcocoa/src 以下があれば事足りますが、折角なのでサンプルソースがありますので動かしてみます。

Evernote.mファイルのヘッダ付近にある、consumerKey、consumerSecret、username、passwordを設定します。username/passwordはクリッピングする操作者のアカウント情報です。

実行して、Titleに適当に入力して「Create a new note」を押してみてください。成功した場合、サンドボックス上のEvernoteにクリッピングされたことが確認できます。

https://sandbox.evernote.com/ にアクセスして確認できます。

f:id:h_mori:20111106221103p:image

f:id:h_mori:20111106221104p:image


サンプルソース

クリッピングに必要な骨組みのソースを抜き出してみました。

addNoteViewController#sendNoteEvernote

-(IBAction)sendNoteEvernote:(id)sender{
    
    // Creating the Note Object
    EDAMNote * note = [[[EDAMNote alloc] init]autorelease];
    
    // Setting initial values sent by the user
    note.title = @"test";
   
    // Simple example ENML we are going to use as content for our note
    NSString * ENML = [[[NSString alloc] initWithString: @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n<en-note>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."]autorelease];
    
    ENML = [NSString stringWithFormat:@"%@%@", ENML, @"</en-note>"];
    NSLog(@"%@", ENML);
    
    // Adding the content & resources to the note
    [note setContent:ENML];

    // Saving the note on the Evernote servers
    // Simple error management
    @try {
        [[Evernote sharedInstance] createNote:note];
    }
    @catch (EDAMUserException * e) {
        NSString * errorMessage = [NSString stringWithFormat:@"Error saving note: error code %i", [e errorCode]];
        UIAlertView *alertDone = [[UIAlertView alloc] initWithTitle: @"Evernote" message: errorMessage delegate: self cancelButtonTitle: @"Ok" otherButtonTitles: nil];
        
        [alertDone show];
        [alertDone release];
        return;
    }
    
    // Alerting the user that the note was created
    UIAlertView *alertDone = [[UIAlertView alloc] initWithTitle: @"Evernote" message: @"Note was saved" delegate: self cancelButtonTitle: @"Ok" otherButtonTitles: nil];
    
    [alertDone show];
    [alertDone release];
}

Evernote#createNote:

- (void) createNote: (EDAMNote *) note {
    // Checking the connection
    [self connect];

    // Calling a function in the API
    [noteStore createNote:authToken :note];
}

Evernote#connect

- (void) connect {
    
    if (authToken == nil) 
    {      
        // In the case we are not connected we don't have an authToken
        // Instantiate the Thrift objects
        NSURL * NSURLuserStoreUri = [[[NSURL alloc] initWithString: userStoreUri] autorelease];
        
        THTTPClient *userStoreHttpClient = [[[THTTPClient alloc] initWithURL:  NSURLuserStoreUri] autorelease];
        TBinaryProtocol *userStoreProtocol = [[[TBinaryProtocol alloc] initWithTransport:userStoreHttpClient] autorelease];
        EDAMUserStoreClient *userStore = [[[EDAMUserStoreClient alloc] initWithProtocol:userStoreProtocol] autorelease];
 
        // Returned result from the Evernote servers after authentication
        EDAMAuthenticationResult* authResult =[userStore authenticate:username :password : consumerKey :consumerSecret];
        
        // User object describing the account
        self.user = [authResult user];
        // We are going to save the authentication token
        self.authToken = [authResult authenticationToken];
        // and the shard id
        self.shardId = [user shardId];
        
        // Creating the user's noteStore's URL
        noteStoreUri =  [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@%@", noteStoreUriBase, shardId] ] autorelease];
        
        
        // Initializing the NoteStore client
        THTTPClient *noteStoreHttpClient = [[[THTTPClient alloc] initWithURL:noteStoreUri userAgent: @"iosdemo" timeout:15000] autorelease];
        TBinaryProtocol *noteStoreProtocol = [[[TBinaryProtocol alloc] initWithTransport:noteStoreHttpClient] autorelease];
        noteStore = [[[EDAMNoteStoreClient alloc] initWithProtocol:noteStoreProtocol] retain];
        
    }
}

EvernoteのノートはENMLというXML形式で保持される仕組みとなっています。

クリッピングするXMLデータを事前に作成する必要があります。

ENMLの仕様はこちらに記載されています。

http://www.evernote.com/about/developer/api/evernote-api.htm#_Toc297053072

ここでは EDAMNote に titleとcontentを設定して EDAMNoteStoreClient#createNote:: でノートを送信しています。

サンプルでは、authTokenは送信時に認証していますが、実際にはユーザー名、パスワードを登録する画面が必要となりますのでそこで認証させ、authTokenを保持しておけばよいかと思います。

実際に組み込む時は、cryptoとapiEvernote.h、Evernote.mを自分のプロジェクトにコピーして、固定値となっている箇所をNSUserDefaultsとかから引っ張る仕組みに組み替えます。



アクティベート

組込み後、sandbox上でテストが完了したらKey取得時にメールにURLがありますので、そこからアクティベート申請を行います。

http://www.evernote.com/about/developer/api/activate.php?code=[consumerKey]

f:id:h_mori:20111106221105p:image

申請して2日ほどでアクティベート完了のメールが届くので、NoteStoreとUserStoreのURLをsandboxからwwwに変更して本番サーバにてテストします。

//NSString * const userStoreUri = @"https://sandbox.evernote.com/edam/user";
//NSString * const noteStoreUriBase = @"https://sandbox.evernote.com/edam/note/"; 
NSString * const userStoreUri = @"https://www.evernote.com/edam/user";
NSString * const noteStoreUriBase = @"https://www.evernote.com/edam/note/"; 

そこまで難しい仕様(ENML)でなければ実装は認証画面を含め2、3日くらいで可能だと思います。

ENMLが厳格な仕様なのでWebのHTMLのBody内をそのままクリッピング使用とすると大抵ENMLバリデーションエラーとなります。

Evernote site memoryのjavascriptを上手く活用できれば、全てのHTMLでクリッピングできそうな気がしますが、まだ試していないので余力があればチャレンジしてみます。

2011-10-27

Twitterへのツイートの実装方法

前のエントリーで書いたようにiOS5のSDKに標準で追加されたためTwitterへのツイート機能の実装のハードルが下がり、1時間もあれば余裕で実装可能となりました。ATND暦で行なった実装した手順について書きます。



Twitter.frameworkのインポート

プロジェクトのターゲットを選択してBuild PhasesよりTwitter.frameworkを追加

f:id:h_mori:20111027205728p:image



Twitter.hのインクルード

実装したいViewControllerにTwitter.hをインクルード

#import <Twitter/Twitter.h>


TWTweetComposeViewControllerをモーダル表示

ツイート編集画面を表示するアクションにて、

TWTweetComposeViewControllerを生成してpresentModalします。

iOS5 SDKならブロックが使えるので通信のコールバックを拾いComposeViewControllerをdismissします。

    TWTweetComposeViewController *tweetViewController = [[[TWTweetComposeViewController alloc] init] autorelease];
    [tweetViewController setInitialText:@"ツイート初期文字列"];
    
    [tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
        if (result == TWTweetComposeViewControllerResultDone) {
            NSString *message = @"ツイートしました.";
            UIAlertView *alert = [[[UIAlertView alloc]  initWithTitle:nil 
                                                          message:message
                                                         delegate:nil 
                                                cancelButtonTitle:@"閉じる" 
                                                otherButtonTitles:nil] autorelease];
            [alert show];
        }
        [self dismissModalViewControllerAnimated:YES];
    }];
    [self presentModalViewController:tweetViewController animated:YES];


Twitter投稿可否の制御を行う

iOS4以前を利用している、iOS5でまだTwitterのアカウント設定を行なっていない場合などを想定して、ツイート可能かチェックします。具体的にはボタンをdisableにするなどに利用します。

    if (![TWTweetComposeViewController canSendTweet]) {
        //ボタン非表示等
    }

と以上の手順だけです。


今までは、Twitterのクライアント申請してKeyをもらい、MGTwitterEngine等のOAuth認証モジュールに頼りながら頑張って認証画面を作り認証情報を管理してツイート画面もせっせと作ってと、ツイート投稿の実装だけでも最低でも1週間くらいはかかったんですが、iOS5ではあっさり作れちゃいます。


全くTwitterに関係ないアプリだとしてもアプリ宣伝のため実装することをオススメします。

2011-10-25

ATND暦の新バージョンが公開されました

申請から予想以上に早くに公開となりました。

ver0.9.1の新機能は下記になります。

・イベントのツイート機能を追加 (iOS5+)

・イベントのメール送信機能を追加

・ATNDユーザーのプロフィール表示機能を追加

・カレンダーのスケジュール編集機能を追加



公開されてから気がついたのですが、iOS5 SDKを使用してのTwitterへのツイートの場合、利用したアプリのfromリンクはつかないと思ってたんですが、公開されるとAppStoreへのリンクが付くようです。

f:id:h_mori:20111025213336p:image


公開前のテスト版では"iOSから"となっていたんですが、どうやらAppStoreのメタ情報を上手く利用して自動的にリンクをつけるみたいです。さすがAppleは導線を作るのがうまいなと思った瞬間でした。

iOS5以降でツイッターを実装する場合に自前でOAuth認証を実装するのはAppStore以外にしたい以外のメリットはほぼ皆無となりました。ツイート投稿の実装はすごく簡単でバイラル効果はすごく高いと思いますので、まだ対応されてない方は超オススメです。



ATND暦

http://itunes.apple.com/jp/app/id469446797?mt=8