Title

unameで取得できるiOSデバイスの名前一覧

抜けがない完全なリストが何故かみつからなかったので、改めてまとめてみました。
リビジョン違いなど、微妙に派生ハージョンがあるのが要注意ですね。
iPhone5もモデルが2種類あります。
また、iPad miniはiPad2と同系列ですね。

■iPhone
“iPhone1,1”

■iPhone3G
“iPhone1,2”

■iPhone3GS
“iPhone2,1”

■iPhone4
“iPhone3,1” //GSMモデル
“iPhone3,2” //GSMモデル(Rev.A)
“iPhone3,3” //CDMAモデル

■iPhone4S
“iPhone4,1”

■iPhone5
“iPhone5,1” //A1428モデル
“iPhone5,2” //A1429モデル

■iPod touch
“iPod1,1” //初代(スピーカーなし)
“iPod2,1” //第2世代
“iPod3,1” //第3世代(8GBモデルは第2世代と同じ)
“iPod4,1” //第4世代(Retina、カメラ搭載)
“iPod5,1” //第5世代(iPhone5と同じサイズのディスプレイ)

■iPad初代
“iPad1,1” //Wifi
“iPad1,2” //GSM

■iPad2
“iPad2,1” //Wifi
“iPad2,2” //GSM
“iPad2,3” //CDMA
“iPad2,4” //Wifi(Rev.A)

■iPad mini
“iPad2,5” //Wifi
“iPad2,6” //GSM
“iPad2,7” //CDMA

■The new iPad (第3世代)
“iPad3,1” //Wifi
“iPad3,2” //GSM
“iPad3,3” //CDMA

■iPad Retina display model(第4世代)
“iPad3,4” //Wifi
“iPad3,5” //GSM
“iPad3,6” //CDMA

大人になったらゲームやりほうだい!!

この前、家に着ていた男の子(小学校低学年)が、ずっとDSやりたい、DSやりたいって言ってました。
ずっとゲームばっかで親も困ってるらしい。

なんかなー。
やっぱDSやってる子供みると良くないよなぁって見えてしまう。

そこで僕の持っているNintendoDSと3DSとPSP2台,PS Vitaをおもむろに取り出し、
ゲームは子供がするもんじゃないよ、大人になったらやり放題だよ って見せてやりました。

ゲームは大人の嗜みですよね。

写真 2013-02-01 1 45 51

「努力すれば報われる」っておかしいよね

たとえ話です。

とある部族は、旱魃(かんばつ)が起きると雨乞いのための儀式を行います。
この儀式は部族に古くから伝わるもので、これまで数々の旱害から人々を救ってきました。

さて、現代人には当たり前ですが、ふつう、人間の儀式くらいで雨は降りません。
つまり、儀式は天候に何の影響も与えないはずです。

しかしながら、この部族の儀式の成功率は100%であると言います。
何故でしょうか?

答えは簡単です。
雨が降るまで儀式を続けるのです。
途中で誰かが死のうが、絶対に続けるのです。
そうすると、いつか雨が降ります。
儀式は成功します。

努力をします。
努力とは全く無関係な幸運によって、成功したとします。
努力は報われました。

努力をします。
しかし努力の量とは無関係な不運によって、成功しませんでした。
努力が足りませんでした。
もっと努力を続けて成功させるべきですね。
そうすれば、いつかきっと報われるはずです。

というわけで、「努力は報われる」というアドバイスは論理的に破綻しており、意味がありません。
「どのくらい」努力をすると、「どのように」報われるのか定量的に示さない人の言うことは聞く必要ありません。

我慢して「努力する」ことは不合理だと思う

学校の成績などで相対評価(つまり偏差値)が使われることがよくありますが、あれは成績の出現が正規分布になることを期待しているわけです。

しかしながら人の意思が働くような事柄では正規分布にならない事の方が多いということが知られており、実際に試験の成績分布は正規分布にならないそうです。
(なので相対評価は問題であると唱える人もいます)

それでは先天的な才能(もしくは物心つくまでに身につけた能力)の出現は正規分布に近似できるのでしょうか。

先天的な才能には人の意思が入る要素が(ほとんど)ありません。才能の違いはまさに多数の因子の和であり、遺伝子の誤差とも言えます。そのような仮定をすると才能は正規分布で出現することになります。
(独立な要素の和は正規分布になります。=中心極限定理)

仮に才能が正規分布に従うとしましょう。

