【iPhone】Push Notificationの実装方法

Posted by: daichi  /  Category: iphone開発

pic1pic2pic3
新作でTwitter,はてな,Google Readerから横断的に情報収集し、マルチポストするアプリを作っているのですが、そこでTwitterのリプライPush機能を実装したので、Push Notificationを実装する方法をまとめてみます。

Push Notificationの流れ

Push Notificationに関する登場人物は、
  • iPhone
  • Apple Push Notification Service(APNs)
  • Provider
の3者です。

iPhoneはいわずもがな、みんなの手元にあるiPhone。APNsはAppleが用意しているPushしてくれるやつです。Providerは、開発者が用意するもので、こいつがPushしたい情報を送る役割を持ちます。

この3者間でのデータの流れは大きくデバイス登録とPush通知の2つのフェーズに分かれます。

デバイス登録

デバイス登録フェーズではAPNsへPush通知するiPhoneを登録します。このときAPNsから一意なデバイストークンが発行され、これをProviderが保持することで、Push通知を送りたいiPhoneをProviderが特定できるようになります。
流れはこんな感じ。
  1. iPhoneにアプリをインストール
  2. アプリ起動時にiPhoneからAPNsへデバイスの認証通知をする
  3. APNsから認証されると、デバイストークンを受け取る
  4. iPhoneからデバイストークンをProviderへ送る

Push通知

Push通知フェーズでは、ProviderからAPNsへPush情報と共に認証情報を送ります。APNsから認証されると、送信先iPhone宛にPush通知が送られ、晴れてiPhone上であのAlertが表示されるようになります。
流れはこんな感じ。
  1. 任意のタイミングでProviderからPush情報と認証情報をAPNsへ送る
  2. APNsから認証されるとiPhoneへPush通知が送られる
  3. iPhone上でポップアップ!
というわけで、以降デバイス登録から順に書いていきます。

鍵を作る

デバイス登録手順1のアプリインストールは飛ばすとして、2のiPhoneからAPNsへデバイス認証通知をするためには、鍵が必要です。

なのでApple Developer Connection – iPhone Dev Center – Overviewへ行って鍵を作りましょう。
手順はこんな感じです。
  1. 左メニューApp IDsからNew App ID
  2. Descriptionには自分のわかりやすい説明を
  3. Bundle Seed IDはGenerate NewでOK
  4. Bundle Identiferは*は使えません。net.longearth.earth等、一意な値となるようにドメイン名を逆から綴ったものにしておく
  5. 以上を入力してsubmit
  6. App IDsのManage画面で登録したApp IDのConfigureリンクを押す
  7. ひとまず開発用の設定をするため、Development Push SSL CertificateのConfigureを押す
  8. Lightbox風に鍵作れといわれるのでキーチェインを起動
  9. キーチェーンアクセス→証明書アシスタント→認証局に証明書を要求…
  10. ユーザのメールアドレスは登録したメールアドレスを
  11. コモンネームは他の証明書の時と同じ名前を
  12. ディスクに保存をチェック→続ける→保存
  13. ブラウザに戻りContinueを押す
  14. さっき作った証明書を選択してGenerate
  15. 認証されたらContinue
  16. Downloadなうして、Done
  17. Lightbox風が終わるので画面上でステータスがenabledになっていることを確認
  18. ダウンロードした証明書をダブルクリックしてキーチェーンに保存
  19. キーチェーンの「自分の証明書」分類にあるApple Development Push Servicesを選択して、メニュー→ファイル→書き出す…→保存(apns-dev-cert.p12)
  20. 同様にキーチェーン画面からApple Development Push Services横の三角を開き、秘密鍵を選択→メニュー→ファイル→書き出す…→保存(apns-dev-key.p12)
長い。。。

ここまでがApple上のドキュメントに書いてあるのですが、p12ファイルとやらをどう使えばよいのかよくわからないので、pemフォーマットに変換(正直この部分はわかってない。男は黙って以下のコマンド群を打ち込む。)
  1. openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
  2. openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
  3. openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
  4. cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
これでapns-dev.pemとapns-dev-key-noenc.pemができあがるので、これで鍵の準備は完了。

鍵ができたら、ここで作成したApp IDを指定したProvisioningファイルを作成して、Xcodeにインストール。code signに設定しておくことも忘れずに。

