2012年12月12日水曜日

ルンバがメンバー入り


本日、とうとう我が家にルンバが登場しました。
ルンバ 780。現状の最上位モデル。
節約モードの私に変わり、旦那様が昨日ポチられた!やったね!

ラグマットの上だろうが、ちょっとした段差だろうがガシガシ進む。
思った以上にパワフル。

とりあえず動かしてみたところ、1つの部屋でうろうろ。
もう1つの部屋にはなかなかお掃除をしてくれない。
バーチャルウォールと、ライトハウスの機能は必須なのを実感しました。

「時間かけていいからやっといてね」というスタンスの商品なので、じーっと動きをみてイライラする方が違いそうですけども...やっぱ最初はかわいいのでみちゃいますよねw

毎日定時に動作するようにしておけば、かーなーりお部屋が綺麗になりそうな予感。

うさうさにルンバを会わせたかった。
たぶん、足をバンバンして敵意むき出しにしたんだろうなーーっ

• • •

2012年12月2日日曜日

退職しました

先月をもって、退職いたしました。
プレイシズには、1年と少しの間、大変お世話になりました。ありがとうございました!

退職の理由は会社の解散ということで、いろいろ悔いの気持ちがあります。
反面、私自身についての経験値はとても濃いものでした。
- アプリ開発をしよう!とチャレンジするタイミングで参画できたこと。
- 同じフィールドにたった状態で、デザイナーさんから意見をいろいろ聞けたこと。
- アプリ開発での収益をあげるのがとても難しいこと。
- 便利と思うようなUIを考えたり、少しの驚きを加える時の生みの苦しさ。

・・・と一般的なこともありますが、

形をなかなかイメージ出来ないときに、"こうすると良いのでは?"のアドバイスをもらえる、ほりさん。
発想もしなかった視点でのアドバイスで新たな発想を生み出してくれる、えつこさん。
とても素敵な組み合わせでした。

そのメンバーが解散してしまうのはとても残念なのですが、これからもゆるく付き合っていけそうな感じ。退職後もそういう関係が出来るのは本当にありがたいです。

今後はやはりスマートフォン/タブレットのアプリ開発をもう少し続けて、壁を突破してみたい と思っています。
具体的に何の壁なのかは言葉ではいい表せないですが、あるのです。突破してみたい壁が。

収益をあげるためには、ゲームでアプリ内課金を... が現状の常套手段ですが、私が作りたいものはもっと、コンピューターに任せるようなものは任せることにより、生活が便利になるようなものを作りたい。
ゲームで時間を無駄につかってしまった。 というよりも、時間を有効活用しているようになった と思うようなアプリ達を作りたい。
(来年には違う事を思っているかもしれませんが!w)

そして.... 正直な本音としては、
使いやすい画面とは。楽しくなる画面とは。使いやすい部品とは。良いアプリとは。
というのを、たくさん見る。作る。 をもっとしてみたい。

私の職業はプログラマーですが、素敵と思えるものがやっぱり大好きだということを実感した1年でもありました。
よいデザインだったり主旨が明確なUIだと、実装を作るのにテンションMAXで作業しちゃうのですが、
逆にそうでもないと、(できもしないのに)あれやーこれやーといじって時間を浪費したり。

標準UIもよく出来ていているのですが・・・ちょっと脱線してみたい。脱線した後、やっぱり標準に戻るのかもしれないけども、それでも良いかなと思っています。多分、その道のりは無駄じゃないはず。

そんな脱線は、当然、会社ではなかなかできない。実際作らないと体感できない。
趣味程度ささっと作れたとしても、よい製品としてリリースできる精度にあげるのが実はとっても大変で重要。
でも、私が得たい経験値はそこなんですよね。今は。

最初に画面構成を考えたタイミングでは、どうしてもWEBサイトのような階層形式な画面遷移で書いてしまいます。
でも、動かしてみたり、ゆっくり考えてみたりすると、まったく違う構成になったりするのです。何画面も想定していたけど、実は1画面になった とか。その逆も。

いろいろ情報を置けたWEBサイトに比べ、アプリは狭い画面というハードルがあるので本当に必要なものは何なのか?を考えないといけない苦しみがある反面、良い強制ギブスでもある。それがあるから、「WEBよりもアプリの方が使いやすい」 みたいなサービスもでてきたりもするのでしょう。

今後については... このよい機会をもらったととらえて、個人の活動で経験値をあげていこうと思っています。
"ObjectiveCが書けるプログラマー" を脱出し "アプリ作成のプロ" を目指して!

最後になりましたが、
アプリ作成の場を与えてくれたプレイシズの皆様、本当にありがとうございました!
そしてこれからも、よろしくおつきあいくださいませ!


• • •

2012年11月17日土曜日

iOSの日付処理まとめ

日付処理をするとき、どーだったっけ.. と迷うので私なりにまとめ。

日付関連の要素


NSCalendar

[NSCalendar currentCalendar]
[NSCalendar autoupdatingCurrentCalendar]

OSの設定 > 一般 > 言語環境 > カレンダー によって変わる。
「和暦」になっていると、NSJapaneseCalendar
「西暦」になっていると、NSGregorianCalendar 

Calendarには、後述の TimeZoneやLocale を保持しています。
autoupdatingCurrentCalendar は、ユーザが変更した内容を自動的に反映してくれるカレンダー。
クラス変数としてカレンダーを保持する場合などはこちらを使用するとよいかも。
だけど、保持せず使うタイミングで取得するのであれば、[NSCalendar currentCalendar] のままでよさそう。

NSDateFormatterで "yyyy-MM-dd" のようなフォーマットを使用している場合には、OSのカレンダー設定で和暦の設定されている場合に注意。

常に西暦で処理したい場合には、
[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]
NGregorianCalendarを作成して、NSDateFormatterなどに設定して使用します。

NSTimeZone

[NSTimeZone defaultTimeZone]
[NSTimeZone systemTimeZone]
[NSTimeZone localTimeZone]

OSの設定 > 一般 > 日付と時刻 > 時間帯 によって変わる。

時差を管理するもの。これは分かりやすい。
日本だったら、GMT +0900 / JST
NSDateFormatter などを init すると、OSの設定が入ります。

基本、あまり入れ替えることはないはず。あるとしたら、各国での時間を表示するときぐらいかな?
アプリ内部で日時情報を保持する場合には、
[NSDate timeIntervalSince1970] のGMT +0000 での経過時間で管理して、表示時にOS設定のCalendar, TimeZoneを使って 年月時間を表記 というのが素直な方法。

TimeZoneにはDaylightSavingTime(サマータイム)の情報も含みます。

NSLocale

[NSLocale currentLocale]
[NSLocale systemLocale]
[NSLocale autoUpdatingCurrentLocale]

OSの設定 > 一般 > 言語環境 > 書式 
OSの設定 > 一般 > 日付と時刻 > 24時間表示
などによって変わる。

国毎に変わるもの(フォーマットなど)を管理。
日本 : 「11月」 アメリカ:「November」
日本 : 「午前」  アメリカ : 「AM」
とかお金の単位とか文字が変わるのもあるし、文章の方向とか、カンマ と ピリオドの扱いとか国によって違うものが管理されています。

全世界で使われるようなアプリでは、それらの差を自分で書かないといけない... ところをLocaleを設定してFormatterに処理を任せるようにすれば対応できてしまう、本当はありがたいもの。ハマる所でもありますが。