世の中には天才的な才能を持つ人がいます。
分散±3σに収まる割合は99.73%です。
500人に一人は平均値+3σを超える才能を持つわけです。
(そして同時に平均値-3σ以下の才能を持つ人間もいるということになります)

「努力したら報われる」は結果論でしかありません。
せっかく努力をしても才能に恵まれず報われないことはよくあります。それが徒労としか言えない結果になることもあります。
人はその徒労への恐怖があるからこそ努力できないのです。

仮に自分が+2σの才能を持っているとすると、それは全体の5%未満のすぐれた才能です。きっと自分は優れていて、努力すれば報われると思えることでしょう。
しかしながら更に平均から倍も離れた+4σの分布に入る人も約0.006%存在します。
1億人の人がいたらその中に6340人もいることになります。

才能がなくても人並み以上の努力でカバーできるという主張は、努力で埋められる値の方が才能の分散σよりも十分に大きいと言っていることになります。
もちろん分野によりますが、経験的にそれは正しくありません。

「自分には才能がないから努力しない」というのは殆どの人にとって正しい選択です。
徒労への恐怖は当然の感覚であり、合理的な判断に基づくものです。

努力が徒労にならない場合、それは努力自体が楽しい場合です。結局好きであることが最大の才能なんですね。(というよりは、才能があってうまくいくことは楽しくできるんですね)

我慢してまで何かをやる必要はないと思ってます。
それは徒労になる可能性が高く、声高に努力を薦める人は無責任な人で、徒労の損害を補償してくれません。

どうせなら好きなことを努力しましょう。徒労になる心配がないので。

iOSでBluetoothキーボードの入力を取得する(ハードウエアキーボードのキー取得)

結論からいうと例によって公式な方法は無いようです。

BluetoothキーボードからUITextFieldに文字を入力できますが、直接キー入力を取得するには以下の非公式な方法で可能なようです。
非公開メソッドを使ってしまうので何かとやっかいです。。

まず、UIApplicationに来るイベントを監視します。
UIApplicationのsendEventをオーバーライドするとアプリケーションに色々なイベントが飛んでくるのが見られます。

UIEventの非公開メソッドである_gsEvent:で得られるポインタが指す、正体不明なデータを監視してみると、なんか入ってます。仮に32bit単位読んで先頭を0番目とすると、2番目にキーを押したかどうか、12番目に修飾キーの情報、15番目にキーコードっぽいものが入っているのがわかります。このコードは何なのかは不明な値ですが、とりあえずキーに対応した固有の値が入ります。他にも[17]番目はアスキーコードっぽいのが入るみたいです。
アローキーやファンクションキーなどの特殊キーも取得できます。
シフトキーやコントロールキーが押されたかどうかは12番目の値を見るとビット和で入っています。

詳しくはサンプルプログラムを作りましたので見てみてください。
https://github.com/rhotta/iOS_bluetoothKeyboardInputSample

普段は編集することのないmain関数を編集します。
UIApplicationMainの第3引数に独自クラス名を指定するとUIApplicationをオーバーライドできます。

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, @"MyUIApplication", NSStringFromClass([AppDelegate class]));
    }
}

新しい子育てアプリをリリースしました「添い寝アラーム」

前々からちょっと書いていましたが、新しいアプリをリリースしました。

そもそも、ComicGlassの開発するために子どもを寝かしつけてから時間を取っていたのですが、子どもと一緒に寝てしまうんですよね。

この「子どもと一緒に寝てしまう」問題は多くの親が「そうそう!」って頷く問題なわけですが、それをなんとかしようというアプリです。アプリ名は「添い寝アラーム」です。

スクリーンショットはこんな感じ。

添い寝アラームスクリーンショット1

まず、最初にやったのは「暗闇でも止められるアラーム」です。
普通のアラームアプリは画面を見て止めますよね?
あれだと、もしまだ子どもが寝ていなかったりするときに画面を点灯させなければならないのが困るのです。
そういうわけで、加速度センサを利用し、iPhoneを軽く叩くとアラームがスヌーズになるアラームアプリを作りました。

しかし、これでやってみるとアラーム時間を何分後くらいに設定すればいいのかが難しい。
絵本を読み聞かせている途中になってしまったり、まだ子どもが起きていてしゃべっている最中や、ゴロゴロ転がっている(子どもはよく動きます)途中にアラームがなってしまったりします。

そこでアラーム時間の自動設定方法の開発に取り組みました。
使えるのはマイクと加速度センサ。

