ラベル iOS の投稿を表示しています。 すべての投稿を表示
ラベル iOS の投稿を表示しています。 すべての投稿を表示

2015年6月19日金曜日


Appleの開発者のイベント、WWDC2015に弊社からも参加いたしました。今回の勉強会ではWWDC2015の報告会とAppleWatchの新機能、そしてAutoLayoutの新機能やiOS9からiPadに搭載されるMultitaskingについて発表を行いました!


[コラム]WWDC2015報告会&iOS&AppleWatch勉強会を開催しました


Appleの開発者のイベント、WWDC2015に弊社からも参加いたしました。今回の勉強会ではWWDC2015の報告会とAppleWatchの新機能、そしてAutoLayoutの新機能やiOS9からiPadに搭載されるMultitaskingについて発表を行いました!


2015年5月9日土曜日


AppleWatchの発売日である4/24とその翌日の4/25にそれぞれ大阪と東京でApple Watchの勉強会を開催いたしました。
AppleWatch発売!Apple Watch WatchKit勉強会 大阪
AppleWatch発売!Apple Watch WatchKit勉強会 東京
私はNotificationについて説明させて頂きましたのでその時のスライドをベースに、その後試した内容を加筆してblogとして公開いたします。

実際にApple Watchを一週間使ってみて、アプリ機能やグランス機能なども一通り試してみました。私がApple Watchで一番頻度の高い機能であると考えるのはNotificationです。ちらりと見るだけで情報を把握、気になる内容だったらiPhoneを取り出してチェック、そんな風に使えるのでとても便利です。アプリケーションの品質を高めるためには、使いやすく、一見するだけで情報を把握できるように配慮されたNotificationを実装するべきでしょう。

Apple WatchでNotificationを出す方法


AppleWatchの発売日である4/24とその翌日の4/25にそれぞれ大阪と東京でApple Watchの勉強会を開催いたしました。
AppleWatch発売!Apple Watch WatchKit勉強会 大阪
AppleWatch発売!Apple Watch WatchKit勉強会 東京
私はNotificationについて説明させて頂きましたのでその時のスライドをベースに、その後試した内容を加筆してblogとして公開いたします。

実際にApple Watchを一週間使ってみて、アプリ機能やグランス機能なども一通り試してみました。私がApple Watchで一番頻度の高い機能であると考えるのはNotificationです。ちらりと見るだけで情報を把握、気になる内容だったらiPhoneを取り出してチェック、そんな風に使えるのでとても便利です。アプリケーションの品質を高めるためには、使いやすく、一見するだけで情報を把握できるように配慮されたNotificationを実装するべきでしょう。

2015年2月18日水曜日

nestとはサーモスタットのように人々に愛されていない器械に焦点を当て、これをリデザインし合理的なデザインかつ利便性の向上を果たした次世代のサーモスタットです。現在Nest Developer Programとしてnestを操作するためのAPIが公開されており、本文書ではnestについての説明を日米の冷暖房文化の違いを交えて説明した上で開発環境の構築方法について解説します。

PDFがこちらからダウンロード出来ます。
http://www.brilliantservice.co.jp/bril-tech-blogspot/nest_develop_environment.pdf

IoTを実現するGoogle Nest APIでスマートホーム開発環境を整える

nestとはサーモスタットのように人々に愛されていない器械に焦点を当て、これをリデザインし合理的なデザインかつ利便性の向上を果たした次世代のサーモスタットです。現在Nest Developer Programとしてnestを操作するためのAPIが公開されており、本文書ではnestについての説明を日米の冷暖房文化の違いを交えて説明した上で開発環境の構築方法について解説します。

PDFがこちらからダウンロード出来ます。
http://www.brilliantservice.co.jp/bril-tech-blogspot/nest_develop_environment.pdf

2013年12月19日木曜日


ビーコンって何を考えてるんでしょうね?聞いてみたいと思いませんか?

と、唐突に書き始めてしまいました。開発のやりすぎで頭がおかしくなったのでしょうか? いえ、そうではなくて、今回は、ビーコンの近さに応じて、再生する音の大きさを変えてみようというお話です。でも、それはまるで、ビーコンが「近づいたよ〜」「遠のいたよ〜」と言っているように聞こえるので、結構、たのしいのです。(実際には、電波が強くなったよ〜、ですが。。。)

では、さっそく作って行きます。

1.ボタンを押したら、曲を再生する、というところまでを作ります。xcodeのプロジェクト(BeaconVoiceという名前にしました)を作成し、AVFoundation.frameworkを追加します。また、"sounds"というフォルダを作成し、そこに用意したMP3ファイルをおきます(図参照)。


画面はこんな感じ(図参照)。

しょぼいですね〜。音量と電波受信強度のラベルだけはつけときました。

ソースコードは、こんな感じです。(STARTボタンを押すと、曲が再生されて、もう一度押すと、停止する、という動きにしてます。)

ViewController.m


はい、では、次行きましょう。

2.CoreLocation.frameworkをセットして、ビーコンを受信できるようにします。この辺りは、このブログで何回か紹介してますので、コードだけ載っけます。

ViewController.hのプロパティ

ViewController.mのViewDidLoadの中

ViewController.mの中のLocationManagerのデリゲート処理

はい、できました!

では、実行の様子をお聴きください...。


ああ、残念です。音声がお伝えできない。

音量は、0.0〜1.0までの値です。RSSIの値は、-90〜-58にしています。つまり、この画像では、最大値になっています。iPhoneもビーコンもスクリーンショットを撮った開発環境のPCに接続しているので無理ないですね。では、ちょっとビーコンを遠くへ離してみます。