逆に、ここは常に英語の表記したいのになーー  という場合には
[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
と自分でLocale作成して設定もできます。

cunnretLocaleはユーザがOSの設定でしている情報。
systemLocaleは端末でフォルトの情報。

NSDate

GMTの経過時間(NSTimerInterval)を保持している。
Calendarなどの概念が含んでいないのでtimezoneが違っても同じものとして扱える。
内部で保持するデータモデル的クラスです。
UI上に表示する場合には、NSDate と、上記Calendarなどを組み合わせて日時をフォーマットして表示する感じ。


日付を扱うクラス


NSDateFormatter

@"yyyy-MM-dd HH:mm:ss" でフォーマットを指定しているのに、

「0024-11-16 21:09:17」になっちゃった!
(カレンダーに和暦が設定されているとき)

「2012-11-17 午後11:07:47」 になっちゃった!
(24時間表示の設定がOFFのとき)

とういのが、あるある 事件。
カレンダーについてはNSDateFormatterにNSGregorianCalendarを設定して、
24表示については、Localeに[NSLocale systemLocale]をすると上手くいきます。

systemLocaleにすると24時間表示になる理由はわからず。。
どのパラメータが影響しているのだろうかー。

OSで設定されている日付フォーマットに沿って文字列を生成するには
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle: NSDateFormatterShortStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
NSString *dateStr = [formatter stringFromDate:date];
のようにします。
日付部分のフォーマット、時間部分のフォーマット を CFDateFormatterStyle の定数で指定します。CFDateFormatterNoStyle を指定すると表示なしになるので時間だけを表示ということも可能。

NSDateComponent

NSCalendar と NSDate から、年、月、日、時間 などの取得や、日付計算ができる。

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponent *comp = [calendar components:params fromDate:[NSDate date]];

本日の00:00:00のNSDateを取得
NSDateComponent *comp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[NSDate date]];
NSDate *date = [calendar dateFromComponents:comp];

1日後のNSDateを取得
NSDateComponent *comp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[NSDate date]];
comp.day += 1;
NSDate *date = [calendar dateFromComponents:comp];

2つのNSDateの日数を取得
NSDate *fromDate;
NSDate *toDate;
NSDateComponent *comp = [calendar components:NSDayCalendarUnit fromDate:fromDate toDate:toDate options:0];
NSInteger between = comp.day;

曜日を取得
NSDateComponent *comp = [calendar components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger weekday = comp.weekday;

曜日の文字列は、NSDateFormatter の weekdaySymbols から取得できるけど、曜日の並び順番がズレているので注意。

NSDatePicker

これに先日ハマっていた...

DatePickerにGrigorianCalendarを設定する

NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
datePicker.calendar = gregorian;

iOSの設定で、24表示無し(AM PM表示) にしているとき
iOS5(iPhone4S)の端末では、AM PM表示になるのに、
iOS6(iPhone5)の端末では、24時間表示になってしまう。

NSDateFormatter では Locale を SystemLocaleにすると24時間表示にできたが、
DatePickerのLocale、設定するCalendarのLocale ともにSystemLocaleにしても、24時間表示にはならない。

端末設定に依存せず、常に24時間表示にする方法はわからず。

NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
gregorian.locale = [NSLocale currentLocale];
datePicker.calendar = gregorian;

...と 自作したGregorianカレンダーのLocaleにCurrentLocaleを設定すると、iOS5,6ともに設定された24時間表示どおりになるようです。

• • •

2012年11月4日日曜日

CoCafe ver2.0 リリース!



CoCafeがVer2.0になりました!

CoCafeは、GooglePlaceAPI(Googleローカル)を使っているのですが、このAPIはGoogleマップ上に取得結果を表示しないといけない という規約があります。

ご存知の通り、iOS6からはGoogleマップではなく、Appleのマップに代わり規約違反状態に....
これはマズイ!マズイ! ということで、Googleマップでの表示になるように修正を加えるとともにUIも一新しました。

Googleマップを表示する方法としては、
WebViewをつかってWeb表示にする という方法と、
地図の画像を取得してきてiOSのMapKit地図上にタイルとしてペタペタ貼るという方法が考えるのですが、後者も規約違反らしい。

Google Maps/Google Earth APIs Terms of Service より
10.1.1. General Restrictions. 
(a) No Access to Maps API(s) except through the Service. You must not access or use the Maps API(s) or any Content through any technology or means other than those provided in the Service, or through other explicitly authorized means Google may designate. For example, you must not access map tiles or imagery through interfaces or channels (including undocumented Google interfaces) other than the Maps API(s).

ということで、WebViewと使って今までと同じ機能になるように @shin1ogawaの協力も得つつ仕上がりました!

WebViewなので表示にもっさり感。でもGoogleマップの安心感があります!w
AppleStoreにあるGoogleマップではさくさく動くのがあるのだけど、タイル使ってるんじゃないかなぁーという密かな疑惑中...

iOS5ではネイティブマップ(Googleマップ)を使い、
iOS6以上ではWebViewでマップを使うようになっています。
やっぱり、ネイティブマップの方がサクサク動くのでiOS5はネイティブの実装で。

もう一つの大きな変更がUIの変更。
今までのものは、検索結果のマップ表示 と 一覧リスト を切り替えで表示 する仕組みでしたが、これだと、
「一覧リストでみたお店をマップのどこにあるかを表示」という事ができなくて不便でした。
これを満たすためには、マップ表示と、一覧表示を同じ画面に表示する必要があるなーーということで...
こんな感じで、マップをスライドさせて一覧が見れるようにしました。
行を選択すると、マップ上で選択したお店が中心に移動してお店名の吹き出しがでます。
ボタン類の所を、左右にドラッグするとマップがスライドするように出来ているのと、お店の詳細画面も左から右へのスワイプでマップに戻るように出来ているので、
検索 → 一覧を見る → マップ上で場所確認
のようなよく行う事が片手でも出来るように工夫しています。

FIND の 下の真ん中にある
のボタンは、表示中マップの中心から再検索 というボタンです。
マップをズイズイと移動したら、このボタンタップで再検索してみてくださいね!

次はコンパス機能を使って、どっちの方向を向いているか?
を実装できたらなぁーー とか思っています。



CoCafe
価格 : 無料 (広告非表示は250円)
カテゴリ : ナビゲーション
対応機種 : iPhone
対応OS : iOS5.0以上

• • •

2012年10月19日金曜日

実践 スマートフォンアプリケーション開発




実践 スマートフォンアプリケーション開発 の献本頂きました。
ずっしりと大きい堂々の541ページ! 

この本は、iPhone, Android, WindowsPhone についていろんな側面から比較されています。
スマートフォンと一言でいってもiPhone, Android, WindowsPhone のプラットフォームにより、
  • 機能としてできること/できないこと
  • 用意しないといけないリソース類
  • 申請に必要なこと
...などなど差があります。
それらの差はどんなものがあるのか? というのが比較されているので、

  • スマートフォンアプリを作ってみたいと思っているが、iPhone, Android, WindowsPhone... どれでいこうか? と悩んでいるの方。
  • iPhoneアプリ/ Androidアプリ の開発者だけど、他のプラットフォームにも手を出したいと考えている方。
  • iPhoneアプリ/ Androidアプリ のデザイナーだけど、他のプラットフォームにも手を出してみたいと考えている方。
  • iPhoneアプリ/ Androidアプリ をリリース済みだが、他のプラットフォームにも出せるか検討してみたい人。
  • iPhone,Android, WindowsPhone 上で使われているUIの名前を覚えたい人 

などなどの方には、手っ取り早く比較ができるのでとても助かると思います。
WEB上で情報を拾おうとすると結構大変なはず。
目次から見たい内容を引けるので辞書的に手元においておくと便利そうです。

ページ数は多いですが、内容は難しくないです。
逆に、3つを比較するためにはこんなにページ数がいる情報になるんだなー こりゃ大変! と思いました。

私は、iPhoneばかりやっていたので、
通知バーとかシステムトレイとか...Android,WindowsPhone上の名前は良く混乱しますw
正確な名前がわからないと検索もできないし、会話もできないので名前ってとても重要!

WindowsPhoneはやりたい...というか、やらねばあかんやろっ いつかはっ
と思っているのでとてもためになりました。

発売日は2012/10/24で、現在予約受付中です。
興味ある方はぜひどうぞ!


最後に、レビュー時に声をかけてくれた @hyoromo さんに感謝! おつかれさまでした!

• • •

2012年10月12日金曜日

1日は24×60×60秒とは限らない

24×60×60=86,400秒 ではない日 というのは、
サマータイム や DST(daylight saving time) の開始日/終了日。

本日の日付の00時00分00秒を起点にして、
1日後は + 24×60×60
2日後は + 2 × (24×60×60)
のような感じで作っていくと、計算が合わなくなります。

カレンダーを使って、ちゃんと日付をとりましょう。

NSCalendar *cal = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *today = [NSDate date];

NSDateComponents *components = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];
components.day += 1;
 NSDate *tomorrow = [cal dateFromComponents:components];

