info.plist と NSUserDefaults

アプリ内のちょっとしたデータを保存するのに、CoreData に保存するほどでもないんだよなーということがあって、具体的には、観察地を入力する時のデフォルト地点を、前回の場所にしておきたかったんですね、毎回場所を変えてバードウオッチングする人は稀で、普段はホームグラウンドとしている地点を探鳥し、たまに遠征するだろう、自分みたいにと思って。

そんな時、NSUserDefault を使うとすごく便利なんですが、info.plist に思い違いをしていて、軽くハマりました。値の取り出しまではすんなり、というか、久しぶりだったので、こんなにめんどくさかったんだと思いながら作っていましたが、さて、値を更新しようとして、やり方がさっぱりわからず・・・それもそのはずで、初期値の設定は手動で、読み出しのみというのが info.plist の役割なので、更新できたら逆に困るというもの。

以前買った古い本を引っ張り出してきて、あ、NSUserDefault だったとようやく気付いた次第です。

info.plist ですが、使いにくいことの一つに、値を取り出す時に指定する key が見えているまんまなのか、接頭語を付けるのかわからない点があります。

Xcode で、info.plist を選んで、右クリックすると、コンテキストメニューには Show Raw Key/Value というメニューが見えるので、それを選ぶとプログラミング時に指定する実際の key が見えます。大抵、頭に CFBundle などの文字を付けてやることになりますが、知らないと、指定がうまくいかずハマりが深くなるので、知っていると便利ですね。

なお、info.plist に開発者が key を追加した場合、プログラムで指定する key は接頭語を必要とせず、マンマで大丈夫です。でも、付けようとする名前が予約されていると混乱の元になりますから、my とか、oreore とか、何らかの自分を主張する接頭語を自身でつけてやるのが良いんでしょうね。

 

 

CloudKit Storage

アプリ利用者のデータを統合すると集合知的な利用方法ができる。

今構築中の野鳥観察記録(Field Note)では、例えば有名な探鳥地に行くとして、遭遇できるであろう野鳥の種別とその期待値を出したり、日本各地における渡り鳥の初認日から、自宅周辺での初認日を予想したりと、ふだんの bird watching life が充実すること間違いない。

アプリ利用者のデータを集めるにはどうすればいいのかよく分からなかったで、mobile backend とかを色々調べたりしていたのだけれど、結局どれが生き残るかよく分からない混沌とした状況で、決め手にかけるなぁというのが正直なところ。

そんな中、CloudKit Storage というのが、Apple 謹製であったので、びっくりこきました、ってか、知ってる人からすると、そんなことも知らないの、ぷっっ 状態。

ちょっと色々調べてみることにしよう。

CoreData relations は valueForKey でも指定できる

CoreData で many to many を指定。あるレコードに関連づけられた N のレコード数は一体どうやって取り出すのだ?と疑問が生じました。一覧の画面で、detail に登録した野鳥の数だけ表示したいと思ったんです。

ダメ元で、relations で規定した文字を指定してみました。

    NSMutableArray* many_records = [object valueForKey:@"toWildBird"];

    cell.numberOfObserve.text = [NSString stringWithFormat:@"Wild Bird (s): %ld", [many_records count]];

 

なんのエラーにもならず、ちゃんと動くのですね。

分かってくると、やっぱり CoreData は便利だなと実感しました。

CoreData many to many における、many の検索

CoreData を使い、野鳥観察記録帳のデータを管理。観察記録テーブルと野鳥一覧を many to many で連結。RDB の場合、

(1) 野鳥観察記録ー(N )観察した野鳥ー(1) 野鳥一覧

のように、テーブルを定義しますが、CoreData では many to many という指定ができるので、トランザクションテーブルである、観察した野鳥は作らなくていよい。あー便利・便利。

と、ここまでは良かったんだけど、野鳥観察記録一覧から、観察した野鳥の名前で検索するにはどうすればよいのか。つまり、あの珍しいジョウビを観察したのはどこだっけ?となってしまった場合、「ジョウビ」と入力したら、ジョウビタキが観察された記録を探して欲しいということ。

いろいろ調べたところ、SUBQUERY と ANY という指定ができるようで、

        NSPredicate* predicate =

         [NSPredicate predicateWithFormat:

          @"location CONTAINS[c] %@ OR (ANY toWildBird.jname CONTAINS[c] %@)",

          incSearchText, incSearchText];

 

こんな書き方が可能。ANY で指定している、toWildBird.jname 部分は、Relationship で定義した名前と N 側のフィールド名になる。Relationship 名の代わりにテーブルの名前にしてしまうとエラー発生(key path error)なので、すぐわかる。

many to many の指定は、RDB に慣れているとそんな指定はできないので初めよく分からなかったんだけど、追加、削除、検索がすごく簡単にできるので、理解できると、とても便利ですね。

 