デバイス認証通知

認証通知は簡単です。UIApplicationのregisterForRemoteNotificationTypes:で通知処理を設定します。これだけでcode signされた内容でデバイス認証しに行く様子。アプリ起動直後あたりに仕込んでおきます。ちなみにここでPush時にバッヂ表示させるか、音をならすか、アラート画面を出すかを選択できます。以下はすべてを通知させるような例。

?View Code OBJECTIVE-C
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	[[UIApplication sharedApplication] 
	 registerForRemoteNotificationTypes:
             (UIRemoteNotificationTypeBadge| 
	      UIRemoteNotificationTypeSound|
		UIRemoteNotificationTypeAlert)];
        // 他の処理...
}


デバイストークンを受け取る

APNsから認証されるとデバイストークンを受け取ることができます。認証後はUIApplicationのapplication:didRegisterForRemoteNotificationsWithDeviceToken:メソッドが呼ばれるのでここで受け取ります。

?View Code OBJECTIVE-C
- (void)application:(UIApplication*)app 
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken{ 
	NSLog(@"deviceToken: %@", devToken); 
	self.devToken;
        [self sendProviderDeviceToken:devToken];
}

sendProviderDeviceToken:メソッド内でProviderへデバイストークンを送る処理をしています。NSLogで送られてきたdevTokenをログ出力してますが、このとき表示される32バイトの値がデバイストークンです。後のproviderでのテストのために控えておきます。
認証エラー時は以下のメソッドが呼ばれます。

?View Code OBJECTIVE-C
- (void)application:(UIApplication*)app 
didFailToRegisterForRemoteNotificationsWithError:(NSError*)err{ 
	NSLog(@"Errorinregistration.Error:%@",err); 
}

code signが間違っている等、分かりやすい日本語で表示してくれているので助かります。

Providerへデバイストークンを送る

ここは好きなようにProvider宛にデバイストークンをPostしてあげてください。
ちなみにこんな感じでポストできるはずです。

?View Code OBJECTIVE-C
- (void)sendProviderDeviceToken:(NSData *)token {
		NSMutableData *data = [NSMutableData data];
		[data appendData:[@"device=" dataUsingEncoding:NSUTF8StringEncoding]];
		[data appendData:token];
 
 
		self.request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"ホスト名"]];
		[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];		
		[request setHTTPMethod:@"POST"];
		[request setHTTPBody:data];
		[NSURLConnection connectionWithRequest:request delegate:self];
}


サーバ側では、このデバイストークンを控えておきます。実用的な所でいうと、このデバイストークンと何かしらのユーザを識別するIDをサーバへ送ることになると思います。
ここまでで、デバイスの登録が完了です。

ProviderからAPNsへPush通知を送る

ProviderからAPNsへの通知は以下のようなフォーマットで送る必要があります。

aps_provider_binary
始めの3バイトは固定で、0,0,32。16進では0×00,0×00,0×20です。その後デバイストークンと続き、0×00,送信データサイズ、送信データという流れです。
このあたりはバイナリにまとめたものをファイルに書き出し、ターミナルから
xxd ファイル名
として中身を確認することをおすすめします。アプリ側のNSLogで出力したデバイストークンは16進表記なので、その値がきれいに上のデバイストークンの場所に収まっていればだいじょぶだと思います。

送信処理をrubyで書くとこんな感じです。以下のスクリプトを実行する時は、作成した証明書と秘密鍵を同じディレクトリに置いておいてください。

#!/usr/bin/ruby
 
require 'openssl'
require 'socket'
 
    device = ['デバイストークンのバイナリ値']
 
    socket = TCPSocket.new('gateway.sandbox.push.apple.com',2195)
 
    context = OpenSSL::SSL::SSLContext.new('SSLv3')
    context.cert = OpenSSL::X509::Certificate.new(File.read('apns-dev.pem'))
    context.key  = OpenSSL::PKey::RSA.new(File.read('apns-dev-key-noenc.pem'))
 
    ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
    ssl.connect
 
    payload = <<-EOS
{
  "aps":{
    "alert":"New Message!",
    "badge":1,
    "sound":"default"
  }
}
EOS
    (message = []) << ['0'].pack('H') << [32].pack('n') << device.pack('H*') << [payload.size].pack('n') << payload
 
 
    ssl.write(message.join(''))
    ssl.close
    socket.close