か、かすかに音が聞こえます。そして、ときどき、ゴハッって感じで音が大きくなります。まるで溺れかけの人のように。おおお、いい感じでビーコンの声が聞こえてますね。

まとめ

もともとビーコンの電波がどれくらい不安定なのか知りたく思い、音で体感できるようにしたかっただけなのですが、なかなかいい感じで確認できることがわかりました。例えるなら、トンネルに入ったときのラジオの音でしょうか?でも、ビーコンに近いときは、安定して聴けます。

応用として、ある範囲では、クラシック、ある範囲では、ジャズなど、特定の範囲でだけ特定の音楽が聴けるとかのサービスができそうですね。

(おわり)

ビーコンの声を聞いてみよう!


ビーコンって何を考えてるんでしょうね?聞いてみたいと思いませんか?

と、唐突に書き始めてしまいました。開発のやりすぎで頭がおかしくなったのでしょうか? いえ、そうではなくて、今回は、ビーコンの近さに応じて、再生する音の大きさを変えてみようというお話です。でも、それはまるで、ビーコンが「近づいたよ〜」「遠のいたよ〜」と言っているように聞こえるので、結構、たのしいのです。(実際には、電波が強くなったよ〜、ですが。。。)

では、さっそく作って行きます。

1.ボタンを押したら、曲を再生する、というところまでを作ります。xcodeのプロジェクト(BeaconVoiceという名前にしました)を作成し、AVFoundation.frameworkを追加します。また、"sounds"というフォルダを作成し、そこに用意したMP3ファイルをおきます(図参照)。


画面はこんな感じ(図参照)。

しょぼいですね〜。音量と電波受信強度のラベルだけはつけときました。

ソースコードは、こんな感じです。(STARTボタンを押すと、曲が再生されて、もう一度押すと、停止する、という動きにしてます。)

ViewController.m


はい、では、次行きましょう。

2.CoreLocation.frameworkをセットして、ビーコンを受信できるようにします。この辺りは、このブログで何回か紹介してますので、コードだけ載っけます。

ViewController.hのプロパティ

ViewController.mのViewDidLoadの中

ViewController.mの中のLocationManagerのデリゲート処理

はい、できました!

では、実行の様子をお聴きください...。


ああ、残念です。音声がお伝えできない。

音量は、0.0〜1.0までの値です。RSSIの値は、-90〜-58にしています。つまり、この画像では、最大値になっています。iPhoneもビーコンもスクリーンショットを撮った開発環境のPCに接続しているので無理ないですね。では、ちょっとビーコンを遠くへ離してみます。

か、かすかに音が聞こえます。そして、ときどき、ゴハッって感じで音が大きくなります。まるで溺れかけの人のように。おおお、いい感じでビーコンの声が聞こえてますね。

まとめ

もともとビーコンの電波がどれくらい不安定なのか知りたく思い、音で体感できるようにしたかっただけなのですが、なかなかいい感じで確認できることがわかりました。例えるなら、トンネルに入ったときのラジオの音でしょうか?でも、ビーコンに近いときは、安定して聴けます。

応用として、ある範囲では、クラシック、ある範囲では、ジャズなど、特定の範囲でだけ特定の音楽が聴けるとかのサービスができそうですね。

(おわり)

2013年12月16日月曜日



はじめに

飛行機を使った移動で一番困るのが到着時の荷物受け取り
いつまで待っても預けた荷物が出てこない、いやとっくの昔に出てしまったかも?、もしかしたらロストバゲット!?
流れるベルトコンベアを眺め続けながら、いつもこのような不安がよぎります・・・
今回はそんな悩みをiBeaconで解決してみたいと思います。

iBeaconで海外渡航を楽しく



はじめに

飛行機を使った移動で一番困るのが到着時の荷物受け取り
いつまで待っても預けた荷物が出てこない、いやとっくの昔に出てしまったかも?、もしかしたらロストバゲット!?
流れるベルトコンベアを眺め続けながら、いつもこのような不安がよぎります・・・
今回はそんな悩みをiBeaconで解決してみたいと思います。

2013年11月4日月曜日

11月2日(土)に、スマベン(=スマートフォン勉強会)関西が開かれました。

http://sumaben.jp/?KansaiSpecial05BLE

今回は、メインスピーカーに上原昭宏氏を迎えて、Bluetooth Low Energyの勉強会をするということで私も参加してきました。

参加者はハードウェアの製造をされる方からソフト開発者、ウェブサービス開発者、マスコミ関係者まで幅広く、マッシュアップが非常に期待される顔ぶれでした。それほどBLE/iBeaconに対する各分野からの関心が高いということでしょう。

[コラム] スマベン関西に参加してきました。

11月2日(土)に、スマベン(=スマートフォン勉強会)関西が開かれました。

http://sumaben.jp/?KansaiSpecial05BLE

今回は、メインスピーカーに上原昭宏氏を迎えて、Bluetooth Low Energyの勉強会をするということで私も参加してきました。

参加者はハードウェアの製造をされる方からソフト開発者、ウェブサービス開発者、マスコミ関係者まで幅広く、マッシュアップが非常に期待される顔ぶれでした。それほどBLE/iBeaconに対する各分野からの関心が高いということでしょう。

2013年10月11日金曜日


iBeacon は、iOSでBLEを利用できるようにしたもの、という認識でしたが、調べてみるといろいろと知っておかないといけないことがあるようです。

例えば、ビーコンを表現したCLBeaconというクラスがCoreLocationフレームワークにありますが、信号を受信できるビーコンは、Apple社のベンダー情報が設定されていないと行けないことがわかりました。どうもAppleとのNDA契約がないと勝手にiBeaconの製品を販売できないことになっているようです。