かく言う私は、このバグを埋め込んでしまった人。
時間で足した方が、処理も早いやん!と単純な発想でミス。

「英語圏の人はIMEに不具合いれてくるわー」とぼやいていた私ですが、逆に私もやってしまった感。
気をつけます...
• • •

2012年10月2日火曜日

iPhone5は縦長だ!

4インチ iPhone5 皆様楽しんでいらっしゃるでしょうか! 
実機を手に取って操作すると、縦長になった事にはすぐに慣れ、 iPhone4に戻ると
ちっさ! 使いづらい!!
と思うようになってきました (笑)

 使う立場からみるとそんな事を思う訳ですが、アプリ開発者の立場から見るとかなりの大きなサイズ変更で、うわーーっ となります。
テーブル表示のように元々縦長のコンテンツをスクロールで表示していたような画面では特に問題ないのですが、画面ぴったりのサイズに合うようにデザインしていた画面では、最悪デザインしなおしの勢いが必要なのではないかと思います。 

どんな対応にすべきかは、画面の内容次第。
少し、例をあげてみる。


ある部分を縦にのばせばOKなパターン 

Path の詳細画面は地図部分を縦にのばす対応をしている。
こんな感じで対応できるのであれば、自然な感じだしまだ楽デス。

 

サイズは一緒で場所だけいじるパターン

標準アプリ 時計 のタイマー は、ドラムの部分以下全てが下寄せになっている。
これでおかしく見えないのは、ドラムの位置が タブバーを除いた画面領域の中央ぐらいにあるようにみえるから... かな。



均等にサイズを大きくするパターン

標準アプリの電卓。
各ボタンの大きさが均等に縦長になるようになっています。



iPhone4ではスクロールしてみえるようにするパターン

Pintarestの詳細画面。
写真が入るような画面だと、写真の縦横比率を変える訳にいかないので難しいです。
iPhone5で綺麗にみえ、iPhone4だとスクロールしてね って妥協案は現実的かとおもう。



iPhone4とiPhone5でレイアウトを変えてしまうパターン

FreshPantryの詳細画面。
どーすっかなーといろいろ悩んで結局デザインを変えました。




今後は.....
縦のサイズが変わっても対応しやすいように、縦にスクロールして全てが見れる画面が増えるかもしれないですね。
でも、縦がのびたことにより、画面上部のボタンが、かーなーり押しにくくなりました。(遠い!)

手が小さい私としては、
よく押すボタンは下の方に配置
もしくは
スワイプなどの操作と関連して動作できる
というのが使い勝手と密接しそう。

どんなのが操作しやすいのか、しにくいのか というのは実際に操作しないと分からないので、はじめに紙上でデザインしてそのままOKになるのはよほど慣れた人だけなんじゃないのかなー と思う日々。

ま、それはそれで、面白くなってきたんじゃないの!? とも思う訳ですがw

• • •

2012年8月30日木曜日

PopWeight - 体重・体脂肪率記録アプリ でたよ!

本日、 体重・体脂肪率を記録するiPhoneアプリPopWeight をリリースしました!

このアプリの最大の特徴は、
1タップ&ドラッグ の操作で体重入力が完了できること。

よくある体重記録アプリは、

  1. 体重入力画面で値をぽちぽち入力し
  2. グラフ画面に移動して、昨日からの増減をチェック
という手順で使うことがほとんどだと思うのですが、どうせグラフで見るのであれば
  1. グラフ画面で体重を入力しつつ昨日からの増減をチェック
にして手順を減らしてしまおう!
というのがこのアプリです。

グラフ上の ◎ を LongTapして、ドラッグすると体重入力ができ、 ピンチイン/ピンチアウト するとグラフ表示期間が変更できます。
もち、横スクロールでどんどん過去の情報もみれる。

...とはいえ、このアプリを考え始めた当初からこの発想だったわけでなく、 よくある体重記録アプリと同じ画面設計をしていました。

  1. 体重を入力する画面
  2. グラフ表示画面 (1週間/1ヶ月/3ヶ月の切替ボタン付き)
という感じ。
一旦、この方針でアプリを作ったのですが、実際触ってみて、"これだったらさ..." と作り直しを繰り返し、今の方針のアプリになりました。

PLACES Inc.でリリースするiOSアプリは、4本目なのですが、実はこのアプリの内部コードは PL02 .... 2つ目に作り始めたアプリです。
いやー、リリースまでにこんなに時間かかるとはww

もう一つ、PLACES らしさが出ているのは テーマの切替があること。
さすがデザイン会社。後付けでなく最初からその話があった。
(そのため、アプリで画像を使っているところは、ほとんど無かったりします...!)

好きなデザインじゃないと、アプリ起動したくなくなる=続けられない というのは、誰にでもあるとは思うのですが、デザイン好きな女の人の目線だととーーーっても重要な事ですよねー。

私は、WiFi体重計のWithingsを持っているので、データ取り込み機能もつけてしまいました。
「あれ? じゃ結局入力しないんじゃ?」とかのツッコミされそうですが...(笑)

ちなみに、私は、アプリ開発期間の数ヶ月、そこそこ体重計に乗り続けたため、実は既に減量に成功 したというオチw

体重に興味がある方、ぜひお試しください!



PopWeight 体重記録
価格 : 170円
カテゴリ : ライフスタイル
対応機種 : iPhone
対応OS : iOS4.3以上
サポートページ : http://popweight.com/jp/
リリース日 : ver1.0 2012/08/30


• • •

2012年8月10日金曜日

XCode4.4にiOS4.3のシミュレータインストール@MountainLion

もうそろそろ情報もでてきただろうしいいかなー ってことで 昨日、MacOSをMountainLion化しました。

使っていたXCodeのバージョンはちょい古かったので、MountainLionでは使えなかったので、 AppStoreからXCode4.4をインストール。

シミュレータはiOS4.3のものが、まだ今の段階では欲しいのでインストールしたかったのに見当たらない!
Preferences > Downloads の中をみてもないじゃないですかー。

でも、私はしってるよー。
古いSDKのインストールだけして、/Developer の中にあるSDKをXCodeの中にいれればいいんでしょー!

参考:全霊長類待望の「iOS SDK5/Xcode4環境でiPhoneシミュレータをiOS4.2 iOS4.1 iOS4.0 でデバッグする方法」がわかった

もともとiOS4.3のシミュレータ動かしてからあるんじゃね?...が、MountainLionには /Developer のフォルダが無くなっている!
ひーーっ

幸いにも、まだLionのマシンでXCodeを入れていたものがあったのでそこからシミュレータのSDKを抜き出し、XCodeの中にいれる。
シミュレータの一覧にはでてきた。

が、実行するとエラー

やっぱりちゃんと入れないとダメなんすね。

ググってたら、stackoverflowにHow to install Simulator SDK 4.3 to Xcode 4.4 on Mountain Lion というスレッドを発見。

~/Library/Caches/com.apple.dt.Xcode/Downloads/eded78df8bfabaf6560841d10cf8e53766f74f28.dvtdownloadableindex
を直せってかいてあるけど、vimでみたらこれってバイナリファイル?
わからぬ。。

xcode_3.2.6_and_ios_sdk_4.3.dmg をとりあえずいれてSDKをコピーというコメントもあるのでこれで試してみる。 (いまココ)

11:15 追記
dmgをダウンロードしてインストール...を試みたのですが、 インストール場所を指定する方法がわからず...あきらめました。
そのままインストールするのはちょっとこわい。