上の例では、Alert表示に”New Message!”を出して、アプリアイコンバッヂに1を表示させ、デフォルトの音をならすような通知設定をしています。設定方法の詳細はApple Push Notificationサービス プログラミングガイドにあります。

証明書と鍵さえ正しいものを使っていれば、ローカルのmacからでもPushすることができるので、ローカルでごにょごにょ確認するのがいいと思います。ここまでくれば、送る相手のデバイストークンさえ分かればPushできるので、登録されたデバイストークンを全取得する方法を用意しておけば、ローカルから最新情報告知なんていう使い方もできそうです。

特に気の知れた相手のデバイストークンが分かっていれば、「うんこ」なんて通知もできてしまいそうです。もちろん自重します。絶対。

これから

あとはアプリの任意のタイミングで上記のように送りたい相手のデバイストークンを取得して、メッセージを送信することでPushすることができます。
麻雀アプリなら上家がパイを切った後に、Providerへ通知させて、次の相手のデバイストークンを引っ張ってきてPushという形になるでしょう。

Twitterのリプライ通知をどのようにしようかすごく悩んでいたのですが、Stream APIが使えそうです。
Twitter API Wiki / Streaming API Documentation
試してみた所、まだアルファテスト版ということでだいぶ不安定な気もします。Twit Pushとかどうやっているのか気になります。

長いことおつかれさまでした。
しかし、めんどくさい。
もうちょっと楽にできないかな。

参考

後で気づいたけど日本語のドキュメントがあった。
iPhone Dev Center
cocoa*life – Apple Push Notification Serviceを利用した、iPhone クライアントと、Rubyによるサーバの作成。
How to build an Apple Push Notification provider server (tutorial) « Boxed Ice Blog

【iPhone】アプリ内でWEBアプリ感覚で画面遷移する

Posted by: daichi  /  Category: iphone開発

iPhoneアプリで画面遷移させる場合、コントローラをalloc/initしてナビゲーションコントローラのスタックにプッシュしたり、modalしたりする流れになるわけですが、複数の画面から呼ばれる画面だったりするとインスタンスの管理が面倒だったり、決まり文句をいちいち書くのが面倒になります。

そこでThree20のTTNavigatorを使うと、すっきり画面遷移できるようです。

webアプリ感覚で”http://about”のように遷移先を指定するだけで、その画面を表示できるようになります。
httpの部分は任意の文字列を定義できます。

そのためには、まずURLとコントローラのマッピングが必要です。

簡単にサンプルを示します。

?View Code OBJECTIVE-C
#import "DCAppDelegate.h"
#import "DCTwitterController.h"
#import "DCGoogleReaderController.h"
#import "DCAboutController.h"
#import "DCTabBarController.h"
 
@implementation DCAppDelegate
 
- (void)applicationDidFinishLaunching:(UIApplication *)application {
 
	TTNavigator *navigator = [TTNavigator navigator];
	navigator.supportsShakeToReload = YES;
	navigator.persistenceMode = TTNavigatorPersistenceModeTop;
 
	TTURLMap *map = navigator.URLMap;
	[map from:@"*" toViewController:[TTWebController class]];
	[map from:@"dc://tab" toSharedViewController:[DCTabBarController class]];
	[map from:@"dc://twitter" toViewController:[DCTwitterController class]];
	[map from:@"dc://reader" toViewController:[DCGoogleReaderController class]];
	[map from:@"dc://web" toViewController:[TTWebController class]];
	[map from:@"dc://about" toViewController:[DCAboutController class]];
	[map from:@"dc://compose?title=(compose:)" toModalViewController:[DCAboutController class]];
 
    [navigator openURL:@"dc://tab" animated:NO];
 
}
 
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)URL {
	[[TTNavigator navigator] openURL:URL.absoluteString animated:NO];
	return YES;
}
@end


まずTTNavigatorクラスのインスタンスを取得します。
TTNavigator.supportsShakeToReloadをYESにすると、iPhoneを振ると、リロードをしてくれるようになります。
TTNavigator.persistenceModeはアプリ終了時にどの画面を開いていたかを記憶する設定です。persistenceModeAllを指定すると常に最後に開いていた画面を記憶し、次回起動時にその画面を表示するようになります。