連日データを収集し、毎秒どのくらいのデータを取得し、どのように信号処理したらいいのかを試験しました。
少しでも楽に使えたらいいなーと思いながら毎回すこしづづ改善をした結果、それなりに良い感じになってきたので、本格的にアプリにしてみました。
(最初に時点では完全自分用で公開するつもりはなかったのですが)

添い寝アラームスクリーンショット2

最終的に、iPhoneの接近センサー、バイブレーター、マイク、スピーカー、加速度センサ、と、かなり内蔵デバイスを多く使うアプリになりました。
技術的な話をすれば、普通じゃありえないような頻度でAudioSessionを切り替えていたりと色々勉強になりました。

簡単に書きますと、
まずAudioSessionを切り替え、マイク入力を有効にします。

        AudioSessionInitialize(NULL, NULL, NULL, NULL);
        UInt32 category = kAudioSessionCategory_PlayAndRecord;
        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                                sizeof(UInt32),
                                &category);
        AudioSessionSetActive(YES);

それで音声をモニタリング。

加速度センサは60Hzで取得して微分して使っています。

音声と加速度の認識処理の部分は説明できないので省きますが、完璧な検出はやはり無理なので、アラームタイミングを長くしたり短くしたりすることでだいたい目的の動作が得られるようになっています。

アラームタイミングになると、オーディオセッションをマナーモードでも音が出るようにPlaybackに切り替えてバイブレーターを鳴らします。
(録音モードのままだとスピーカーの音量が自動的に抑えられてしまうというのもあります)

もう一つ苦労したのが、スヌーズのやり方です。
iPhoneを軽く叩いた事を検出すればいいだけなので一見簡単そうなのですが、同時にバイブレーターが動作しているというのが問題でした。
iPhoneを置いている場所(の硬さ)によってバイブレーター→謎の伝達関数→加速度センサの値が全然違うんですよね。

そこで、最初の一定時間は「謎の伝達関数」を推定する処理を行い、その後軽く叩いた動作を検出するようにしています。
最初の着想は簡単だったのですが、調整がとにかく大変でした・・・。

子育て中で、「寝てしまう!」問題にお困りの方がいらっしゃいましたら是非お試しくださいませ。

↓こちら
添い寝アラーム - RR Soft

Xcode4.3にしたらFileMargeが見つからない

↓ココにあります。
/Applications/Xcode.app/Contents/Applications/FileMerge.app

XcodeのメニューのOpen Developer Toolからも起動可能。

いろいろな日付の計算(曜日・日付・日本の祝日)

カレンダーを作るにあたって必要な以下の点を考察してみます。
特に祝日の計算は日付クラスなんかを使っても出来ないことが多いので頑張りが必要です。
・日付→任意の曜日
・月が何日までか
・日本の祝日、国民の休日にあたるかどうか

まず任意の日付の曜日を得る方法。
これは簡単。有名なツェラーの公式を使います。

if (y*366+m*31+d < 1582*366+10*31+15) return -1;
return (y + y/4 - y/100 + y/400 + (13*m+8)/5 + d) % 7;

次に任意の月の最後の日(=日数)を計算する方法。
2月以外は固定なので、要するに閏年の計算になります。
閏年を4年に1度と勘違いしている場合がありますが、それだけだと誤差が蓄積するので以下のルールになっています。
1.西暦が4で割り切れる年
2.ただし、100で割り切れる場合は例外
3.ただし、400で割り切れる場合は2のルールは適用しない

int last;
switch(m){
	case 1:last = 31;break;
	case 2:
		//うるう年の算出
		if(y % 4 ==0){
			if(y % 100 == 0) {
				if(y % 400 == 0){
					last=29;		
				}else{
					last=28;
				}
			}else{
				last=29;
			}
		}else{
			last=28;
		}
		break;
	case 3:last = 31;break;
	case 4:last = 30;break;
	case 5:last = 31;break;
	case 6:last = 30;break;
	case 7:last = 31;break;
	case 8:last = 31;break;
	case 9:last = 30;break;
	case 10:last = 31;break;
	case 11:last = 30;break;
	case 12:last = 31;break;
	default: return 0;
}
return last;

最後に祝日・休日の計算方法について
今後制定される祝日については予測のしようがないので仕方が無いとして、既に制定されている祝日について考えます。

日付が固定されている祝日は楽ですが、ハッピーマンデーや振り替え休日がありますので注意が必要です。
また2007年の法律改正により、振替休日のルールが若干複雑になっています。

