iPhone アプリケーション
-
はてな touch/Hatena touch
-
LDR touch
-
テレビ番組表/TV Listings
-
LCD Clock by forYou Inc.
-
MyWebClip by forYou Inc.
-
MyWebClip LITE by forYou Inc.
-
Japan Subway Route Map by Studio Heat
-
こころくろっく by AppBank
-
英辞郎 on the WEB for iPhone by アルク
-
i-Radio by i-Radio
-
くるりんぱ性格診断 by 小学館
-
英辞郎検索ランキング(アルク) by アルク
-
kotobank - コトバンク by genesix
-
miil by frogapps
iPad アプリケーション
共著
2011-12-02
CAEmitterLayer でクリスマスは爆発しろ - iOS Advent Calendar 2011
iOS 5 からCAEmitterLayer と CAEmitterCell クラスが iOS でも使えるようになり、パーティクルを簡単に表示することができるようになりました。
これを使ったクリスマスネタが何かできないかと思って、タップするとクリスマスが爆発するゲームを作ってみました。
みんなでクリスマスを爆発させてください。
kishikawakatsumi/ExplodeChristmas - GitHub
ゲームが始まるとクリスマス(っぽいもの)が落ちてくるので……
タップして爆発させてください。
根こそぎ爆発させてください。
2011-11-20
Titanium mobile の KeyChain モジュール TiKeyChainStore を書きました。【添削希望】
UICKeyChainStore を応用して Titanium mobile の KeyChain モジュール TiKeyChainStore を書きました。
kishikawakatsumi/TiKeyChainStore - GitHub
下記のように使います。
var store = tikeychainstore.createKeychainStore({ service: 'com.kishikawakatsumi.ti' // optional }); store.setKeyChainItem ({ key: 'userame', value: 'kishikawakatsumi@mac.com' }); store.setKeyChainItem ({ key: 'password', value: 'password1234' }); store.synchronize; Ti.API.info(store.description); // debug print
Titanium のモジュールは初めて書いたので、詳しい方に添削してもらえるとうれしいです。
関連リンク
KeyChain のデータを操作するラッパークラス UICKeyChainStore を書きました。
アップルのサンプルコード GenericKeychain に含まれる KeyChain のラッパー KeychainItemWrapper.m の実装が微妙だったので書きました。
kishikawakatsumi/UICKeyChainStore - GitHub
KeychainItemWrapper クラスには下記で報告されている問題や、
A-Liaison BLOG: KeychainItemWrapper を改造して、複数の Keychain Item に同時にアクセス出来るようにしてみた
下記の箇所でメモリーリークする問題があったり、使い勝手もよくないので、そのまま使うのはおすすめしません。
- (void)resetKeychainItem { OSStatus junk = noErr; if (!keychainItemData) { self.keychainItemData = [[NSMutableDictionary alloc] init]; // <= メモリーリークする!
というわけで、あたらしく書いて見ました。
使い方
- リンクするフレームワークに Security.framework を追加します。
- UICKeyChainStore.h と UICKeyChainStore.m をプロジェクトに追加します。
クラスメソッドを使って値を操作する
便利メソッドとしてクラスメソッドを用意してあります。キーと値を指定するだけで簡単に使えます。
サービス名を指定しない場合は自動的に Bundle ID がサービス名になります。
キーと値を指定して値を追加・更新する。
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"]; [UICKeyChainStore setString:@"password1234" forKey:@"password"]; //=> ["username" = "kishikawakatsumi", "password" = "password1234"]
サービス名を明示的に指定することもできます。
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username" service:@"com.kishikawakatsumi"]; [UICKeyChainStore setString:@"password1234" forKey:@"password" service:@"com.kishikawakatsumi"];
値をキーチェーンから削除するにはキーを指定します。
[UICKeyChainStore removeItemForKey:@"username"]; [UICKeyChainStore removeItemForKey:@"password"];
サービス名を指定していた場合は、サービス名も含めて指定します。
[UICKeyChainStore removeItemForKey:@"username" service:@"com.kishikawakatsumi"]; [UICKeyChainStore removeItemForKey:@"password" service:@"com.kishikawakatsumi"];
KeyChainStore オブジェクトを使って値を操作する
複数の項目を追加・更新する場合は UICKeyChainStore のインスタンスを作成するほうが便利です。
NSUserDefaults のような使い勝手になります。
デフォルトのサービス名 (Bundle ID) の KeyChainStore を作成した場合。
UICKeyChainStore *store = [UICKeyChainStore keyChain]; [store setString:@"kishikawakatsumi@mac.com" forKey:@"username"]; [store setString:@"password1234" forKey:@"password"]; [store synchronize]; // Write to keychain.
サービス名を指定して KeyChainStore を作成した場合。。
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"com.kishikawakatsumi"]; [store removeItemForKey:@"username"]; [store removeItemForKey:@"password"]; [store synchronize]; // Write to keychain.
miil 1.0.1 がリリースされました。

miil 1.0.1 がリリースされました。
バージョン 1.0.1 の変更点
- 利用規約を変更しました。
機能改善
- ユーザー一覧画面のフォローボタンのタップ領域を拡大し、押しやすくしました。
- Twitterから友だちを検索する際のUIを改善しました。
- 現在地以外の位置情報を投稿できるようになりました。
- お店を新しく登録する際の手順を改善しました。
不具合の修正
- HOTタイムラインの並び順が更新されない問題を修正しました。
- フォローボタンが正しく動かない問題を修正しました。
- ユーザー登録できないことがある問題を修正しました。
- お店の情報が正しく追加されないことがある問題を修正しました。
- iPod touchで電話をかける画面が表示されてしまう問題を修正しました。
- 「お知らせ」を表示する際にクラッシュすることがある問題を修正しました。
- 「続きを読みこむ…」を押した際にクラッシュすることがある問題を修正しました。
- 新着の「お知らせ」バッジが表示されないことがある問題を修正しました。
関連リンク
miil 1.0.0 がリリースされました。

私がプログラムを担当しました、miil 1.0.0 がリリースされました。
食べものの写真を通して「おいしい!」を共有するアプリケーションです。
写真を撮って投稿したり、ほかの人の写真をみたり、
ほかの人の写真をみたり、感想を書き込んだり、
食べたい写真があったら、お店を調べたりできます。
眺めているだけでも楽しい気分になるアプリケーションですので、ぜひダウンロードしてみてください。
関連リンク
2011-09-16
i-Radio 1.2.0 がリリースされました。

i-Radio
ネットラジオのアプリケーション i-Radio のバージョン 1.2.0 が審査を通過しました。
自動更新購読 (Auto-Renewable subscriptions) による月額プレミアム会員がスタートしました。
プレミアム会員になると、季節ごとのバックナンバーが聴取できるようになるほか、すべての画面で広告が非表示になります。
主な変更点
- 自動更新購読 (Auto-Renewable subscriptions) によるプレミアム機能の追加
関連リンク
2011-07-15
ColorChooser が便利
カラーピッカーで選択した色を自動的に UIColor や NSColor のコードに変換してくれるユーティリティです。
同様のものに Developer Color Picker がありますが、 それのメニュー常駐版のような感じです。
コードを書いているときにどこからでも呼び出せるので私はこちらのほうが便利だなと思います。
2011-07-12
UINavigationBar に複数の UIBarButtonItem を配置するには
UINavigationBar は基本的に左右 (leftBarButtnItem, rightarButtonItem) に一つずつしかボタンを配置することができません。
しかし、ちょっと工夫をするとその制限を突破することができます。
(まあ物理的なスペースの関係でせいぜい2つか3つがやっとなのですけどね)
方法その1. UIToolbar を UIBarButtonItem として配置し、その中に UIBarButtonItem を並べる
もっとも見た目がキレイに仕上がる方法です。
UINavigationBar の leftBarButtnItem と rightarButtonItem は UIBarButtonItem のインスタンスをそれぞれ1つずつしか代入できませんが、UIToolbar を UIBarButtonItem として作成することで、その UIToolbar に複数のボタンを配置することができるようになります。
UIBarButtonItem *sendButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Send", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(send:)]; UIBarButtonItem *cameraButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(cancel:)]; cameraButton.style = UIBarButtonItemStyleBordered; UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIToolbar *toolbar = [[MyToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 110.0f, 44.0f)]; toolbar.backgroundColor = [UIColor clearColor]; toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight; UIBarButtonItem *toolbarBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:toolbar]; [toolbar release]; toolbar.items = [NSArray arrayWithObjects:space, cameraButton, sendButton, nil]; [space release]; [cameraButton release]; [sendButton release]; self.navigationItem.rightBarButtonItem = toolbarBarButtonItem; [toolbarBarButtonItem release];
ただ、標準の UIToolbar の外観は UINavigationBar の外観と微妙な差異があるので、このままでは境界が目立ってしまいます。
そこで UIToolbar のサブクラスを作成し、空の drawRect: メソッドでオーバーライドし、標準の描画を無効にします。
@interface MyToolbar : UIToolbar @end @implementation MyToolbar - (void)drawRect:(CGRect)rect { } @end
すると、このような状態になります。
真っ黒になってしまったので、背景色を透明に設定します。
drawRect: メソッドの処理は backgroundColor と無関係というのがミソですね。
toolbar.backgroundColor = [UIColor clearColor];
キレイになりました。
もし、横方向の画面をサポートする場合、ナビゲーションバーは横方向では 30 ピクセルの幅に変わりますので、ツールバーの autoresizingMask プロパティに UIViewAutoresizingFlexibleHeight を設定しておきましょう。
toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight;
UIViewAutoresizingFlexibleHeight を指定しない場合は下のようになります。すこしボタンの大きさがアンバランスですね。
色をつけると違いが分かりやすくなります。
tintColor を設定すれば色も変えられます。
方法その2. UISegmentedControl をボタンのように使用する
標準のメールアプリでも採用されている方法です。
メールアプリの「前へ」「次へ」のように同じような動作をするボタンを並べる場合は良い方法だと思います。
titleView プロパティに乗せると3つのボタンを並べても余裕があります。
UISegmentedControl をボタンとして使用するには、momentary プロパティを YES に、アクションは UIControlEventValueChanged を設定します。
segmentedControl = [[UISegmentedControl alloc] initWithItems:items]; segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; segmentedControl.momentary = YES; segmentedControl.frame = CGRectMake(segmentedControl.frame.origin.x, segmentedControl.frame.origin.y, segmentedControl.frame.size.width + 16.0f * [items count], segmentedControl.frame.size.height); [segmentedControl addTarget:self action:@selector(segmentedControlAction:) forControlEvents:UIControlEventValueChanged]; [self.navigationItem setTitleView:segmentedControl]; [segmentedControl release];
方法その3. UIToolbar を上部のナビゲーションバーの位置に配置する
簡単ですがオススメしません。
というのも UIToolbar は画面の下部に配置するようにデザインされているため、上部に配置するとどうしても外観に違和感がでてしまうからです。
(iOS 4.x までの iPhone の場合。iPad のツールバーは上下どちらに配置してもいいようにデザインされている。)
ナビゲーションバーの位置に配置したツールバー。
ステータスバーとの境界が不自然ですね。
2011-05-05
NSNull のインスタンスは nil として振舞ってくれると嬉しいなって
NSNullはnilとして振舞うべきじゃないかなー。unrecognized selectorで例外なげるんじゃなくて。
@k_katsumi 私もそう思います。サブクラス化するなりカテゴリで上書きするなりして nil として振る舞えるようにできないですかね?
@griffin_stewie URL こんな感じでOKっす。
2011-04-11 21:47:58 via Echofon to @griffin_stewie
@k_katsumi おお!でも、カテゴリで既存メソッドの上書きはあんまりやりたくないですね。
とか思ってたのですが、そう考える人はやっぱりほかにもいるようです。
NSNullはどんなメッセージ送ってもnilを返してほしいなぁ
たとえば私がいちばん面倒だなと思うのはjson-frameworkがnullをNSNullにマッピングするので(nilはNSArrayやNSDictionaryに格納できないため)でWeb APIからのレスポンスをParseする際に、値がセットされるときとnullがセットされるときと両方あるような場合、ハンドリングがとたんに面倒になるのですね。
NSString *results = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; NSDictionary *dic = [results JSONValue]; NSString *shortURL = [[[dic objectForKey:@"results"] objectForKey:longURL] objectForKey:@"shortUrl"];
上記の場合、longURL の値が NSNull だったとすると objectForKey: の呼び出しが失敗してクラッシュします。
このとき NSNull が nil だとしたら、nil へのメッセージは単に無視されるので問題ないわけなのでそうなっていたら便利なのにという話です。
というわけで、下記のようなカテゴリをどこかに書いておくと、NSNull へのメッセージはすべて無視されるので、まるで nil のように扱えて便利です。
何をしているかというと、メッセージフォワーディングの仕組みが動作するように methodSignatureForSelector: および forwardInvocation: をオーバーライドします。
そうすると存在しないメソッドを呼びだそうとするとこれらのメソッドが呼ばれるので、forwardInvocation: メソッドで NSNull に存在しないメソッドの呼び出しは無視するように処理を変更しています。
[参考]Does Objective-C use short-circuit evaluation? - Stack Overflow
@implementation NSNull(IgnoreMessages) - (void)forwardInvocation:(NSInvocation *)anInvocation { if ([self respondsToSelector:[anInvocation selector]]) { [anInvocation invokeWithTarget:self]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { NSMethodSignature *sig=[[NSNull class] instanceMethodSignatureForSelector:aSelector]; // Just return some meaningless signature if (sig == nil) { sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"]; } return sig; } @end
2011-04-04
MKMapView に CATransform3D を適用するときの注意
MKMapView 3DTransformするとおかしくなるな。残念。鳥瞰図みたいなの表示したかったんだけど。
@junpeiwada ちょいと調べてみました。transformはsuperviewに当てて、その後mapViewにCATransform3DInvertで打ち消すといいんじゃないでしょうか。それをregionWillChangeで毎回。ズームができなくなるのはこれで治りました
2011-04-04 20:29:39 via Echofon to @junpeiwada
@junpeiwadaさんがつぶやいてたので気になって調べてみました。
- (void)viewDidLoad { [super viewDidLoad]; CATransform3D transform = CATransform3DIdentity; transform.m34 = 1.0f / -500.0f; transform = CATransform3DRotate(transform, 60.0f * M_PI / 180.0f, 1.0f, 0.0f, 0.0f); mapView.layer.transform = transform; }
こんなふうに書いてみたところ、どうもズーム機能が正常に動作しなくなるようです。
(ズームはするけど拡大率に合わせて再描画してくれない)
で、いろいろ試した結果、どうやら mapView の親ビューのレイヤーに transform を適用した上で、mapView のレイヤーにはその逆行列を適用することで打ち消してあげると正しく動作するようです。
(単純に親ビューのレイヤーに適用するだけではダメ。親ビューのレイヤーに適用した transform は自動的にサブビューのレイヤーにも適用されるので。)
下記がコード例です。
- (void)viewDidLoad { [super viewDidLoad]; CATransform3D transform = CATransform3DIdentity; transform.m34 = 1.0f / -500.0f; transform = CATransform3DRotate(transform, 60.0f * M_PI / 180.0f, 1.0f, 0.0f, 0.0f); contentView.layer.transform = transform; // mapView に逆行列を適用する CATransform3D t = CATransform3DInvert(transform); mapView.layer.transform = t; }
実行した結果は下のようになります。ちゃんとズームできてますね。
ちなみに、ズームできなくなるのは行列の m34 要素を変更したときのみで、単に回転やスケールするだけなら問題ないぽいです。
2011-03-29
kotobank for iPhone 1.0.0 がリリースされました。

私がプログラムを担当しました、kotobank for iPhone 1.0.0 がリリースされました。
データを内部に持ち、オフラインで使用できる辞書アプリケーションです。
このアプリケーションの特長は、複数の辞書を一度に横断検索できる点です。
初期状態では付属しているポケットプログレッシブ国語辞典だけの検索になりますが、追加の辞書を購入することでひとつの言葉をいろいろな辞書で一度に調べられます。
以下が初期状態の検索結果です。
現在、購入可能な辞書をすべてインストールした場合、同じ語でも次のような結果になります。
「企業がわかる事典」など、普段あまり使わない辞書に意外な結果が出ておもしろかったりします。
検索結果を選択すると、詳しい意味を見ることができます。
この画面からは、調べた単語を単語帳に登録したり、メールで送信することができます。
また、この画面からさらに気になる言葉を選択して、検索しなおすことが可能です。
この機能でどんどん言葉を検索していくと、ついつい時間をわすれてしまいそうになります。
単語帳に登録した言葉は、単語帳タブの画面から見ることができます。
アプリケーションのストアから辞書を購入して追加することができます。
現在は「プログレッシブ和英中辞典 第3版」「プログレッシブ英和中辞典 第4版」「企業がわかる事典」の3つが購入できます。
和英と英和辞書はそれぞれ 1,600 円ですが、「英和中辞典セット」という商品を購入すると、2,000 円で両方の辞書を一度に購入できるのでおトクです。
そのほか、普段あまり使用しない辞書は検索対象外にしたり、ひとつの辞書だけで検索したりといった設定ができます。
ということで、辞書を追加していくことでどんどん調べる楽しさが増えていくアプリケーションです。
ぜひダウンロードして使ってみてくださいませ。
関連リンク
2011-03-24
LCD Clock HD 1.1.2 がリリースされました。

バージョン 1.1.2 がアップルの審査を通過しました。
iOS 4.3の動作と、日本以外の国において2011年後半の移動休日のデータを更新しました。
変更点
- iOS 4.3の動作を確認しました。
- 日本以外の国において2011年後半の移動休日のデータを更新しました。
2011-03-17
LCD Clock 4.0.2 をリリースしました。

iOS 4.3の動作と、日本以外の国において2011年後半の移動休日のデータを更新しました。
変更点
- iOS 4.3の動作を確認しました。
- 日本以外の国において2011年後半の移動休日のデータを更新しました。
iPhone アプリにおいて Interface Builder を使って Grouped Style の UITableView を作るときは separatorStyle の値に注意
iPhone, Xcode, Objective-C, Cocoa
Grouped スタイルのテーブルビューを使用した iPhone アプリケーションの中に、下の画像のように先頭セクションの区切り線が2重に表示されているものをチラホラ見かけます。
実用上の問題は無いのですが、ちょっと不恰好なので気になりますよね。
この現象は、UITableView の separatorStyle に UITableViewCellSeparatorStyleSingleLineEtched が指定されていることが原因で発生します。
コードでインスタンスを生成した場合の separatorStyle デフォルト値は UITableViewCellSeparatorStyleSingleLine なのですが、Interface Builder で UITableView を Grouped スタイルで作成した場合はデフォルト値として UITableViewCellSeparatorStyleSingleLineEtched が自動的に選択されるようになりました。
(もともとはそんなことはなかったのですが、UITableViewCellSeparatorStyleSingleLineEtched が iOS SDK 3.2 から導入され、おそらくそのあたりのタイミングで動作が変更されたようです。)
ということですので、iPhone の場合に Grouped スタイルのテーブルビューを Interface Builder を使って作成するときは、separatorStyle の値を UITableViewCellSeparatorStyleSingleLine など、UITableViewCellSeparatorStyleSingleLineEtched 以外に設定しましょう。
コードでインスタンスを生成した場合のデフォルト値は UITableViewCellSeparatorStyleSingleLine ですので問題はありません。
公式のドキュメントによる言及が見つからないのですが、UITableViewCellSeparatorStyleSingleLineEtchedは(おそらく)iPad 専用の値です。
次のように iPad で Grouped Style のテーブルに対して指定した場合はキレイにハマります。
というわけで、コードで作る場合にはデフォルト値はドキュメントに書いてあるとおりなのですが、Interface Builder を使って作る場合にはデフォルト値は (IB が空気を読んで?) ドキュメントと異なる場合が多いので注意したほうがいいですね。
Interface Builder で作った場合とコードで書いた場合のデフォルト値の違いは、ほかにも各種ビューの backgroundColor や autoresizingMask などがありますので、余計な色が付いていないかどうかなど、きちんと確認したほうがいいでしょう。


















