その後のTTURLMapがURLとコントローラのマッピング情報を保持するクラスです。
from:toViewControllerメソッドでは、fromに指定されたURLが呼ばれるとtoViewControllerの画面を表示する、というような設定になります。
fromに”*”を指定すると、マッピングにないURLが指定された場合のコントローラを指定できます。

URLを指定したら、TTNavigatorのopenURL:animated:メソッドを呼べば画面遷移が行われます。

TTNavigatorはシングルトンなため、どの画面からでも同一インスタンスを取得でき、遷移したい時にopenURL:animated:メソッドを呼んでやればよい、という感じです。

TabBarコントローラのような全画面で共通で使いたいコントローラの場合は
from:toSharedViewController:メソッドを使うと一つのインスタンスを使い回せるようです。

また、コントローラに渡すパラメータも指定できます。

?View Code OBJECTIVE-C
[map from:@"dc://compose?subject=(compose:)" toModalViewController:[DCAboutController class]];

の部分がそれで、これはDCAboutControllerクラスのcompose:メソッドが呼ばれます。

パラメータの受け取りは以下のように行います。

?View Code OBJECTIVE-C
#import "DCAboutController.h"
 
@implementation DCAboutController
 
- (void)createModel {
	self.dataSource = [TTSectionedDataSource dataSourceWithObjects:
						@"About",
						[TTTableTextItem itemWithText:@"サイト" URL:@"http://iphone.longearth.net"],
						[TTTableTextItem itemWithText:@"ご意見ご要望" URL:@"dc://compose?subject=%5biSlot%20Pro%5d%e6%84%8f%e8%a6%8b%2f%e8%a6%81%e6%9c%9b"],
					   [TTTableTextItem itemWithText:@"友達にすすめる" URL:@"dc://compose?subject=&body=http%3a%2f%2fitunes%2eapple%2ecom%2fWebObjects%2fMZStore%2ewoa%2fwa%2fviewSoftware%3fid%3d304074830%26mt%3d8"],
						@"関連アプリ",
					   [TTTableTextItem itemWithText:@"iPachi" URL:@""],
					   [TTTableTextItem itemWithText:@"iSlot Pro" URL:@""],
					   [TTTableTextItem itemWithText:@"iTaskTimer" URL:@""],
						nil];
}
 
- (UIViewController *)compose:(NSString *)subject query:(NSDictionary *)param {
	TTMessageController* controller =
    [[[TTMessageController alloc] init] autorelease];
	controller.subject = subject;
	controller.body = [param objectForKey:@"body"];
	return controller;
}
@end

第一引数にはsubjectで指定したものが、第二引数以降にも&繋ぎで複数パラメータが指定でき、中身はDictionaryとして取り出すことができます。
上の例ではパラメータを受け取り、それらの値を使って、メール送信画面を起動しているところです。

createModelメソッドはTTTableViewControllerでテーブルデータを表示する際に呼ぶメソッドで、ここではあまりふれません。
が、少しだけ触れておくと、TTTableViewControllerのdatasourceがテーブルデータとなり、TTSectionDataSourceを入れています。TTSectionDataSourceは引数にNSStringがあればそれをセクション名とし、それ以降のものをセクション内に属するデータとして扱います。それからそのデータとしてTTTableTextItemがあり、textで表示する文字を、URLでタップした時の遷移先を指定しています。以上でこんな画面になります。
About画面

URL形式での画面遷移でもすごい画期的なのに、まだまだThree20にはすごい部分が盛りだくさんです。
マジすごい。

【AppStore】【iPhone】Cameraアプリはもうダメかも

Posted by: daichi  /  Category: アプリ

以前Appleに申請していたFakeCameraがまたもやリジェクトされた。
今度は非公開APIを使っているからダメですよ。という内容。
ちょっとシャッターボタンのビュー掘り起こして、ボタン押すイベント横取りしてシャッター音出しただけなのに、やっぱりダメなのね。

シャッター音使ったことには何も言ってこなかったんだよなぁ。
こっちはいいってことなのだろうか。
カメラに過敏になってるのだろうか。