ちなみに、インストール開始時に、セキュリティのためインストールできないよ 的なメッセージがでる時は、
設定 の Security & Privacy で
[Mac App Store and identified developers]
がデフォルトで選択されているのを、
[Anyware]
に変更するとインストール開始できました。

これが、以前噂できいていた、Mac App Storeからじゃないとアプリ入れられなくなるぜーー! という話のやつですかね。にゃるほど。

私は、Lionの環境のマシンもあるのでiOS4.3のシミュレータは最悪動かせるので、もう少し情報が集まるまでこのまままってみる。
開発マシンが1台しかない人は、MountainLionにあげるのは情報揃えてからにしたほうがよいよ!
というオチでw

• • •

2012年8月6日月曜日

CoCafe v1.4リリースしたよ!

CoCafe v1.4をリリースしました!
今回の修正は、以下になっています。
  • 新しいデザイン
  • Webの表示で前・次ボタンやリンクコピー機能追加
  • 起動時の初期画面がMapに変更
  • レスポンス向上
  • バグ修正

CoCafeは、Cafe検索ができる iPhoneアプリ。
特徴としては、
・登録情報が多い(Googleローカルの情報)
・wifi状況が登録/共有できる。
ちょこちょこと登録してくれる方も増え、
「わ!登録してくれている!!」と発見する事がたびたび出てきてとても嬉しいデス♪

でも、まだまだいろんな人に使ってほしー(登録してほしー)ということで、
v1.4リリース記念として、
広告非表示が ¥250 → ¥85 にセール中です!
8月20日までの期間限定なので、お見逃しなく!

GoogleローカルのAPIが、お店の写真とかを提供してくれたら、CoCafeでも出すように早速するんだけどなーー ...ということで、最近はGoogleローカルでお店の写真をできるだけ投稿するように頑張っております。

Googleローカルで投稿した写真って、自分のpicasa に [Google マップ用の写真]としてアップされるんですね。しらんかった。
こんな感じ

Googleローカルで投稿した写真だから、お店情報とリンクしてくれればいいのに、それもない。ちっ

picasaって、無料で使える容量制限あった気がするので、Googleローカルでいっぱい写真が見れるように頑張ると、これまた自腹を切って容量追加せねばならんのかーー?!
イケズだわー。もー。

• • •

2012年7月17日火曜日

UIKeyboardTypeDecimalPadの注意点

iOSのキーボードの種類UIKeyboardTypeにある UIKeyboardTypeDecimalPad。

このキーボードは、iOS4.1以上から使用できますが、iOS4.3.5の実機で試すと表示できない場合があるようです。
表示できない場合というのは、
対象画面表示直前に表示したキーボードが、
QWERTYキーボードであれば、DecimalPadになりますが
フリック入力(Japanese Keyboard)の場合、NumberPad(ピリオドなし)
になってしまいます。
iOS5ではこの現象は発生しないので、多分バグかなと。

QWERTYキーボードなのか、 フリック入力キーボードなのか の判別方法は見つけられず....
そうなると、iOS4.X以下の場合には、NumberPad を表示するようにして、ピリオドを自分で追加する感じにしてあげないといけなさそう。

ピリオドのボタンはどこに表示するか? ですが、
Keyboardの一番左下のボタンに乗せてDecimalPadのように見せるには、どのViewに載せるかが微妙。
Keyboardって、AppDelegateで渡ってくるWindowではなくて、UITextEffectsWindow っていう違うWindowで表示されているみたい。
NSArray *allWindows = [[UIApplication sharedApplication] windows];
のwindowsから取ってこれるが、あんまりやりたくない感じではあります。
参考 : How to add your own Done button to the iPhone numeric keypad

キーボードを入れ替えするのであれば、UITextField#inputView
キーボードの上部に載せるのであれば、UITextField#inputAccessoryView
のViewを入れ替えればいけそう。
こちらは、正式リファレンスにもあるので安心して使えますが、自分でデザイン、動作する必要はあります。

もう一つ、忘れがちなのが国際化対応アプリならば、小数点区切り が ドイツ、フランスでは ,(カンマ)であること。
.(ピリオド)固定でボタンを作らないように注意です。
NSString *decimalSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
これで区切り文字がとれます。

さらにもうひとつ。
Keyboardをタップする時に音が出るのが標準になっていると思うので、自作して追加したボタンタップ時にも音を出すのが自然。
iOSが出している音と同じものを出したくなりますが、どうやら正式なリファレンスには載っていないぽい?
AudioServices に、predefined system soundsの一覧が載っていますが... 正式リファレンスではないのでリジェクトされるかもしれないし、勝手に消えたり、変更されたりするだろうし... というのは自己責任で。
ちなみに、Keyboardタップ音は、
AudioServicesPlaySystemSound(1104);
ぽいです。

早く、iOS5以上の対応で問題ないぐらいまで、iOS4が消えて欲しいですw

• • •

2012年6月29日金曜日

Google+ History API

 GoogleIOでのGoogle+ History APIのセッション Advanced Google+ History APIを朝から見ていました。

HistoryAPIというのは、音楽を聞いた、動画を見た、購入した という行動のActivityを保存して、後から見ることが出来るもの。

APIドキュメントも公開されています。Google+ History API

今はDeveloperPreviewなので、みるためには、Google+ History APIにあるように、Sign upして、API Consoleで "Google+ History API" を ONにします。
そうすと、G+の画面でHistoryが選べるようになります。


プロフィールにもでてくる。

Activityの登録をするのは、基本はサードパーティ製アプリ。
デモではlast.fmをやっていたので、last.fmは提供してくれるかもしれないですね。
Sourceをみるとこんな感じになっていて、YouTubeの動画をみたらActivityとして登録されていました。

HistoryAPIでは、ActivityではなくMoments というみたい。 Momentsではいくつかの種類があります。

  • AddActivity
  • BuyActivity
  • CheckInActivity
  • CommentActivity
  • CreateActivity
  • ListenActivity
  • ReserveActivity
  • ReviewActivity
  • ViewActivity - video
  • ViewActivity - movie
  • ViewActivity - TV episode

種類によって、登録出来る属性が変わります。
音楽のMomentsだったら、名前、画像、アルバム名やURL、アーチスト名 とか。
チェックインのMomentsだったら、名前、住所、緯度経度、MAPのURLとか。
新しいタイプのリクエストも受け付けてくれるみたい。

amazonの場合、amazonでの購入履歴や表示ページから "おすすめ" を出してくれますが、 Google Historyを使えば、amazonの枠を超えて...楽天とか?... さらなる "おすすめ" を出せるのかもしれません。

APIをみると、タイムトラッカー的につかえるか? と一瞬おもいましたが、 そういうMomentsがない というのもありますが... 上手く使えずに消されていくAPIかもしれない という疑問が出てくる。
これが流行るためにはサードパーティが上手く作ったアプリを提供して、ユーザも便利!って思えるようならないと行けないと思うから...

だが、PCからもmobileからも登録ができるようなアプリ を作りたい場合で、提供されているMomentsにぴったりくるのであれば、このAPIを使えばサーバーを自前で用意しなくてもアプリが作れるという魅力はある。
どこまで気合入れているAPIなんだろうーなー。今後の動向が気になる所。

• • •

2012年6月28日木曜日

実機テスト時にinvalidProductIdentifiersが発生

iPhoneのアプリ内課金の所で、SKProductsRequest を取得しようとすると、Product情報が上手く取得できず、 invalidProductIdentifiers になってしまう。
シュミレータではinvalidにならないのに、実機からテストした時のみinvalidになる状態。

結局何がダメだったのか? ですが、
実機に送っていた時のプロビジョニングファイルが、*(アスタリスク) のものだったからでした。(なんでもOKのやつ)

実機上のアプリを削除してから、Bundle Identifierと同じProvisioningFileを選択し再度起動したら正常に取得できた。
ちなみに、よく、"バイナリをアップして自分でリジェクトする"という記事があるが、これはしなくても大丈夫です。
(昔はそうだったのかなー。)