また、春分・秋分の日については法令としては前年になるまで確定しませんが、天文学的な春分日・秋分日と違う日になることはまず無いと推測できるので、計算により導いてみます。

以下は春分と秋分日の近似計算です。西暦1851年~2150年の間で利用できます。

//春分(3月)
int GetVernalEquinoxDay()
{

	int y = m_Systime.wYear;
	int  d;
	if(y<1851) return -1;
	else if(y < 1900){
		d = (int)(19.8277 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
	}else if(y < 1980){
		d = (int)(20.8357 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
	}else if(y < 2100){
		d = (int)(20.8431 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
	}else if(y < 2151){
		d = (int)(21.8510 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
	}else return -1;
	return d;
}

//秋分(9月)
int GetAutumnalEquinoxDay()
{

	int y = m_Systime.wYear;
	int  d;
	if(y<1851) return -1;
	else if(y < 1900){
		d = (int)(22.2588 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
	}else if(y < 1980){
		d = (int)(23.2588 + 0.242194 * (double)(y-1980) - ((y-1983)/4));
	}else if(y < 2100){
		d = (int)(23.2488 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
	}else if(y < 2151){
		d = (int)(24.2488 + 0.242194 * (double)(y-1980) - ((y-1980)/4));
	}else return -1;
	return d;
}

最後に祝日です。 現在と2007年の改定前の祝日を拾うようにしてみました。 これに加えて、振替休日を考慮する必要があります。 2007より前は日曜日に重なった場合は月曜日を休日に、 2007年以降は「その日後においてその日に最も近い「国民の祝日」でない日」が休日です。


int c = (d-1) / 7 + 1;
if(m==9)
	autumnalEquinoxDay =GetAutumnalEquinoxDay();
if(m==3)
	vernalEquinoxDay = GetVernalEquinoxDay();
if(m==1 && d==1){
	return DAY_NEWYEARSDAY;
}else if((y >= 1949 && y < 2000) &&  m==1 && d==15){
	//1949-1999 1月、15日
	return DAY_SEIJINNOHI;
}else if((y >= 2000) &&  m==1 && w==1 && c == 2){
	//2000~、1月、月曜日、第2
	return DAY_SEIJINNOHI;
}else if(y>= 1967 && m==2 && d==11){
	//1967~、2月、11日
	return DAY_KENKOKUKINENBI;
}else if(y>= 1949 && y<1989 && m==4 && d==29){
	//1949~1988、4月、29日
	return DAY_TENNOUTANJOBI;
}else if(y>=1989 && m==4 && d==29){
	if(y>=2007) return DAY_SHOWANOHI;
	//1989~、4月、29日
	return DAY_MIDORINOHI;
}else if(y>=1949 && m==5 && d==3){
	//1949~、5月、3日
	return DAY_KENPOUKINENBI;
}else if(y>=1986 && m==5 && d==4){
	if(y>=2007) return DAY_MIDORINOHI;
	//1986~、5月、4日
	return DAY_KOKUMINNOKYUJITU5;
}else if(y>=1949 && m==5 && d==5){
	//1949~、5月、5日
	return DAY_KODOMONOHI;
}else if(y>=1996  && y<2003  && m==7 && d==20){
	//1949~2002、7月、20日
	return DAY_UMINOHI;
}else if(y>=2003 && m==7 && w==1 &&c==3){
	//2003~、7月、月曜、第3
	return DAY_UMINOHI;
}else if(y>=1966  && y<2003  && m==9 && d==15){
	//1966~2002、9月、15日
	return DAY_KEIROUNOHI;
}else if(y>=2003 && m==9 && w==1 &&c==3){
	//2003~、9月、月曜、第3
	return DAY_KEIROUNOHI;
}else if(y>=1966  && y<2003  && m==10 && d==10){
	//1966~2002、10月、10日
	return DAY_TAIKUNOHI;
}else if(y>=2003 && m==10 && w==1 &&c==2){
	//2003~、10月、月曜、第2
	return DAY_TAIKUNOHI;
}else if(y>=1948 && m==11 && d==3){
	//1948~、11月、3日
	return DAY_BUNKANOHI;
}else if(y>=1948 && m==11 && d==23){
	//1948~、11月、23日
	return DAY_KINROUKANSYANOHI;
}else if(y>=1989 && m==12 && d==23){
	//1989~、11月、23日
	return DAY_TENNOUTANJOBI2;
}else if(y>=2003 && m==9 && GetNumOfWeek(d-1)==3 && w-1 == 1 
	&& (d+1)==m_AutumnalEquinoxDay){
	//2003~、9月、前日が第3月曜日、翌日が秋分の日
	return DAY_KOKUMINNOKYUJITU9;
}else if(m==3 && d==m_VernalEquinoxDay){
	//春分
	return DAY_SYUNBUNNOHI;
}else if(m==9 && d==autumnalEquinoxDay){
	//秋分
	return DAY_SYUUBUNNOHI;
}

accelerometer:didAccelerate:がDeprecatedになっている

加速度センサを使うアプリを新たに作っています。
ふとドキュメントを見たら、accelerometer:didAccelerate:が、(Deprecated in iOS 5.0.)になっていました。

代替は手段はどうするんだろうって悩んだのでメモ。

    motionManager_ = [[CMMotionManager alloc] init];
    motionManager_.accelerometerUpdateInterval = 1.0/60.0;

    NSOperationQueue *currentQueue = [NSOperationQueue currentQueue];
    accelerationValueFirst_ = YES;

    [motionManager_ startAccelerometerUpdatesToQueue:currentQueue
            withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
    {
        CMAcceleration acceleration = accelerometerData.acceleration;

        UIAccelerationValue x = acceleration.x;
        UIAccelerationValue y = acceleration.y;
        UIAccelerationValue z = acceleration.z;
        //お好きな処理
	}

ブロックを使う方法が推奨されているようです。
・・・と思いきやbeginAnimations:context:はDeprecatedになっていませんね。

CMMotionManagerはiOS4.0から利用できるようです。

どこでもドア

夢の道具に文句つけても仕方ないのだけれど、「どこでもドアがあったらなぁ」と想像して楽しむときに、どうしても「こういう場合どうなるんだ?」と疑問になってしまう。

一番最初に気づく問題は「気圧差」。
ドアを開けた先の世界とは気圧差があり、ドアを開けた瞬間突風で吹き飛ばされるのでは? というもの。
ドアには見えないバリアみたいなのがあって、気圧差は保ったまま人間だけが通過できる、と解決案を示せないことはないが、それはそれで、あらゆる物理量の微分値が無限大になるような境界面が存在するのか、それとも緩やかに変化させる緩衝帯があるのか、いろいろと新たな疑問点がわいてくる。未来の科学でうまいこと調整しているのだろうか。

もう少し想像してみると、「位置エネルギー」が心配になってくる。
質量・エネルギー量保存の法則はおそらく宇宙の大原則で覆らない。
高い位置と低い位置をどこでもドアで繋いだら永久機関が出来てしまう。
この問題はエネルギーの増減をどこでもドア側で吸収するような仕組みがあると考えるのが妥当だろう。
どんなエネルギー源で動作しているのか不明だが、低い位置から高い位置にどこでもドアを通じて物質が移動したとき、どこでもドアは何かしらのエネルギー(電気とか)を多く消費する。
位置エネルギーが問題になるならば、重力や電界や磁界のエネルギー差も当然あるわけだが、これも同様にどこでもドアが調整する。

このような事からドアがエネルギーを消費することがわかる。
どこでもドアを通過している途中にエネルギー切れ(電池切れ)等が発生した場合、どのような安全対策が施されているのかについても興味が尽きない。

もう一つ心配なのが、地上で使う限り、どこでもドア自体が常に移動していることである。
相対性理論によると、絶対的静止系は存在しない。よってどこでもドアが移動しているかどうかは特に関係ないのだが、ドアを開けた先と現在地に相対速度差がある場合は話が別である。さらに、地上に置かれた物は、重力と遠心力、地表からの反力が釣り合った状態で円運動をしている。つねに複雑な相対速度差がどこでもドアのこちら側とあちら側には存在する。
相対速度差があるということは時間の流れに差があるということだ。
例えば、ドアのあちら側とこちら側で原子の振動数が見かけ上、変わる。
人間などが通過するとき、その体を構成する原子が、原子や分子としての構造を保ったままどうやって通過しているのか気になるところである。
ここもSF的発想が必要だ。例えば質量を無効にする装置が搭載されているとか、別次元の平面宇宙のようなものを通過するだとか。

いろいろ考えてみたが、おそらく他にもある。
どこでもドアを実現するには、工学的問題の前に机上で解決しなければならないパラドックスが多数存在する。

カレンダー

2024年5月
 12345
6789101112
13141516171819
20212223242526
2728293031  

▲Pagetop