んーこれは本当にお蔵入りの様相を呈してきた。

ちょっと一区切りついたので、一旦たまってきた旧アプリのバージョンアップを端からやりつつ、騙し騙し再申請とかしてみようかと思う。

Google Book SearchアプリはGoogleさんから止められてしまったし、なんかお蔵入りが続いている。

とはいえ、最強情報収集&発信アプリもThree20で作成中なので、それはそれで焦らずに取り組んで行こうと思う。

ひとまずtwitterのタイムラインとはてぶのほってんとりとGoogle Readerの一覧見れて、どの一覧からでもブラウザ開いてマルチポストできるアプリ。
ブラウザでタップ長押しで出てくるツールチップに「ポスト」を追加して、そこからブックマークしたり、つぶやいたり。

一旦小休止です。

Three20とJSON-FrameworkでTwitterのタイムライン画面を作る

Posted by: daichi  /  Category: iphone開発

Three20 JSON datasource implementation – revetkn.com

Three20とjson-frameworkを使って簡単にタイムライン画面を作ってみる。

それぞれセットアップは以下を参考に

【Three20】をプロジェクトで使えるようにする手順 | iphoneアプリで稼げるのか
[iPhone] JSON Framework の使い方(準備編) | Sun Limited Mt.

※JSONFramework側の不具合で上記リンクの通り設定した場合でも、OS3.0で使うと実機転送時にcode signエラーが出た。そんな時は「他のリンカフラグ」等の設定はせずに、JSONディレクトリの中身のファイル達を直接プロジェクトに追加で回避できる。6月末に修正されたらしいので最新版を使えばだいじょぶかもしれない。
json-framework – Google Code

最低限のAPI仕様は

  1. http://twitter.com/statuses/friends_timeline.jsonへ
  2. ベーシック認証つきで
  3. GETメソッドでリクエストを投げる
上記3点が満たされていればOK。

例によってTwitter APIの詳細は公式wikiに譲る。
Twitter API Wiki / Twitter REST API Method: statuses friends_timeline

Three20の中でも今回は

を使う。

コードは以下。

コントローラ

FirstViewController.h

?View Code OBJECTIVE-C
#import
#import "Three20/Three20.h"
 
@interface FirstViewController : TTTableViewController {
 
}
 
@end


FirstViewController.m

?View Code OBJECTIVE-C
#import "FirstViewController.h"
#import "JSONDataSource.h"
 
@implementation FirstViewController
- (void)loadView {
	self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
	self.view.backgroundColor = RGBCOLOR(240, 242, 245);
	self.variableHeightRows = YES;
       // STATUS_HEIGHTはTTGlobal.hで定義されてるステータスバーの高さを表す定数
	self.tableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480 - STATUS_HEIGHT)
												   style:UITableViewStylePlain] autorelease];
	self.tableView.autoresizingMask =
    UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
	self.tableView.sectionIndexMinimumDisplayRowCount = 2;
	[self.view addSubview:self.tableView];
}
 
// この辺はTTTableViewControllerのdelegateメソッド
// ここで返したデータソースを使ってTTTableViewControllerが描画もろもろやってくれる
- (id)createDataSource {
	JSONDataSource *dataSource = [[[JSONDataSource alloc] init] autorelease];
	[dataSource load:TTURLRequestCachePolicyNoCache nextPage:NO];
	return dataSource;
}
 
- (UIImage*)imageForError:(NSError*)error {
	return [UIImage imageNamed:@"Three20.bundle/images/error.png"];
}
 
@end


データソース

JSONDataSource.h

?View Code OBJECTIVE-C
#import
#import "Three20/Three20.h"
 
@interface JSONDataSource : TTListDataSource {
@private
        // 読み込み中フラグ
	BOOL _isLoading;
       // 読み込み完了フラグ
	BOOL _isLoaded;
       // ここいらのフラグを見て読み込み中Activityとか出し分けしてる様子
}
 
@end


JSONDataSource.m

?View Code OBJECTIVE-C
#import "JSONDataSource.h"
 
static	NSString *username = @"username";
static	NSString *password = @"password";
 
@implementation JSONDataSource
 
- (id)init {
	if (self = [super init]) {
        	_isLoading = YES;
		_isLoaded = NO;
	}
	return self;
}
 