また、CoreLocationフレームワークは、GPSやネットワークを使った測位全般を扱うフレームワークですが、そこにBLEを使った領域観測の窓口があるのは、アプリ開発者にとって直にBluetoothのプロファイルを扱わなくてもよいというメリットがあります。

調べた内容は、「iBeacon開発」(ダウンロードはこちら)にまとめましたので、ご覧ください。

iBeaconの仕組を調べてみました


iBeacon は、iOSでBLEを利用できるようにしたもの、という認識でしたが、調べてみるといろいろと知っておかないといけないことがあるようです。

例えば、ビーコンを表現したCLBeaconというクラスがCoreLocationフレームワークにありますが、信号を受信できるビーコンは、Apple社のベンダー情報が設定されていないと行けないことがわかりました。どうもAppleとのNDA契約がないと勝手にiBeaconの製品を販売できないことになっているようです。

また、CoreLocationフレームワークは、GPSやネットワークを使った測位全般を扱うフレームワークですが、そこにBLEを使った領域観測の窓口があるのは、アプリ開発者にとって直にBluetoothのプロファイルを扱わなくてもよいというメリットがあります。

調べた内容は、「iBeacon開発」(ダウンロードはこちら)にまとめましたので、ご覧ください。

2013年10月10日木曜日

BLEでどういったことができるのか、現状で手に入るBLEモジュールとそのサンプルプログラムを動かしてみました。今回はRedBearLab社の2つを使用しました。



BLE Shield

Arduino用のシールドです。
2013/10/07現在でArduino Uno、Arduino Mega、Arduino Leonardoの3つに対応しています。
公式サイトで提供されているサンプルスケッチはFirmataプロトコルと呼ばれるArduinoを制御できる汎用プロトコルをBLE経由で使用できるものです。



公式サイトからダウンロードできるファイルは次の3つから構成され、それぞれ次のライセンスが記載されていました。
・BLEライブラリ(MITライセンス)
・BLE用Firmataライブラリ(LGPLライセンス)
・サンプルスケッチ(LGPLライセンス)
比較的扱いやすいライセンスが適用されています。

Arduinoに装着し、サンプルスケッチを書き込めば直ぐに使用できました。iPhone用のサンプルプログラムをAppStoreからダウンロードし、実行します。接続画面からArduinoに接続するとArduinoの操作画面が表示されます。操作画面からはArduinoの各ピンの電圧のON/OFFや値の読み取りが行えます。

サンプルスケッチではBLE経由のFirmataプロトコルの通信のみとなっていますが、内部実装を見たところ、通常のシリアル通信のようなやり取りもできるようになっていますので、自分でプロトコル設計をすれば独自のことも行えそうです。

BLE Mini

UARTインターフェースを持ったBLEモジュールです。
このBLEモジュールにはPINが6本あり、内2本がTX、RXのUARTインターフェースとなっており、標準的なシリアル通信が行うことができます。UARTインターフェースなのでArduinoに限らずRaspberry Pi、BeagleBone、Netduino、RENESAS、PICと幅広いボードで利用可能できそうです。




BLE Shield同様にFirmataプロトコル用のサンプルスケッチが提供されています。
※このサンプルスケッチはArduino Uno用になっており、Arduino Leonardoで動作させるには修正が必要でした。

BLE Miniはファームウェアの書き換えが可能で、後述のiBeaconのように単独での動作も可能になります。公式サイトによるとファームウェアの開発環境についてはまだベータ版ということですが、今後の広がりに期待が持てます。

iBeaconとBLE Mini

BLE MiniにはArduinoのような別のマイコンに接続せず、
単独でiBeaconとなるファームウェアが提供されています。
2013/10/07現在は正式な仕様が公開されておらず、
このファームウェアは試験評価用という位置づけですが、
こちらもiPhone用のサンプルプログラムが公開されており、
どのように動作するかを体験することができます。




非常に汎用的ですので応用すれば自分たちでBLEを用いたハードウェアを創ることもできます。BLEは省電力かつ手軽に使えるということからこれを使ったデバイスが増えていくことが期待されますので、これからもこういったモジュールを追って行きたいと思います。


なお、今回紹介したRedBearLab社のBLEモジュールは技術基準適合は受けておりません。電波暗室や電波障害を起こさない十分に広い敷地・建屋内で実験を行ってください。不用意に電波を発射すると、日本の法律に反する可能性がありますのでご注意ください。

[Tips] BLEモジュールを試してみました

BLEでどういったことができるのか、現状で手に入るBLEモジュールとそのサンプルプログラムを動かしてみました。今回はRedBearLab社の2つを使用しました。



BLE Shield

Arduino用のシールドです。
2013/10/07現在でArduino Uno、Arduino Mega、Arduino Leonardoの3つに対応しています。
公式サイトで提供されているサンプルスケッチはFirmataプロトコルと呼ばれるArduinoを制御できる汎用プロトコルをBLE経由で使用できるものです。



公式サイトからダウンロードできるファイルは次の3つから構成され、それぞれ次のライセンスが記載されていました。
・BLEライブラリ(MITライセンス)
・BLE用Firmataライブラリ(LGPLライセンス)
・サンプルスケッチ(LGPLライセンス)
比較的扱いやすいライセンスが適用されています。

Arduinoに装着し、サンプルスケッチを書き込めば直ぐに使用できました。iPhone用のサンプルプログラムをAppStoreからダウンロードし、実行します。接続画面からArduinoに接続するとArduinoの操作画面が表示されます。操作画面からはArduinoの各ピンの電圧のON/OFFや値の読み取りが行えます。