同じ場面になる人はあまりいないかもしれないけどー、一応共有デシタ。

2012/08/02 追記 プロビジョニングファイルは関係なくて、アプリを一度削除して入れ直すだけでいけてたような気がする...
• • •

2012年6月20日水曜日

賞味期限メモ FreshPantry リリースしました

最近家にいることが多いので、食材を備蓄する機会が増えた @aqubi です。
そうだ!賞味期限アプリで管理しよう! と思い探していたのですが、これが、なかなか気に入るのがない!!

理由はいくつかあれど、一番は...
画面デザインが嫌!

もっとかわいい感じで、入力とか見るのとかが楽しくなるようなアプリが欲しい。
楽しくなくちゃ絶対続かない。少なくとも私は(笑)

ということで作り始めたのが 賞味期限メモ Fresh Pantry

見てて楽しい画面ってどんなんだろーなー
→ 写真だな! 写真が並んでいたら嬉しい!

写真があるなら....
→ カテゴリとか、食材の名前とか入れなくても分かるじゃん! 消しちゃえ!

と、ザクザクと入力項目を減らし、シンプルを目指して画面を作成していきました。

悩んだ所は....
まず、「写真選択」のところ。
普通は、カメラ or フォトライブラリー から選ばせるパターンが多いと思うので、当初はそう作っていたのだけど、アプリの特性上、既に写真を撮っていてフォトライブラリーから選ぶ事ってすくないよなー。
ってことで、カメラのみに断捨離。これで、入力時のタップ回数が1つ削減w

もう一つは、「削除」の所。
ちゃんと使い切った時には、使いきったぜ! という気持ちが欲しかったので、削除ボタンではなくて、
| 使いきった! | 捨てちゃった... |
という2つのボタンを作ろうか と。
そういう選択したら、その結果もみたいよねーってことで、使いきった割合 とか出すかなー とか。
最終的には、DELETE ボタンだけにしました。
気持ちよさも大事なんだけど、無駄な選択肢は無いほうがよいよな。つーことで。

結果、
1. + ボタン(追加ボタン) をタップ
2. カメラでシャッター をタップ
3. カメラで 「使用」をタップ
3. 期限日をドラムで選択
4. 「保存」をタップ
だけのミニマム操作なアプリとなりました。

こんな感じで、面倒くさがり屋の私が作ったアプリ。
ぜひ、使ってみてください!
ちなみに、他人の登録内容をみるのも楽しい。冷蔵庫を見ているようで。
他人の冷蔵庫ってちょっとした秘密っぽくて、みると楽しいですよね? 私だけ?w

P.S.
使ってくれる人が多そうであれば、データを転送出来る機能をつけたい...

賞味期限メモ Fresh Pantry
価格 : 85円
カテゴリ : ライフスタイル
対応機種 : iPhone
対応OS : iOS4.3以上
サポートページ : http://freshpantry.places-inc.com/jp/
リリース日 : ver1.0 2012/06/19


• • •

2012年6月4日月曜日

iOSで角丸画像の作り方

画像を角丸にして表示したい 時。
いくつか方法があります。

a. 角丸の画像を描画して抜き出す

How to make an image with rounded corners
のようにゴリッと書いて画像を作ってしまうパターン。

Resize a UIImage the right wayにすぐに使えるコードも置いてある。素敵。

b. マスク画像で抜き出す

画像処理に使えるUIImageのTips10個 - (9) マスク処理で角丸画像を作成する
私はまだやったことないのですが、角丸のように単純でない抜き出しは楽そうー。

c. CALayerの cornerRadiusで指定する

#import <QuartzCore/QuartzCore.h>

@implementation FERoundView

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        self.layer.cornerRadius = 4.0f;
    }
    return self;
}
@end

こんな感じで、CALayerのcornerRadiusで指定するのはとっても簡単。
1つこんな感じのViewをつくっておけば、角丸にしたいラベルの背景がある時に InterfaceBuilderのクラスに作ったクラスを指定するだけで完了します。

調子に乗って、角丸画像が一覧になっている画面にCALayer#cornerRadiusで指定したものを並べてみたのですが、 これが遅い! スクロールするとガクガク...
そんなに重い処理だったんですね、コレ。

このLayerの機能をつかって a.のような角丸画像作成メソッドとして使っちゃう手もあります。
シンプルなコードでかけるのが魅力的。

- (UIImage *)makeCornerRoundImage:(UIImage *) image {
    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(0, 0, 200, 200);
    imageLayer.contents = (id) image.CGImage;
    imageLayer.masksToBounds = YES;
    imageLayer.cornerRadius = 4.0f;
    
    UIGraphicsBeginImageContext(imageLayer.frame.size);
    [imageLayer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return roundedImage;
}



当たり前のお話なんですが、画像を一度にたくさん表示するのであれば、
・最適の画像サイズ&角丸などの処理済み の画像を用意しておく
・表示はUIImageViewでなくてdrawRectで書いてメモリ節約
ってのはとても効果が大きいもんですなぁ

テスト的にアプリ作っていると、ついつい手抜きでInterfaceBuilderで画面イメージ想像しながらUI部品貼り付けて、画像も既にある画像を拡大/縮小してとりあえず表示しちゃう。
ま、それはそれでいいですよねぇー。あとで、ちゃんと書きなおすのであればw

UIImagePickerでカメラを起動して写真撮ると、結構メモリを消費する上に、
その際に メモリ警告がでると それまでに作成していたViewが削除されてしまう状態になり...
viewが削除された画面に戻ると、UIViewControllerのloadViewからまたふただびCallされる事になり...
"わはーっ ちゃんと真面目にやろう..."
と、ワタワタした土曜日を過ごした(笑

• • •

2012年5月29日火曜日

DeskClockCalendarのプロモコード差し上げます!

iPad用アプリ 時計&カレンダー Desk Clock Calendar がリリースしました! やったね♪
Desk Clock Calendarは、時計・カレンダーとともに、経過時間を円グラフで表示するアプリ。

ずっと表示するものだから、ちょっとカッコイイものが欲しくて作成しました。
雰囲気はちょっとレトロなポスター風(勝手なイメージw)。
仕事場やリビングにおいていても良い感じに仕上がっていると思うので、iPadをお持ちの方は是非使ってみてください!
価格は170円ですが、6/12まではリリース記念として半額の85円でセール中です。

そこで....私から...
先着10名様に無料で使えるプロモコードをプレゼント!
欲しい方は twitter で @aqubi までご連絡ください。"プロモコード欲しいよ" と書いてもらえればOKですー。
プロモコード送付はTwitterのDirectMessageで送る予定です。

プロモコードを使う方は、AppleStoreのレビューを書いて頂けると有りがたいですm(__)m
レビュー、ホント有りがたいのです....(;_;)
ご応募お待ちしてまーす! プロモコードの使用期間が限られているのでお早めに....

追記:
プロモコードを使ってインストールすると、AppStoreのレビューは書けないことに気づきました。。
よければ一言感想を頂けるとうれしいです!





Desk Clock Calendar
価格 : 170円 (6/12までリリース記念セール中で85円)
カテゴリ : ライフスタイル
対応機種 : iPad
対応OS : iOS5.0以上
サポートページ : http://dcc.places-inc.com/
リリース日 : ver1.0 2012/05/29


• • •

2012年5月27日日曜日

iOSで時計アプリを作る

GW中にゴソゴソつくっていた、iPad用時計アプリ 時計&カレンダー Desk Clock Calendar がもうすぐ公開される予定です!
仕事中でパソコンに向かっている時、眠っているiPadを有効に使いたいー と思い作ってみました。
今週、今月、今年で、もう何%過ぎてしまったか? のグラフ見れる、焦る機能付きですw

多分、プロモコードの配布とかすると思うので、興味有る方は是非。

時計では 時間の表示 をします。
時間を表示って、結構いろんなアプリで表示が必要になりますけど、誰もが一度は多分経験するだろうハマリ箇所をご紹介。

時間の表示は、NSDateFormatterを使ってフォーマットして表示します。
NSDateFormatterはOS側のLocaleの設定や、24時間表示 on/off の設定によって挙動が変わってしまうの注意!

たとえば、以下のように表示設定をするとする。
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
NSDate *date = [NSDate date];
NSLog(@"date %@", [formatter stringFromDate:date]);

HHは、24時間表示の設定なので、

2012/05/27 15:22:50

のような24時間表示の結果を期待するのですが、これが、表示が何もされなくなったり、12時間表示になったり というパターンになる時があります。
その時は、OS側の設定で 設定 → 一般 → 日付と時刻 で 24時間表示 が off になっている時に発生します。
逆に 24時間表示が on になっている時に、hh(12時間表示)のフォーマットにしてもNG。

解決策としては、NSDateFormatterにLocaleを設定してあげること。
[formatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"ja_JP"] autorelease]];

