こんにちは。きんくまです。
HabitKeeperがバージョン1.2にアップデートしました。
今、年末年始セールやっているので、よかったらチェックしてみてくださいませ。
今回のアップデートは、新規リピート機能の追加です。月のうちの特定の日の指定が可能になりました。
こんな感じです。
それで、次回のバージョンはiCloud対応させようと勉強中です。
いろいろと考慮しなくちゃいけないことなどが多く、ムズイですね、、。
後回しにしちゃおうかな、、。
その他にもいろいろとユーザーの方からご要望をいただいているので、そちらも実装していきたいと思っておりますです。
んで、宣伝ばっかりだとつまんないので、今回のアップデートで使ったライブラリとか、テクとかの紹介です。
MBProgressHUD
MBProgressHUDはAndroidのToastみたいな機能を実装するライブラリです。
ポップアップでいろいろ表示できます。
今回はDBのマイグレーション作業中に出すポップアップに使いました。
ライブラリといっても、.hと.mの2ファイルだけの軽量なものです。
メインスレッドで、ポップアップを出しつつ、バックグラウンドで指定したことをしてくれます。
ソースちょっとみたらGCD使ってました。
サンプルプロジェクトを立ち上げれば、どんなものか一通りわかると思います。
HabitKeeperは他に特にライブラリとか使ってなくて、グラフ機能も自作だったりします。
(グラフのライブラリ調べたのだけど、合うやつがなかったのです。なので、もうちょっと作り込みが必要だったりするのだ、、。)
それで、ちょっと前にiOSのチュートリアルサイトのRAYWENDERLICHで人気ライブラリの投票をやってまして。
そこで、上位に入っていたのがこのMBProgressHUDでした。
>> Top 10 Most Useful iOS Libraries to Know and Love
使い方も簡単なので、そんなに人気なら大丈夫だろうと思い今回使用しました。
1から31日のフラグを4バイトにおさめるビット演算
今回のアップデートでは、1から31日までのどの日にチェックするかのフラグを管理する必要がありました。
CoreDataのAttributeで31個のBooleanフラグを立てても良いのですが、さすがに見た目が悪いのと、イマイチな実装だと思いました。
それで、ずっと前にやったプチコンでのビット演算でのフラグ管理の話を思い出しまして。
AttributeでInteger32 = 4バイトであれば、4バイト = 32ビットあるので、31個のフラグが管理できそうです。
これで1つのAttributeで31個のフラグを管理することができます。
おおこれは使うしかないと思い、今回やってみました。
ビット演算によるフラグ管理は、端末のスペックが弱かった昔のゲームなどでは使われたみたいですが、今はどうだかしらないです。
あと、今回のようにDBの容量節約+日付という同一のものを管理する今回の場合には大丈夫だと思うのですが、最近はあまり推奨されてないみたいです。
理由は単純にわかりづらいから。なんで、使いどころには注意が必要だと思います。
例えば、全然関係ないものをひとつのIntegerに入れてしまうとか。
実際のコードです。こんな感じのメソッドを用意します。
- (BOOL)specificDateFlagInFlags:(NSUInteger)flags date:(NSInteger)date { if(date < 1 || date > 31){ [NSException raise:@"date range error" format:@"date %d is out of range", date]; } BOOL flag = (flags & (1 << (date - 1))) ? YES : NO; return flag; } - (NSUInteger)setSpecificDateFlagInFlags:(NSUInteger)flags flag:(BOOL)flag date:(NSInteger)date { if(date < 1 || date > 31){ [NSException raise:@"date range error" format:@"date %d is out of range", date]; } if(flag == YES){ flags = flags | (1 << (date - 1)); }else{ flags = flags & (~(1 << (date - 1))); } return flags; } //see http://stackoverflow.com/questions/1286425/nsstring-to-print-in-in-binary-format - (NSString *)getBitStringForInt:(int)value { NSString *bits = @""; for(int i = 0; i < 32; i ++) { bits = [NSString stringWithFormat:@"%i%@", value & (1 << i) ? 1 : 0, bits]; } return bits; }
使ってみます。
NSUInteger flags = 0; //初期状態 //1日のフラグを立てる flags = [self setSpecificDateFlagInFlags:flags flag:YES date:1]; //中身を見てみる NSLog(@"test1 = %@", [self getBitStringForInt:flags]); //18日のフラグを立てる flags = [self setSpecificDateFlagInFlags:flags flag:YES date:18]; //中身を見てみる NSLog(@"test2 = %@", [self getBitStringForInt:flags]); //5, 24, 31日のフラグを立てる flags = [self setSpecificDateFlagInFlags:flags flag:YES date:5]; flags = [self setSpecificDateFlagInFlags:flags flag:YES date:24]; flags = [self setSpecificDateFlagInFlags:flags flag:YES date:31]; //中身を見てみる NSLog(@"test3 = %@", [self getBitStringForInt:flags]); //5日のフラグを調べる NSLog(@"day5 is %d", [self specificDateFlagInFlags:flags date:5]); //8日のフラグを調べる NSLog(@"day8 is %d", [self specificDateFlagInFlags:flags date:8]); //18, 24, 31日のフラグを下ろす flags = [self setSpecificDateFlagInFlags:flags flag:NO date:18]; flags = [self setSpecificDateFlagInFlags:flags flag:NO date:24]; flags = [self setSpecificDateFlagInFlags:flags flag:NO date:31]; //中身を見てみる NSLog(@"test4 = %@", [self getBitStringForInt:flags]);
出力結果です。特定の日のビットがたっているのがわかると思います。
test1 = 00000000000000000000000000000001 test2 = 00000000000000100000000000000001 test3 = 01000000100000100000000000010001 day5 is 1 day8 is 0 test4 = 00000000000000000000000000010001
というわけで、最近のプログラム環境では使いどころの難しいビット演算ですが、たまには役に立つのだ。
というお話でした。
興味のある人はググってみると良いかもです。
>> ビット演算
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