サンプルスケッチではBLE経由のFirmataプロトコルの通信のみとなっていますが、内部実装を見たところ、通常のシリアル通信のようなやり取りもできるようになっていますので、自分でプロトコル設計をすれば独自のことも行えそうです。

BLE Mini

UARTインターフェースを持ったBLEモジュールです。
このBLEモジュールにはPINが6本あり、内2本がTX、RXのUARTインターフェースとなっており、標準的なシリアル通信が行うことができます。UARTインターフェースなのでArduinoに限らずRaspberry Pi、BeagleBone、Netduino、RENESAS、PICと幅広いボードで利用可能できそうです。




BLE Shield同様にFirmataプロトコル用のサンプルスケッチが提供されています。
※このサンプルスケッチはArduino Uno用になっており、Arduino Leonardoで動作させるには修正が必要でした。

BLE Miniはファームウェアの書き換えが可能で、後述のiBeaconのように単独での動作も可能になります。公式サイトによるとファームウェアの開発環境についてはまだベータ版ということですが、今後の広がりに期待が持てます。

iBeaconとBLE Mini

BLE MiniにはArduinoのような別のマイコンに接続せず、
単独でiBeaconとなるファームウェアが提供されています。
2013/10/07現在は正式な仕様が公開されておらず、
このファームウェアは試験評価用という位置づけですが、
こちらもiPhone用のサンプルプログラムが公開されており、
どのように動作するかを体験することができます。




非常に汎用的ですので応用すれば自分たちでBLEを用いたハードウェアを創ることもできます。BLEは省電力かつ手軽に使えるということからこれを使ったデバイスが増えていくことが期待されますので、これからもこういったモジュールを追って行きたいと思います。


なお、今回紹介したRedBearLab社のBLEモジュールは技術基準適合は受けておりません。電波暗室や電波障害を起こさない十分に広い敷地・建屋内で実験を行ってください。不用意に電波を発射すると、日本の法律に反する可能性がありますのでご注意ください。

2013年10月4日金曜日


最近よく耳にするiBeaconとはなんでしょうか。Appleはまだ明言していないようですが、いろいろなサイトを読むと、Bluetooth 4.0 で導入されたBLE(=Bluetooth Low Energy)をiOSで使えるようにしたものの総称のようです。iOS7から実装されています。

今、流行のiBeaconとは?


最近よく耳にするiBeaconとはなんでしょうか。Appleはまだ明言していないようですが、いろいろなサイトを読むと、Bluetooth 4.0 で導入されたBLE(=Bluetooth Low Energy)をiOSで使えるようにしたものの総称のようです。iOS7から実装されています。

2012年6月25日月曜日



Want to use iCloud's key-value store, NSUbiquitousKeyValueStore, to synchronize data in your app between devices?
 
I've started using NSUbiquitousKeyValueStore in my game "Harigana" but noticed a flaw that I would like to share. Nothing much really, just a small tip.

The recommendation is that you early in your app start cycle call

[[NSUbiquitousKeyValueStore defaultStore] synchronize];

and then start listen to the notification NSUbiquitousKeyValueStoreDidChangeExternallyNotification.

This will call your app when the store is changed on other devices. However, this seems to be reliable only if the app is active at the time the other device changes a value. If the app is not running at the time the store is updated you might not get notification when you wake the app up. Sometimes it works, sometimes not, according to my experience.

Therefor, to be sure you have the latest value from iCloud, force a synchronization at app startup/wakeup. Simply iterate through all values in your NSUbiquitousKeyValueStore and overwrite the local value with the value from the store. Of course, this requires that when you store the values, always store the them in both iCloud's key-value store and the user defaults, otherwise you might overwrite users hard earned points with something that could be zero. iOS will take care of everything for you under the hood, whether the user has activated iCloud or not.

Remember, the truth is in the Cloud.

iCloud key-value store



Want to use iCloud's key-value store, NSUbiquitousKeyValueStore, to synchronize data in your app between devices?
 
I've started using NSUbiquitousKeyValueStore in my game "Harigana" but noticed a flaw that I would like to share. Nothing much really, just a small tip.

The recommendation is that you early in your app start cycle call

[[NSUbiquitousKeyValueStore defaultStore] synchronize];

and then start listen to the notification NSUbiquitousKeyValueStoreDidChangeExternallyNotification.

This will call your app when the store is changed on other devices. However, this seems to be reliable only if the app is active at the time the other device changes a value. If the app is not running at the time the store is updated you might not get notification when you wake the app up. Sometimes it works, sometimes not, according to my experience.

Therefor, to be sure you have the latest value from iCloud, force a synchronization at app startup/wakeup. Simply iterate through all values in your NSUbiquitousKeyValueStore and overwrite the local value with the value from the store. Of course, this requires that when you store the values, always store the them in both iCloud's key-value store and the user defaults, otherwise you might overwrite users hard earned points with something that could be zero. iOS will take care of everything for you under the hood, whether the user has activated iCloud or not.

Remember, the truth is in the Cloud.

2012年5月15日火曜日


 

I was really surprised when one of my apps was rejected by Apple when all I did was update the icon and the app have past previous reviews with flying colors. It seems like there's a new rule about data you store in the /Documents folder.

All files in the Documents folder are backed up to iCloud and such files that can be re-downloaded or re-created should not be stored there. For obvious reasons, to not waste those precious 5 GB we have by default. However, if you put your data in Caches folder or tmp folder, it might be deleted in low storage situations so there is a new solution from iOS 5.0.1.

This allows you to put files that you generate, like a read-only database, to the Documents folder without having it backed up to iCloud.

Here's a snippet from iOS Developer Library

Q:  My app has a number of files that need to be stored on the device permanently for my app to function properly offline. However, those files do not contain user data and don't need to be backed up. How should I store those files in iOS 5?