ちなみに、
[formatter setLocale:[NSLocale currentLocale]];
では上手く反応してくれなくて解決になりませんw
国際化しているアプリでは気持ち悪いデスヨネ...
Localeがjaだと 5月と表示されるが、enだと May となったりもするので、そのコードにjaのLocaleを単純にいれてよいのか?はちゃんと確認が必要です。

逆に考えると、OSの設定が引き継がれるので、自分のアプリで設定項目を作らなくてもよかったりする場面もあるかも。
表示される文字の長さに注意して、画面レイアウトすれば... ですけども。

今回作成したアプリでは、時間はキモのところであり、経過時間などの計算もしたりするので、 NSDateFormatterでのフォーマットを使っている所もあるのですが、NSDateComponentを使ってNSDateの情報を抽出して自分でフォーマットしている所の方が多いw
NSDateComponent は、NSDateを年/月/日/曜日 などに分割してくれるものですが、NSCalendarと一緒に組み合わせて使うと、 経過日数の算出とか、今月の日数の算出とかできます。

まとめると....
日付を表示するアプリを作る場合は、複数のテスト端末を用意して、24/12時間表示の設定が違うもの、Localeが日本と日本以外で違うもの を用意する。さらに言語設定が違うものも揃えとくと吉。
というお話でした。

• • •

2012年5月21日月曜日

iPhoneアプリの作成の入り口

先日見ていた某USTで、
"MVCのcontrollerがでかくなっちゃって、modelどこいった? みたいなの ありがちw"
ってお話を聞いたので aqubi風の手順をPicTackを作った時を例にを書いてみよう! というエントリ。

手順は、作るモノによっても違うし、作り手によっても違うと思いますが、参考になったと思ってくれる人がいるのかもしれない という期待を込めて。



1.アプリのイメージを固める

まぁ当たり前ですねw
PicTackの場合は、一言でいうと、 "出されたお題にそって絵を書くアプリ"
"対戦にすることで、絵が上手い人だけでなく下手な人だって楽しく、盛り上がる!" というのが面白さ。
ということで対戦するのが必須の機能として作成を始めました

2.ワイヤーフレーム作成

どんな感じで画面がすすんでいくか? のイメージをざっくりと作成します。
cacooを使って作成しました。(お世話になっています)
実際この作業の完了タイミングは、後述の 3.プロトタイプ作成 が終わるまで続いていきます。

3.プロトタイプ作成

2.ワイヤーフレーム作成 って固まるまではそこそこ時間かかるので、 並行して プロトタイプを作成し始めました。
ポイントは、ブレが少なそうな所から固めていくこと。

3-1. 外部IOの調査

外部要因は思わぬ落とし穴があるもの。
新しく使うiOSの機能とか、外部のサービスをつかう とかの場合は調査をします。
PicTackの場合は、Bluetoothで送受信がどこまでできるか? という所でした。

このタイミングで決めるのは機能として必須となるもののみ。
twitterでツイートする とか補足的な機能は絶賛後回し! ここの切り分け重要。

このタイミングで、改めて分かる制限事項などがあるので、でてきたら、ワイヤーフレーム作成フェーズ中にフィードバック。

3-2. データモデル作成

最初はデータモデルを作成します。
データモデルはブレが少ないし、これがある程度あると後の画面の組立とても楽になります。
でも仕様が決まっていないと、完璧なものは出来ないので、ブレが無さそうな基本的な所を作っていきます。

設定項目用のデータモデルはだいたい作るので作成しますね。
単純な設定しか無い時はシングルトンにしたりもします。

PicTackの場合は、
「1回のゲーム」class の中に、「タイトル」「サンプル画像へのリンク」の情報が入っている
「参加者」class の中に、「参加者の名前」「書いた絵の情報」 の情報が入っている
というのが最初からなんとなく見えているので、なんとなくのレベルで作っていきます。
あるかなー ないかなー と悩むものは、作りこまないのが吉。
だけど、データの塊(RDBでいうとテーブルになりそうな部分)はクラスだけ作っておきます。

なんとなく.. というのが微妙とおもわれるかもしれませんが、この属性(変数)をどこかに書きたい! と思った時に、適切なデータモデルのクラスがあり、そこにすぐに書けるのはとっても大事と思います。
そうでないと、Controllerとか適当な所に書きたくなっちゃいますので。

3-3. InterfaceBuilderで画面をざっくり作成

2.ワイヤーフレーム作成 で 画面の流れがみえてきたなー と思ったらざっくり作り始めます。
内部の細かな実装は後回しで、画面遷移部分を最初にひと通り作って、仕様の考慮不足がないかを確認していきます。
なんかあれば、ワイヤーフレーム作成フェーズ中にフィードバック。
実際画面を動かしてみると見えてくるものが多いもんですw

3-4. 外部IOのデータモデル、データモデルのコントローラ作成

PicTackの場合は、Bluetoothの通信の基本部分の作成になりました。
Bluetoothの通信はバイナリで行うことにしたので、各タイミング毎にデータフォーマットを決めて、それをデータモデルに落とし込みます。
送受信のイベントを受け取り、データモデルに展開して使いやすくするような動作の部分も作成していきます。
そういう部分のところは、データモデルのコントローラ といっていいのかなー。
ここを使いやすく、テストもして正常動作を確認して、後で安心して使えるように用意しておきます。
Bluetoothの通信がおかしいときに、ここのバグが原因だとあとでめっちゃ混乱するのは目に見えているのでw

PicTackの時にはなかったのですが、外部のサーバーとのアクセスをする時には、 アクセスするための口(メソッド)は用意しておきます。
ネットワークアクセス開始した/終了したタイミング、システムバーの通信中のインジゲータのグルグルを開始したり止めたりしたいので、そこらへんが上手く動くように最初に作りこんでおきます。
非同期で基本動かすと思うので、ちゃんとカウントとってグルグルさせましょー!

3-5. イベントの整理

画面からのAction, 外部IOのcall、callback のイベントのメソッドを作っていきます。
このイベントの結果受け取りは、どうやって行うのか? をまとめていきます。
方法としては、以下のように色々ありますよねー。

  • delegateでやり取りする
  • observer的にやりとりする(NSNotificationCenterなど)
  • クラスの変数を保持しているので直接メソッド/プロパティをcallする
統一された作りになるように、全体をみつつ設計していきます。ここ、楽しい作業ですよ!
最初はメソッドの実装は空のまま、ザクザク必要そうなものを作っていくのがオススメ。
全体から俯瞰する というのに集中力がきれないように作成していけるので。
後の組立作業で、この箇所が上手く設計されていると やったった! という気分になります。

3-6. 主となる機能を実装

いままで下ごしらえしたものを、実際組み上げていきます。
PicTackの場合は、ゲームを開始して、書いて、結果が見える所まで。
プロトタイプで必要となる実装のみ、先程用意したメソッドの中にコードを書いていきます。
ここで、プロトタイプとしてレビューしました。
レビュー後、やっぱり欲しい画面とか機能とか追加して、ワイヤーフレーム作成フェーズとともにプロトタイプの完了。