#pragma mark TTTableViewDataSource
 
- (void)load:(TTURLRequestCachePolicy)cachePolicy nextPage:(BOOL)nextPage {
       // この辺はTwitterポスト時とほぼ同じ
	static NSString *jsonUrl = @"http://%@:%@@twitter.com/statuses/friends_timeline.json";
	NSString *url = [NSString stringWithFormat:jsonUrl, username, password];
 
	TTURLRequest *request =
    [TTURLRequest requestWithURL:url delegate:self];
	request.cachePolicy = cachePolicy;
	request.response = [[[TTURLDataResponse alloc] init] autorelease];
	request.httpMethod = @"GET";
 
	BOOL cacheHit = [request send];
	NSLog((cacheHit ? @"Cache hit for %@" : @"Cache miss for %@"), jsonUrl);
}
 
#pragma mark TTLoadable
 
- (BOOL)isLoading {
	return _isLoading;
}
 
- (BOOL)isLoaded {
	return _isLoaded;
}
 
#pragma mark TTURLRequestDelegate
 
- (void)requestDidStartLoad:(TTURLRequest*)request {
	_isLoading = YES;
	_isLoaded = NO;
	[self dataSourceDidStartLoad];
}
 
- (void)requestDidFinishLoad:(TTURLRequest*)request {
        // 通常通りレスポンスゲット
	TTURLDataResponse *response = request.response;
	NSString *responseBody = [[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding];
 
        // JSONFrameworkのメソッドでArrayとして受け取る。JSONの構造次第でNSDictionaryの可能性もあるのでAPI要確認
	NSArray *json =  [responseBody JSONValue];
 
	for(NSDictionary *result in json) {
                // JSON内のデータ構造はTwitter APIを参照
		NSDictionary *user = [result valueForKey:@"user"];
                // データソースの要素としてTTIconTableFieldをセット。これでアイコンとテキストがワンセットのテーブルになる。
		[self.items addObject:[[[TTIconTableField alloc]
                                                                // JSONからテキスト取得
								initWithText:[result objectForKey:@"text"]
								url:nil
                                                                // JSONから画像取得
								image:[user objectForKey:@"profile_image_url"]
                                                                // 画像読み込み前のデフォルト画像を指定。ここは自分で用意
								defaultImage:[UIImage imageNamed:@"DefaultAlbum.png"]] autorelease]];
	}
 
	_isLoading = NO;
	_isLoaded = YES;
	[self dataSourceDidFinishLoad];
}
 
// この辺はNSURLRequestでおなじみな感じ
- (void)request:(TTURLRequest*)request didFailLoadWithError:(NSError*)error {
	NSLog([error localizedDescription]);
	NSLog(@"didFailLoadWithError");
	_isLoading = NO;
	_isLoaded = YES;
	[self dataSourceDidFailLoadWithError:error];
}
 
- (void)requestDidCancelLoad:(TTURLRequest*)request {
	NSLog(@"requestDidCancelLoad");
	_isLoading = NO;
	_isLoaded = YES;
	[self dataSourceDidCancelLoad];
}
 
@end


以上で、こんな画面の出来上がり。

timeline

これだけで、ネットワーク接続エラー時の対応やデータキャッシュや読み込み中表示などをこちらが意識せずとも勝手にやってくれる。
※表示項目をよりtwitterクライアントにしたい場合は別途カスタマイズが必要。

JSONに関してはアクセス先のURLと取り出し方法の2つが外部APIに依存する部分なので、その辺をdelegateに任せるなりすればこのソースをうまいこと活用できると思う。

iPhoneアプリにTwitterポスト機能は標準搭載でもいいのでは?

Posted by: daichi  /  Category: アイデア

個人的にも僕の回りでも世界的にも、何よりiPhoneユーザ周辺で多いに盛り上がりをみせてるTwitter。

今日もiTwitterというPush Notification搭載のiPhoneアプリが出て、僕のTimeLineがiTwitterだらけになっていたけど、iPhoneユーザでtwitterを使っている人はけっこう多いと思う。
Twitterアプリに異変あり! – iTwitter 1.0 – 普通のサラリーマンのiPhone日記

Twitterの最大の魅力はそのリアルタイム性だと思っていて、リアルタイムを最大限に活かせるのはやっぱりモバイルだよね。
いつでもどこでもモバイルならつぶやきを投稿できるから、実況つぶやきとか、そゆものまで出てくる。
そういうリアルタイムな情報を誰かが投稿してくれてるから、つぶやかない人にとってもTwitterはとても楽しめるものになっていて、ただ独り言をつぶやくだけのツールではなくなってる。Twitterはじめる前は、独り言をひたすら書いて何が楽しいのか全く理解できず、仮に返信が来たとしても、それほど楽しい気もしていなかったのだけど、真のTwitterの価値はつぶやくことではなくて、リアルタイムな情報収集にあるってことがやってみて分かった。

続きを読む

【iPhone】【Objective-C】Twitterにつぶやきをポストする

Posted by: daichi  /  Category: iphone開発

最近Twitter熱が僕の回りでも加速してきたけど、アプリ標準機能として搭載すべく、iPhoneアプリ内でtwitterポストするためのサンプルコードを書いてみた。

Twitter API Wiki / Twitter REST API Method: statuses update

詳細は公式Wikiに譲るとして、最低限のAPI仕様は

  1. http://twitter.com/statuses/update.xmlへ
  2. ベーシック認証つきで
  3. POSTメソッドを使い
  4. statusパラメータ=「つぶやき」のリクエストを投げる
上記4点が満たされていればOK。

そんな条件を満たしたポストコードが以下。

続きを読む

【iPhone】3GSのここがイイ!5つのポイント&アプリネタ

Posted by: daichi  /  Category: アイデア

iPhone 3GS。買いましたよ。

個人的iPhone 3GSのここがイイ!5つのポイント&アプリネタ。

続きを読む

【iPhone】公開前にアプリネタを晒すことの意義

Posted by: daichi  /  Category: 販売促進

これまでAppStore公開前にアプリネタを公言するのは、ネタをパクられたらどうしよう的な懸念から避けていたのですが、これは全く逆効果なのではと思い直しました。

続きを読む

【アプリ】いたづら系カメラアプリFakeCamera開発中

Posted by: daichi  /  Category: アプリ

最近、いたづら系カメラアプリFakeCameraを開発中です。
画像右下のアイコンがそれ。
aceCamera

普段気取っているアイツの素の表情を撮りたい、気になるあの子の無防備な表情を撮りたい、そんな本能的な欲求を満たすカメラアプリ。

怖いもので、人間カメラのシャッター音を聞くと、実際写真を撮られていないとしても、撮られたと思いますよね。このアプリはその潜在的な部分をツキます。つまり、最初に写真を撮ってもいないのに、シャッター音だけならしてしまうのです。
すると、完全にキメた顔をしていたアイツやあの子の表情は緩みます。そこを本当のシャッターが捕えるというもの。

突然の不意打ちも有効です。横からカシャっと音を鳴らせば、何?と振り返ります。そこを本当のシャッターで取り押さえる!

これまで、パチスロ(iSlot Pro)や仕事(iTask Timer)など使う人だけが使うアプリを作ってきましたが、次回は本能に語りかけるアプリでiPhoneユーザのみなさんに楽しんでもらおうと思ってます。

とりあえず、メインのトラップを仕掛ける部分は出来ていて、これからは撮った写真をmixiやtwitter、tumblr、flickr、facebook等にアップロードする機能を作るとこです。

【App Store】iTaskTimerをリリースしました

Posted by: daichi  /  Category: 販売促進

少し告知が遅れましたが、2009/06/05に時間管理アプリiTaskTimerをリリースしました。

iTask Timer

iTask Timer 2009/06/05 リリース
仕事効率化
時間管理アプリ
app_store_badge



アプリの説明はこちら。
iTaskTimer

しかも早速レビューしてくださった方が!
日々のタイムマネジメントのお供に♪ – iTaskTimer1.0 – 普通のサラリーマンのiPhone日記

自分の作ったアプリを使ってくれる人がいて、それに対して意見や感想を言っていただけるというのは、一番モチベーションが上がります。
twitterのiphonefanで議論されるようなアプリを作れたら最高だろうなぁ。

そういったアプリを作れるように頑張ります!

Get Adobe Flash playerPlugin by wpburn.com wordpress themes