A: Starting in iOS 5.0.1 a new "do not back up" file attribute has been introduced allowing developers to clearly specify which files should be backed up, which files are local caches only and subject to purge, and which files should not be backed up but should also not be purged. In addition, setting this attribute on a folder will prevent the folder and all of its contents from being backed up.

Important The new "do not back up" attribute will only be used by iOS 5.0.1 or later. On iOS 5.0 and earlier, applications will need to store their data in <Application_Home>/Library/Caches to avoid having it backed up. Since this attribute is ignored on older systems, you will need to insure your app complies with the iOS Data Storage Guidelines on all versions of iOS that your application supports.

How to set the attribute

#include <sys/xattr.h>

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

Data in the Documents folder


 

I was really surprised when one of my apps was rejected by Apple when all I did was update the icon and the app have past previous reviews with flying colors. It seems like there's a new rule about data you store in the /Documents folder.

All files in the Documents folder are backed up to iCloud and such files that can be re-downloaded or re-created should not be stored there. For obvious reasons, to not waste those precious 5 GB we have by default. However, if you put your data in Caches folder or tmp folder, it might be deleted in low storage situations so there is a new solution from iOS 5.0.1.

This allows you to put files that you generate, like a read-only database, to the Documents folder without having it backed up to iCloud.

Here's a snippet from iOS Developer Library

Q:  My app has a number of files that need to be stored on the device permanently for my app to function properly offline. However, those files do not contain user data and don't need to be backed up. How should I store those files in iOS 5?

A: Starting in iOS 5.0.1 a new "do not back up" file attribute has been introduced allowing developers to clearly specify which files should be backed up, which files are local caches only and subject to purge, and which files should not be backed up but should also not be purged. In addition, setting this attribute on a folder will prevent the folder and all of its contents from being backed up.

Important The new "do not back up" attribute will only be used by iOS 5.0.1 or later. On iOS 5.0 and earlier, applications will need to store their data in <Application_Home>/Library/Caches to avoid having it backed up. Since this attribute is ignored on older systems, you will need to insure your app complies with the iOS Data Storage Guidelines on all versions of iOS that your application supports.

How to set the attribute

#include <sys/xattr.h>

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

2012年4月3日火曜日

The other day I was preparing our new game for release and while tests using the debug build worked beautifully the game suddenly starting crashing in a weird situation that was difficult to discover when run using the release build.

Narrowing it down to the fact that it worked without optimization but crashed with any level of optimization I figured some object that should be released hadn't been released, or released to soon, or maybe not released at all.

This introduced me to the great feature "Zombie objects" for the first time. Zombie objects are not enabled by default so you have to enable this in the scheme configuration of your project. Zombie objects keep released objects in memory so instead of getting an error like "EXC_BAD_ACCESS" you can see what kind of object your code is trying to access. Great, isn't it?

So now I could see what object my code was trying to access when it crashed and also where in the code the crash happened instead of seeing just a block of assembler code.

ARC, Automatic Reference Counting, is great new feature of Objective-C that manages the pointers for you and releases the objects when they are not longer referenced to. However, it is different from Garbage Collection and apparently we need to take care in certain situations otherwise error likes this might happen.

Maybe this is only because my lack of knowledge, or maybe unknown "feature" of ARC. Anyhow, I want to share this with whoever finds their way to this blog.

I the code causing trouble I have  a matrix of pointers, like this:

__strong Tile  *_board[13][13];

Actually you don't need the keyword __strong because it is default but I put it there for clarity. This means that this matrix will strongly hold on to whatever Tile pointers I put there. Good, now we want to do something with these pointers. Like finding out where row of tiles start vertically.

while (row > 0) {
    Tile *t = _board[row-1][column];
    if(t == nil) break;
    row--;
}

This work great in debug mode (no optimization) but crashes in release mode with code optimization. Well, it doesn't crash the first time it is run but the second time, after it's gone out of scope. Apparently all the Tile objects iterated over is released when the method goes out of scope.

Changing the code to this solved the problem.