ここまでのプロトタイプの作成で、手元のメモによると 5日かかった模様。
まぁ、アプリってそこからが長いんですけどもねーw

• • •

2012年5月19日土曜日

iOSでバッテリー残量を取得する

iPhone/iPadのアプリで、バッテリー残量を取得するには、以下で取得が可能です。

[UIDevice currentDevice].batteryMonitoringEnabled = YES;
float battery = [UIDevice currentDevice].batteryLevel;

float battery にて入ってくる値は -1 〜 1.0 までになり、
-1 は シュミレータで実行などにより、バッテリー状態が不明な時(UIDeviceBatteryStateUnknown の時)に設定されます。
実際の値は、0〜1.0 までの値で設定されるので 100 をかければ パーセントの値になります。

簡単やーん! とおもって早速書いていたのですが、
iPhone/iPadでiOSが表示している上部のステータスバーのバッテリー残量の%と違う値が返ってくる。

コードでは 85% の時、ステータスバーは92%
コードでは 65% の時、ステータスバーは69%
コードでは 55% の時、ステータスバーは57%
コードでは 50% の時、ステータスバーは51%

どうやら、コード上では 5%刻みでしか取得できていないっぽい。

ググっていたら以下のサイトを発見。

How to get UIDevice batteryLevel to provide status in 1% increments or finer

The UIKit calls to retrieve Battery can only get a number better 0.0 to 1.0 with 0.05 steps which means 5% intervals. In order to get it with finer granularity you might have to jail break the device and setup something like this but you might not be able to submit the app. Just in case, I came across this post, which might be of interest to you.

そういうものらしいです。
リジェクト対象になってもいいなら方法はあるらしいw

試していると、
しかも誤差は +-5%には収まらない時がある気もする。 +-10%とかなのだろうか。
UIDeviceBatteryLevelDidChangeNotification で変更イベントをリスナーしていると、充電してないのにbatteryLevelが増えた値が来る時があったりとかもする。
まぁ、あまり当てにしてはいけない ということだろう。

ということで、本日の教訓。

バッテリー残量を自作して表示する時は、90%など、実際の数値は表示しないほうがよさそう。
誤差が +-10%離れた値が返ってくる可能性もあるので、正確な値はやんわり隠しても大丈夫なアプリ仕様を考えよう。
• • •

2012年5月18日金曜日

選択肢から選ぶアイデアを探す

先日、選択肢から1つ選ぶiPhoneのUI部品 というエントリを書きましたが、普段接しているモノにもいいアイデアがありそうだなー ということで探してみました。

Saeco Talea Giro Plus という エスプレッソメーカーの操作部分です。

抽出する "お湯量調整" を銀色のグルグル回す所で選択します。
カップマークボタンは、それを押すと "抽出開始" する。 一番使うボタン。
その下の "珈琲豆調整" ボタンは、ボタンを何回か押すことにより豆の量を選択させるボタン。

普段よく使うものは、"抽出開始" と "お湯量調整"です。
それらがぐっと前に出ているので、ぱっと選択しやすい効果をうまく出していますよね。

"お湯量調整" 、"珈琲豆調整" は、両方共選択肢から1つを選ぶラジオボタン的な要素です。
"珈琲豆調整"は最初に好みの量を色々試行錯誤するけど、そのあとはあまり触らなくなります。
なので、選択がしにくくてもあまり不満は感じてません。

左側にある光りそうな部分は、現在のステータスを表示してくれるもの
お湯を暖めているからまってね... というタイミングでは、4つのランプの光がグルグルと回ります。
まるで、端末のUIで使われる loading中のインジゲータみたいに。
右側にある光りそうな部分は、清掃をする時などにトグルの操作で設定します。つまりあまり普段は使わないボタンです。

  • 普段よく変更するもの
  • 変更しないが設定内容は見えてて欲しいもの
  • 普段は設定内容が見えてなくてもいいもの

という、内容によって表現を考慮し、見かけ上も素敵なデザインになっていて素晴らしいです。

  • 大きく設定を変えるものは操作しやすい ぐるっと廻るボタンに
  • あまり普段は変えないものは、ボタンを何度か押して選択させるものに
というのも感じます。 ぐるっと回せるレバーは、実際のモノでは使いやすいけど端末上でドラッグさせるのは難しい というのもあるので、iPhoneなどのUIでそのまま使えるものではないのですが、 色々考慮されている素敵なUIは身近にあるんだなー と思いました。

• • •

2012年5月17日木曜日

選択肢から1つ選ぶiPhoneのUI部品

iOS(iPhone, iPad)で、
  • 複数の選択肢の中から1つを選択する
  • 日付などを選択する
という場合、Picker(ドラム) を使ったりします。
Pickerというのは↓ こういうやつ。
このPickerの表示、
  • 全体サイズが思うように調整できない
  • 色のカスタマイズも思うようにできない
...があり、凝った感じにUIや色を使っている場合には合わなくなってしまう事があります。
通常はラジオボタンを並べそうな用途の場合、Picker使うか、Tableを表示して行選択させるか などの選択になるのですが、 もっと小さく、手軽に(小さい領域)で選択できる方法はないもんか! と思う時も多々あります。

ということで、使いやすそうなUI部品を自作しているアプリを。

Fitocracy

http://www.fitocracy.com/

運動を通じてみんなと共有出来るアプリ。
細かなUIがしっかり作りこまれていて、かなり金かけてやってるなー という感じ。
運動が続けられるように仕組まれているものも豊富っぽい。
Achievements , Quests , Challenges とかもある。
だけど、機能が豊富&英語なので私には使いこなせません。。
ここでの体重入力は↓な感じ。
邪魔にならない色デザインになっている のと、選択されているものが はっきりとわかりやすい。
Pickerに慣れている人には違和感なくつかえそうです。

National Parks by National Geographic

http://itunes.apple.com/jp/app/national-parks-by-national/id518426085?mt=8

国立公園の画像とか情報が見れるアプリ。
このアプリも綺麗につくられていて、見てるだけで和みます。
惚れちゃうぐらい良くできてますね。
選択肢の文字が少ない時は、横に並べたいですもんね。
選択されている箇所はレバーっぽい立体的なボタンが表示され、選択文字列はちょっと上にでています。

他に良いアイデアのUIがないかちょいちょい確認しようーっと。
• • •

2012年3月30日金曜日

うさぎがご飯を食べなくなったら


我が息子、うさうさが亡くなってから1ヶ月が過ぎました。
ようやく気持ちも落ち着き、元気よく祭壇に向かって "うさ、ただいま!" と言えるようになって来ました。

13歳4ヶ月 という長寿なうさぎでしたが、もう少し早く気づいてあげれば... と思う気持ちが残っています。
そのため、うさぎ飼いの方に少しでも情報提供になれば... と思い、このエントリを書こうと思います。

ご飯を食べなくなったら

うさぎがご飯を食べなくなったら、素早く病院に連れていきましょう。
働いている場合は特に、気づくのが夜になってしまう場合が多いです。

「明日の朝イチに病院に連れていこう」
... というのでは間に合わない可能性があります。
実際、うちの子は間に合いませんでした。

夜間診療をしてくれる病院が近くにあるかもしれません。
がんばって探してみましょう。
その数時間の短縮がとても大事になる場合もあります。

お水を飲まなくなったら

ご飯をよく食べる子は、気づくのが遅くなる場合もあるかもしれません。
ご飯だけでなく、お水もちゃんと飲んでいるかを日々確認してみましょう。

胃にガスや水が溜まってしまっている場合、
何かを胃に入れるのは痛いので、ご飯のみならず水も飲まなくなります。

うさうさはご飯をひたすら食べる&早食いタイプ だったのですが、
お水はたしかに1日前から減りが少なくなっていたかも? と今となっては思います。