フォアフット

フォアフットで走ると速く走れる(らしい)と聞いて、実践中。

初めは全然できなかったのだけど、階段を降りる時のように、着地する側の骨盤を下げ、逆に言うと、軸足の骨盤を上げることで着地しやすくなった。

問題はふくらはぎで、初めは疲労感と痛みで 10Km 走れず、体に悪いのではないかと思えたほどですが、3 ヶ月ぐらいでようやく 25Km ぐらいは走れるようになった。未だに、疲労するけど。

フォアフットの利点は未だによく分からない。明らかに違うのが、太ももの前面が全然痛くならないのと、明らかに太ももの裏側の筋肉を使って走っている。そのせいで、今までと比較すると、疲労感は少なく感じる。本などによく書いてある太ももの裏の筋肉を使った走りはどうやるのか疑問だったのだけど、こういうことかと、ようやくわかった。ま、ふくらはぎ疲労とのトレードオフなんだけれども・・・

太ももの前面とふくらはぎの疲労を比較すると、ふくらはぎの方が回復が早い気がするので、それはいいかも。

膝が痛くならないというのもよく見かけるのだけれど、初めから痛くなかったんでここはどうってことがないのだけれど、走った後に膝使ったなぁという感じは確かにしない。

今よく分からないのが、スピードを上げてフォアフットすると以前よりもかなりぎこちない感じ。短距離の走りならフォアフットでできるのだけれど、長距離のスピード走の時のフォームがしっくりこないし、実際速く走れていない感じがする。

また練習してみよう。

 

CoreData relationship, Many-To-Many (N 対 N)について

CoreData を使うと、One-To-Many (1 対 N)や Many-To-Many(N 対 N)を形容できるということで、いろいろ試してみた。

私はもともと RDB を扱っていたので、Many-To-Many の概念がよく分からない。RDB の場合、1 : N : 1 のようにすれば良いわけで、Many-To-Many はなんでそんなことすんのか、することのメリットはなんなのかがよく分からなかったのです。

結論からすると、Many-To-Many は使える。RDB では、1 : N : 1 の形は、1 をマスター、N をトランザクションと呼んでいる。Many-To-Many ではトランザクション系テーブルを作らなくてもよく、トランザクション系のテーブルはプログラマが明示しなくても CoreData が自動で作ってくれる。

さらに、今日のテストでわかったことは、Relationship は重複したレコードを自動で排除してくれる。理由は、Relationship は NSSet で定義されており、NSSet は元々要素の重複を許さない型だからだ。

このような仕組みが採られることが理解できるようになると、プログラムがずいぶん楽になる。以前、RDBトランザクション系のテーブルにレコードを追加する時、重複がないように追加する前にチェックしていたけれども、その必要はない。

コツのようなものはあり、重複しないようにするには、マスターのレコードをポインタで渡すこと。そうしないと、重複の判定がかからないので、いくらでも追加できてしまい、便利な機能を享受できない。

概念はこれぐらいで、今度具体的な方法を記載しよう・・・

 

R1 フーディとキャプリーンサーマルジップネックフーディの違い

冬のジョギングは寒いので、ウインドブレーカーの中に着るのにいいのはないものかと探していたところ、patagonia のキャプリーン 3 (以前はこう呼んでいたはず、いつのまにかキャプリーン4、サーマルと名称が変わった気がする・・・)が良さそうとのことで、数年前に購入。とても具合が良く、走り始めは寒くないし、走り出して暑かったらジッパーを開けて風通しをよくできるので愛用しています。

土日は連続してジョグするのですが、洗濯して乾かないときに、さてどうしたものかと、もう一着買おうかなと調べていたら、同じく patagonia で R1 というのがあり、評判がすごく良い。キャプリーンと形も素材もよく似ているのだけど、さあ、どちらを買おうか悩んだ末に、R1 を購入。

キャプリーンと R1 の違いは、キャプリーンの方が風を通しやすい素材で、内側のキャラメルブロックの目が荒い。どうせウインドブレーカーを上に羽織るので、風通しは実はどっちでも良い。汗の吸収と発散はキャプリーンの方が上。

あと、R1 を一番上に着て外出はありそうでも、キャプリーンを一番上で外出はないかなと。なんでかというと、下着っぽいので。実はどちらも自分的にはないことなんだけど書くだけ書きました。

どちらもフーディを買ってしまいましたが、ジップネックの方が、普段着として寒い日のインナーにできて使い勝手が良い気がしますが、いつもセールで買うので選択肢が限られてしまうのが難点かと。

ちなみにサイズですが、183cm, 67Kg ですが、どちらも M サイズでぴったりです。丈は十分ですね。

特徴がわかったところで、また数年後になろうかと思いますが、在庫が潤沢なうちに買うことにしよう。さて、今回買った R1 は何年着ることになるのやら・・・