while (row > 0) {
    if(_board[row-1][column] == nilbreak;
    row--;
}

However, this seem to only apply to while loops. For loops does not cause the same behavior using ARC. I think I will head over to Apple's documentation and see if I can find a reason for why this is the case...

Debug Build OK - Release Build CRASH - ARC?

The other day I was preparing our new game for release and while tests using the debug build worked beautifully the game suddenly starting crashing in a weird situation that was difficult to discover when run using the release build.

Narrowing it down to the fact that it worked without optimization but crashed with any level of optimization I figured some object that should be released hadn't been released, or released to soon, or maybe not released at all.

This introduced me to the great feature "Zombie objects" for the first time. Zombie objects are not enabled by default so you have to enable this in the scheme configuration of your project. Zombie objects keep released objects in memory so instead of getting an error like "EXC_BAD_ACCESS" you can see what kind of object your code is trying to access. Great, isn't it?

So now I could see what object my code was trying to access when it crashed and also where in the code the crash happened instead of seeing just a block of assembler code.

ARC, Automatic Reference Counting, is great new feature of Objective-C that manages the pointers for you and releases the objects when they are not longer referenced to. However, it is different from Garbage Collection and apparently we need to take care in certain situations otherwise error likes this might happen.

Maybe this is only because my lack of knowledge, or maybe unknown "feature" of ARC. Anyhow, I want to share this with whoever finds their way to this blog.

I the code causing trouble I have  a matrix of pointers, like this:

__strong Tile  *_board[13][13];

Actually you don't need the keyword __strong because it is default but I put it there for clarity. This means that this matrix will strongly hold on to whatever Tile pointers I put there. Good, now we want to do something with these pointers. Like finding out where row of tiles start vertically.

while (row > 0) {
    Tile *t = _board[row-1][column];
    if(t == nil) break;
    row--;
}

This work great in debug mode (no optimization) but crashes in release mode with code optimization. Well, it doesn't crash the first time it is run but the second time, after it's gone out of scope. Apparently all the Tile objects iterated over is released when the method goes out of scope.

Changing the code to this solved the problem.

while (row > 0) {
    if(_board[row-1][column] == nilbreak;
    row--;
}

However, this seem to only apply to while loops. For loops does not cause the same behavior using ARC. I think I will head over to Apple's documentation and see if I can find a reason for why this is the case...

2012年3月2日金曜日

The second post about the making of iNippon, the English-Japanese dictionary of conversations about Japan.

More information about the app can be found in iTunes Preview or in the previous blog post.
This time we take a close look at the History page.



Default view, all scrolls closed.
One scroll open.

Usage:
- Tapping a scroll will open it with an animation.
- Tapping an open scroll will close it with an animation.
- Tapping a closed scroll while another scroll is open will first close the open scroll and then open the scroll that was tapped.
- Tapping a historical event will toggle its language between English and Japanese. Of course the height of the text will change and by getting the content height of the UITextView we can tell the UITableView controller of the new row height and with a nice animation adjust the height of that row as well as the y-position of all rows below it (automatically done for us by the UITableView).

The first idea that probably comes to everyones mind is to use a tableview with the scrolls as section headers and each historical event as row in that section (data read from database). At least, that's what I thought would be the natural approach and as a matter of fact, Apple has sample code showing how to implement this and how to make it looks nice with the new animation features in UITableView.

The sample code is called "Table View Animations and Gestures"(Shakespeare plays and citations) and can be found in the iOS Developer Library. If I remember correctly this might also be presented in a WWDC 2010 video which you can access if you are a registered developer.

Problem
There is a problem however with this sample code and how the animations are implemented and I will try to explain to you how to reproduce this.
- Download the sample code and run the app in the simulator.
- Expand the first section header
- Pinch out to make the rows of the first section taller, do this until the second section header disappears out of the bottom part of the screen.
- Scroll down to the second section header and tap it. 

Now the new UITableView animations will animate the closing of the first section and the opening of the second section. This usually looks nice except in this case. If you followed these steps you will see that the animation "flickers", and doesn't look nice at all. Try it with the iPhone simulator's "slow animations"-option and you'll see what's going on. This was totally unacceptable for me and no matter how I tried I could not make this particular case animate in a nice way so I had to scrap this implementation.

Solution
Because I use Core Data and the user can toggle between languages in individual events (which will change the height that item) I wanted to use UITableView to get "free" animations when changing heights. However, I couldn't use it for expanding and contracting sections in a way that would give a good user experience and nice animations. 

What came to be the solution that can be experienced in the app is the following.
For all the headers, that is, the scrolls themselves, I put them in plain UIViews and stack them from top to bottom.

When a user taps a scroll, I load up a customized UITableView which is hidden behind the scroll and then animate it down so it looks like the scroll is being unrolled and the the same adjust the y-position of all the scrolls below so they don't get covered by the opening scroll.

Also, when a user change the language of an individual event the table view will change height and animate automatically, but at this time I also have to adjust the y-position of all scrolls below with the same animation duration as the table view.

When closing a scroll I basically do the opposite. A bunch of animations, all with the same duration makes this look really natural and nice.

So how about the problem that was caused by Apple's implementation. No problem anymore. When a user taps a closed scroll while another scroll is open, I first close the open one and then open the one that was tapped and set the content offset of the outer scroll view so that the opened scroll is at the top of the screen.

Maybe creating a new controller especially for this would had been the most elegant solution but in this case I wanted to save time and reuse the UITableView I already had at hand so the solution became a mix of my own controller for the section headers (scrolls) and a UITableView for the events.

I haven't bothered filing a bug report to Apple about this behavior because if they took the time to create the sample code and properly test it, this malfunctioning animation should have been obvious to them and I doubt a bug report will fix anything if they haven't fixed it earlier. 

However, maybe the best thing to do is to file that bug report anyway...


iNippon Part 2

The second post about the making of iNippon, the English-Japanese dictionary of conversations about Japan.

More information about the app can be found in iTunes Preview or in the previous blog post.
This time we take a close look at the History page.



Default view, all scrolls closed.
One scroll open.

Usage:
- Tapping a scroll will open it with an animation.
- Tapping an open scroll will close it with an animation.
- Tapping a closed scroll while another scroll is open will first close the open scroll and then open the scroll that was tapped.
- Tapping a historical event will toggle its language between English and Japanese. Of course the height of the text will change and by getting the content height of the UITextView we can tell the UITableView controller of the new row height and with a nice animation adjust the height of that row as well as the y-position of all rows below it (automatically done for us by the UITableView).

The first idea that probably comes to everyones mind is to use a tableview with the scrolls as section headers and each historical event as row in that section (data read from database). At least, that's what I thought would be the natural approach and as a matter of fact, Apple has sample code showing how to implement this and how to make it looks nice with the new animation features in UITableView.

The sample code is called "Table View Animations and Gestures"(Shakespeare plays and citations) and can be found in the iOS Developer Library. If I remember correctly this might also be presented in a WWDC 2010 video which you can access if you are a registered developer.

Problem
There is a problem however with this sample code and how the animations are implemented and I will try to explain to you how to reproduce this.
- Download the sample code and run the app in the simulator.
- Expand the first section header
- Pinch out to make the rows of the first section taller, do this until the second section header disappears out of the bottom part of the screen.
- Scroll down to the second section header and tap it. 

Now the new UITableView animations will animate the closing of the first section and the opening of the second section. This usually looks nice except in this case. If you followed these steps you will see that the animation "flickers", and doesn't look nice at all. Try it with the iPhone simulator's "slow animations"-option and you'll see what's going on. This was totally unacceptable for me and no matter how I tried I could not make this particular case animate in a nice way so I had to scrap this implementation.

Solution
Because I use Core Data and the user can toggle between languages in individual events (which will change the height that item) I wanted to use UITableView to get "free" animations when changing heights. However, I couldn't use it for expanding and contracting sections in a way that would give a good user experience and nice animations. 

What came to be the solution that can be experienced in the app is the following.
For all the headers, that is, the scrolls themselves, I put them in plain UIViews and stack them from top to bottom.

When a user taps a scroll, I load up a customized UITableView which is hidden behind the scroll and then animate it down so it looks like the scroll is being unrolled and the the same adjust the y-position of all the scrolls below so they don't get covered by the opening scroll.

Also, when a user change the language of an individual event the table view will change height and animate automatically, but at this time I also have to adjust the y-position of all scrolls below with the same animation duration as the table view.

When closing a scroll I basically do the opposite. A bunch of animations, all with the same duration makes this look really natural and nice.

So how about the problem that was caused by Apple's implementation. No problem anymore. When a user taps a closed scroll while another scroll is open, I first close the open one and then open the one that was tapped and set the content offset of the outer scroll view so that the opened scroll is at the top of the screen.

Maybe creating a new controller especially for this would had been the most elegant solution but in this case I wanted to save time and reuse the UITableView I already had at hand so the solution became a mix of my own controller for the section headers (scrolls) and a UITableView for the events.

I haven't bothered filing a bug report to Apple about this behavior because if they took the time to create the sample code and properly test it, this malfunctioning animation should have been obvious to them and I doubt a bug report will fix anything if they haven't fixed it earlier. 

However, maybe the best thing to do is to file that bug report anyway...


2012年2月24日金曜日

Starting from now I will spend a few post talking about an app that I made shortly before starting at Brilliant Service, during my job search period. I think there are some implementations that might be interesting for other developers out there.

Take a look at iNippon in the iTunes Preview page here:  English  Japanese

In this post I'll share my experiences of implementing the UIPageViewController that is used in the new template Page-Based Application found in Xcode. For those of you who are not familiar with this, take a look at the iBooks app. The API for creating this beautiful and natural turning of pages is now made available using the UIPageViewController.

What the implementation in iNippon looks like can be seen in this screenshot.

iNippon, Today's view

Similar to UITableViewController, UIPageViewController takes a delegate and a datasource. Simply put, the datasource provide UIViewControllers for the UIPageViewController to display. The template in Xcode provides a fully functional implementation and it shouldn't be any problem to get ones head around how it works.

Problem
The template provided by Apple in Xcode creates new UIViewControllers on the fly when you start to turn the page. I started with this approach and it worked fine in the simulator and on the older generation iPod Touch and iPhone 3GS but on the iPhone 4 it was really slow and jerky. At first I thought this was weird but found the answer when removing the loading of the background image made it really fast and smooth. One might think that the iPhone 4 should be faster at loading images than the 3GS but in this case I used separate images sizes using the @2x suffix so the 3GS only loads an image that is 320x367 while the iPhone 4 uses an image that is 640x734 pixels, four times as much data as the lower resolution. Even though the iPhone 4 is faster it's not four times faster at this task, it seems.

Solution
So, have should we handle this? Some users might never turn the page while some users might use this functionality to flick through pages in a fast pace. Ten background images with different motives are used and loading them all into memory seems like a waste of valuable resources, especially considering most of them might not even be displayed. Remember memory is a valuable resource in mobile devices and by keeping our memory footprint low we keep other apps from being deallocated as well as improving our own loading time which will improve the overall user experience.

The solution came to be a compromise between fast page turning and memory usage. What I do is, in the datasource I keep an NSArray with 3 UIViewControllers, loaded and ready to be displayed. The one in the middle position is the one currently on screen, the others are the previous and the next page. If you turn a page the UIViewController at the next position is provided to the UIPageViewController and once the UIPageViewController has finished it's animations the next UIViewController is loaded and inserted into the array so that the array always contains three UIViewControllers. Of course, I have to keep the user from turning page again until the new UIViewController has loaded completely but this is easy done by deactivating the UIGestureRecognizers during this time. If the user takes the time to look through the content of the page, the new UIViewController will be loaded and ready well in time before the user turns page again. And as always, the edge case has to be handle separately when the user is on page zero and there are no more pages in back direction.

Utilize the UIPageViewController and create beautiful page-based applications you too. They provide a great user experience and make it fun to flick through pages.

iNippon Part 1

Starting from now I will spend a few post talking about an app that I made shortly before starting at Brilliant Service, during my job search period. I think there are some implementations that might be interesting for other developers out there.

Take a look at iNippon in the iTunes Preview page here:  English  Japanese

In this post I'll share my experiences of implementing the UIPageViewController that is used in the new template Page-Based Application found in Xcode. For those of you who are not familiar with this, take a look at the iBooks app. The API for creating this beautiful and natural turning of pages is now made available using the UIPageViewController.

What the implementation in iNippon looks like can be seen in this screenshot.

iNippon, Today's view

Similar to UITableViewController, UIPageViewController takes a delegate and a datasource. Simply put, the datasource provide UIViewControllers for the UIPageViewController to display. The template in Xcode provides a fully functional implementation and it shouldn't be any problem to get ones head around how it works.

Problem
The template provided by Apple in Xcode creates new UIViewControllers on the fly when you start to turn the page. I started with this approach and it worked fine in the simulator and on the older generation iPod Touch and iPhone 3GS but on the iPhone 4 it was really slow and jerky. At first I thought this was weird but found the answer when removing the loading of the background image made it really fast and smooth. One might think that the iPhone 4 should be faster at loading images than the 3GS but in this case I used separate images sizes using the @2x suffix so the 3GS only loads an image that is 320x367 while the iPhone 4 uses an image that is 640x734 pixels, four times as much data as the lower resolution. Even though the iPhone 4 is faster it's not four times faster at this task, it seems.

Solution
So, have should we handle this? Some users might never turn the page while some users might use this functionality to flick through pages in a fast pace. Ten background images with different motives are used and loading them all into memory seems like a waste of valuable resources, especially considering most of them might not even be displayed. Remember memory is a valuable resource in mobile devices and by keeping our memory footprint low we keep other apps from being deallocated as well as improving our own loading time which will improve the overall user experience.

The solution came to be a compromise between fast page turning and memory usage. What I do is, in the datasource I keep an NSArray with 3 UIViewControllers, loaded and ready to be displayed. The one in the middle position is the one currently on screen, the others are the previous and the next page. If you turn a page the UIViewController at the next position is provided to the UIPageViewController and once the UIPageViewController has finished it's animations the next UIViewController is loaded and inserted into the array so that the array always contains three UIViewControllers. Of course, I have to keep the user from turning page again until the new UIViewController has loaded completely but this is easy done by deactivating the UIGestureRecognizers during this time. If the user takes the time to look through the content of the page, the new UIViewController will be loaded and ready well in time before the user turns page again. And as always, the edge case has to be handle separately when the user is on page zero and there are no more pages in back direction.

Utilize the UIPageViewController and create beautiful page-based applications you too. They provide a great user experience and make it fun to flick through pages.

2012年2月13日月曜日


http://upload.wikimedia.org/wikipedia/en/0/0c/Xcode_icon.pngXcode has great code-completion (or auto-completion) and by utilizing this wisely we can save ourselves lots of trouble. A good thing to do at the beginning of every app development is to create an global.h file to hold all constants, strings, etc, and include this in all the classes where needed. Even though it might not feel necessary at the start of a small project, as new functionality is added the amount of constants, strings, etc, needed quickly grows and it becomes difficult to remember them all. By collecting them all in one place, we make configuration, updates and changes very easy to do.


My Global.h can look something like this:

// NSUserDefaults
#define kUDMusicState           @"MusicState"           // BOOL
#define kUDSoundState           @"SoundState"           // BOOL
#define kUDNrOfPlayers          @"NrOfPlayers"          // int
#define ...

// Notification Center
#define kNCFacebookLogin        @"FacebookDidLogin"
#define kNCFacebookLogout       @"FacebookDidLogout"
#define ...

// Images
#define kImageHelpGamePhone     @"helppageGame"        
#define kImageHelpGamePad       @"helppageGame~pad"
#define ...

Now, when somewhere in my code I need to access NSUserDefaults. I know that all my NSUserDefault keys start with kUD... so when I type kUD all the keys are presented to me and I can easily choose from the menu the one I need.
















Same when I need an images, simply typing kImage... and code-completion gives my a list of all my defined image names. No more going back to check what the filename was or looking for bugs that are caused by wrong spelling in the key string (maybe I'm the only one who get this kind of bug *_* )

If Xcode doesn't show the auto-completion list, try hitting ESC. If still no suggestion comes up, the needed file is not included or you're trying write something that doesn't belong there. On rare occasions the auto-completion systems fails to work properly but building the project should solve that.

If you have any good tip on how to make the most of Xcode, please let me know!

Utilize Auto-Completion in Xcode


http://upload.wikimedia.org/wikipedia/en/0/0c/Xcode_icon.pngXcode has great code-completion (or auto-completion) and by utilizing this wisely we can save ourselves lots of trouble. A good thing to do at the beginning of every app development is to create an global.h file to hold all constants, strings, etc, and include this in all the classes where needed. Even though it might not feel necessary at the start of a small project, as new functionality is added the amount of constants, strings, etc, needed quickly grows and it becomes difficult to remember them all. By collecting them all in one place, we make configuration, updates and changes very easy to do.


My Global.h can look something like this:

// NSUserDefaults
#define kUDMusicState           @"MusicState"           // BOOL
#define kUDSoundState           @"SoundState"           // BOOL
#define kUDNrOfPlayers          @"NrOfPlayers"          // int
#define ...

// Notification Center
#define kNCFacebookLogin        @"FacebookDidLogin"
#define kNCFacebookLogout       @"FacebookDidLogout"
#define ...

// Images
#define kImageHelpGamePhone     @"helppageGame"        
#define kImageHelpGamePad       @"helppageGame~pad"
#define ...

Now, when somewhere in my code I need to access NSUserDefaults. I know that all my NSUserDefault keys start with kUD... so when I type kUD all the keys are presented to me and I can easily choose from the menu the one I need.
















Same when I need an images, simply typing kImage... and code-completion gives my a list of all my defined image names. No more going back to check what the filename was or looking for bugs that are caused by wrong spelling in the key string (maybe I'm the only one who get this kind of bug *_* )

If Xcode doesn't show the auto-completion list, try hitting ESC. If still no suggestion comes up, the needed file is not included or you're trying write something that doesn't belong there. On rare occasions the auto-completion systems fails to work properly but building the project should solve that.

If you have any good tip on how to make the most of Xcode, please let me know!
Related Posts Plugin for WordPress, Blogger...