あと、うんちも少なくなるとか、毛が多くついたうんちがでてくる などチェックもぜひ。

夜間診療の病院がなかったときは

まず、胃の部分を軽く触って、いつもより大きくなっていないか? を確認してみましょう。
大きくなっていたら、急性胃拡張かもしれません。
胃拡張になると、痛いのを我慢するため、動かなくなります。
うちの子も、バタバタ走り回るタイプだったのに、パタっと動かなくなってずっと座る状態になりました。

暫くお水を飲んでいないようだったら、スポイドなどをつかってお水を飲ませます。
飲んでくれるようであれば、飲ませてあげて、脱水症状にならないようにします。
嫌がって飲んでくれない時には、相当痛い状態なのかもしれません。無理に飲ませない方がいいかもしれません。

暫くご飯を食べてくれないようであれば、好きなご飯や、ペレットをお水で柔らかくしたものをあげてみましょう。
ご飯を食べないと、より悪循環で悪化してしまう動物なのです。

ご飯を食べてくれない時はエネルギーが少なくなって、体温を維持するのが難しくなるので、
冬場などであれば暖かくしてあげましょう。

胃が大きい場合、仰向けにすると圧迫されて余計に痛くなるようです。
胃の部分を軽くさすってあげて、少し楽そうになっていればさすってあげても良いらしいです。
強くさすらず、優しく優しく。

朝まで頑張ってくれることを祈ります。。
• • •

2012年3月27日火曜日

iPadスタンドを模索

エントリーNo.1 Apple iPad Dock


公式のiPadスタンド。さすがにしっかりした作りです。
立てると同時に充電や同期が安心してできるのはやっぱりコレ。
だけども、縦置きしかできないのが難点。

エントリーNo.2 ダイソー 皿たて

よくよくみると、いろんなお店で備品として使われているコレ。
ダイソーにありそうだという情報を入手して、アルカキット錦糸町のダイソー (めちゃくちゃ大きな店舗)にむかいウロウロしましたが見つけられず。
スタンドになりそうなものをチョイスして、家路につこうとおもったのですが、ふと、近くにある LIVIN錦糸町店 (小さな店舗)のダイソーにいったら発見!

立っている棒の幅は変えれないので、カバー無しの状態だとちょっと斜めになります。

ですが、複数台を持っている人にはオススメ。
安定感もあるし、木なので傷がつきにくい気がする。
したに隙間は少しできるが、電源を差すぐらいの幅は無い。

エントリNo.3 ダイソー まな板たて

ディスプレイとして置くのにはいいかも。
横向きでも縦向きでもそこそこいい見た目。
ですが、安定感はそれほどない。置いておくだけならいいけど、コレに置いてタッチ操作する というのはやめた方がよさそう。
縦置きにした時、電源を差す所はちょうどワイヤーっぽい所と重なって差すことはできない。

エントリNo.3 ダイソー まな板たて2

先ほどののまな板たてよりは安定感はある。だが、ディスプレイというよりも、立てる という趣き。
したに隙間はできるが、これも電源をさせるほどは開いていない。
このまな板たては2つの隙間があって、小さい隙間だとカバーなしですっと立つ感じ。
大きい隙間の方は、カバーありでちょうどいい感じ。
ディスプレイ用じゃなくていいから、立てる所が単純に欲しいというのであればよいかも。
• • •

2012年1月29日日曜日

PicTack:iPhoneでBluetooth通信の巻

PicTackでは、Bluetooth or 同一WiFi で端末を接続しマルチプレイを実現しています。
iPhoneでBluetooth接続するには GameKit Frameworkを使用できます。

GameKitは、GameCenterのライブラリ + PeerToPeer接続のライブラリ + Voiceのライブラリ。
今回使用した PeerToPeer接続のライブラリは、ローカルワイヤレスネットワークとBluetooth を行うことができます。

接続は対話式。

Aさん : 接続したい人募集!
Bさん : だれか接続出来る人いないかなー
Bさん : Aさん発見! 接続させてくれー
Aさん : お。Bさんから接続依頼きた。OKですよー
Bさん : お。AさんからOKきた!

みたいな感じ。
接続は 、GKSessionのクラスで管理されて、セッションのID と 端末毎に PeerID が振られます。
通信は NSData型(バイナリ型)で行います。つまり文字列はもちろん、画像とかも送れます。

2台の端末で接続を行う時は、GKPeerPickerController を使うと楽。
接続対象のリストの表示、選択された端末への接続 などの一連の処理を行なってくれるControllerが標準で用意されています。
素敵なサンプルも公開されています (GKTank)

PicTackでは、GKPeerPickerController を使わず、GKSessionという基本のクラスを使って実装しています。
理由は、GKPeerPickerControllerは2台の接続であること。専用のViewが表示されてしまって、ユーザの手順がわずわらしいこと。

後々知ったのですが、「BlueToothが設定ONになっているか?」というのを知るのは private methodを使わないと出来ない。
だけど、このGKPeerPickerControllerを使えばそれもやってくれるみたい。このメリットは大きいですねー。

GKSessionを使う方法をとると、前述の接続も自前でイベントハンドルして処理してあげることになります。

接続方法は、PeerToPeer と Client-Server と Ring の3種類から選べます。

PicTackで選択したのは、ネットワーク負担も軽そうなClient-Server方式。
Appleのドキュメントによると、最大16人まで接続できます。

接続して通信するのは、比較的簡単に実装できます。
"GKSession" でググればたくさん記事が見つかりますので、ここではハマった点を紹介。

BlueToothの設定がONになっているかどうかを判断できない。

Privateメソッドを使えばできるっぽいけど、それをしたら正式にリリースできない。
BluetoothPowerChangedNotification のイベントを取得したらどうにかなる? とチャレンジするもうまくいかず...

そこで、取った方法は、 GKSessionDelegate の didFailWithError でエラーを取得する方法。
#if 0
#define kGKSessionErrorDomain GKSessionErrorDomain
#else
#define kGKSessionErrorDomain @"com.apple.gamekit.GKSessionErrorDomain"
#endif
- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
    if ([[error domain] isEqual:kGKSessionErrorDomain] &&
        ([error code] == GKSessionCannotEnableError)) {
        // Bluetoothもしくは同一WiFiが無い時のエラー
 
    } else {
       //何かのエラー
    }    
}
ただ、このエラーはセッションを作成して開始したタイミングでは飛んでこない。
タイミングをみてavaliableの値を変えるなどしてチェックし直す感じにしました。

また、BlueToothの設定がOFFでもWiFiに接続しているとこのエラーは発生しないのでご注意を。

いつまで経ってもセッションが確立されない時がある

セッションのゴミが残ってしまう時がどうやらあって、そこに接続しようとすると、
> Bさん : Aさん発見! 接続させてくれー
の後に、Aさんから一切応答が無くなるという自体が発生する。

セッションの接続を切って、すぐにまたセッションを開始しようとするとゴミが残るような感じ (ちょっと不明)
ゴミが残ると暫くの間ずーっと残ったままになってしまう。

できたら、ゴミが残るのを避ける対処をしたかったのですが、こうやったら大丈夫! という保証がなかなか出来なかったので、接続できなかったらタイムアウトして他の端末を探すというような事をしました。
この問題は、"ゴミのセッションが残っている" と理解するまでに時間かかってしまってハマリました (;_;)



Bluetooth接続して、描画データの送受信する という所を実装したのは数日でできたのですが、
上記2つを調べるのになんやら色々時間を食ってしまった 感じです。
開発期間を1ヶ月と区切っていたので妥協点も多いのですが... 最悪の事態にはならないように、落ちたりしないように という方向に集中しました。

始めてマルチプレイの画像をtweetしてもらった時は、いやぁ ホント、ホッとしましたww


PicTack
価格 : 無料 (一部のお題は有料)
カテゴリ : ゲーム
対応機種 : iPhone
対応OS : iOS4.1以上
サポートページ : http://pictack.places-inc.com/
リリース日 : ver1.0 2012/01/16


• • •