Core Data でデータを削除する方法が変わったんですね、Xcode 9

Core Data でデータを削除する時のやり方ですが、今までは for 文の中で deleteObject みたいな形で実装していたのですが、persistentContainer を使うようになってから、同じやり方をしてもダメだと、削除されないと、下位互換は無視すると。エラーにもならず、削除もされないので、ホント困ります。

色々調べたところ、いつの頃からか、NSbatchDeleteRequest という Class が新設されていて、executeRequest で指定することで削除することになったみたいです。

って、分かってしまえば簡単ですが NSBatchDeleteRequest の代わりに、NSFetchRequst を指定してしまいうまく動かない、withContext に self.managedeObject を指定していまいうまく動かないなど、幾多の困難を克服し、ようやく削除できるようになりました。

Core Data は鬼門というか、ほんとわかりにくいです。以前、Core Data に focus した書籍を買ったんですが、今となっては古い知識でアップデートしないとダメですね、ってか、下位互換というか、せめて、Xcode で、その表現古いからアップデートしなよとか suggestion して欲しいところなんですが・・・

Macbook 12 インチの電池交換

電池交換と出るようになってしまい、実際 3h ぐらいしか使えなくてとても不便を感じるので、電池交換を決意。

Apple ストアに予約を取ったら、なんと一週間後しか取れない。銀座が近いので、仕事帰りに持っていったら交換ですねと。修理期間のご案内は 1 週間とご案内していますが、統計を見ると 3 日程度とのことで、えーそんなにかかるのですか、と言いいましたがやむを得ないなと。木曜日に預けて日曜日の午前中に到着。早いね、これ。土日も稼働している感じなんでしょうか。

修理内容見たら、ボトムケースまるごと交換するんだね。すごいね。

 

Master Detail テンプレートの調整:その3

さらに iPad で動作検証を進めていると、iPad では初期表示が detail view であることが判明。これわかりにくいので、初期表示は master にしたいところなのですが、iPad は画面が広いので split view で表示することになり、メールソフトのように、分割して表示するのが流儀のように思い、やり方を調べるもよくわからない。

苦心惨憺の末、self.splitViewController.preferredDisplayMode という property があることが判明。MasterViewController.m の awakeFromNib method で、この property に値をセットすると、master が表示される。

property の値は、以下の 3 つ:

UISplitViewControllerDisplayModeAutomatic

UISplitViewControllerDisplayModePrimaryOverlay

UISplitViewControllerDisplayModeAllVisible

default 値は automatic になっている。値の効能は変数名の通りで、modal primary over lay なら、重なって表示される。all visible ならいい感じで分割されて表示される。今回は、all visible に設定。

って、分かってしまえばなんてことは無いのだけれど、分かるまでが大変で・・・ホント調べるの疲れてきたけれども、ようやくゴールに近づいた感じも。

Master Detail テンプレートの調整:その2

Master Detail テンプレートの調整が済んだと思いきや、データを削除した際の挙動がおかしいことに気づいてしまった。

具体的には、iPad など、split view 表示されてしまう場合に、Master でデータを削除すると detail に表示していたレコードはなくなっているので、状態に応じたレコードを表示しなければ辻褄が合わなくなる。テンプレートのままではこういった自体を想定していないのか、消したレコードがそのまま表示されるている。

データは消えているのに情報が表示されているわけで、アプリ利用者としては??感が強いだろうし、消したのに back ボタンでまた保存が走るのも製作者としては回避したいところ。

どうしたものかと source をいじっていたら、Master の実装ファイルに以下の method を発見。データを削除したら実行される。

- (void)tableView:(UITableView *)tableView

commitEditingStyle:(UITableViewCellEditingStyle)editingStyle

forRowAtIndexPath:(NSIndexPath *)indexPath

この method 内に何か工夫を凝らすことで、レコードを削除した場合の挙動を実装できないか。色々調べたところ、画面が今 split view 表示かどうかは property で調べられることが判明。

self.splitViewController.isCollapsed

これで true が返ってくれば split view されていないことを意味する。false なら split view の状態。

split view されているかどうか判別が付くようになったものの、削除されたためレコードはないのだが、detail に何を表示するべきか。既に実装されている method を呼ぶのが省力化に繋がるだろうとの考えから、segue を呼んでみた。

            [self performSegueWithIdentifier:@"showDetail" sender:self];

うまくいったようで、detailItem が nil の時の挙動が実現された。

っって、分かってしまえばどうってことないのだが、分かるまでが大変なもので・・・

Master Detail テンプレートの調整

Auto Layout の調整もひと段落して、さて、動作検証でもしましょうかと iPad の simlator を立ち上げたら、iPad では勝手に splitView で表示されるのですね。そういえば、Main.storyboard でも、一番はじめのが UISplitViewController なので、なんか新しくなったなぁぐらいにしか考えていなかったんですが、表示のされかたが異なるのは知らなかった。

せっかくなので iPad 対応しておくかといじってみたら、いきなりエラー。原因は、iPhone とは異なり iPad でははじめに表示される画面が detail なので、データが何もない状態で一覧を表示しようとすると detailItem が nil なので保存できずエラーとなっている。関連して、detail を表示した時、viewDidLoad が呼ばれないので configureView も呼ばれず、textView の例文そのまんま表示される(Lorem ipsum... みたいなやつ)、ボタン押し放題など、なんとも厄介な状況に。ようやく、解決方法がわかったらので後学のために書いておこうと思います。

まず、エラーの根本原因は MetailViewController に記載の、viewWillDisappear で毎回 save をかけていましたが、detailItem が nil の時は save しないようにしました。これでエラーは出なくなったけれども、ここがわかるまでが一苦労。

次に、初回表示の際、データがないのでボタンとかはいじって欲しくない。これは、awakeFromNib method に、以下の記載をすることで解決。

    self.view.userInteractionEnabled = NO;

通常、Master から detail に遷移した際は viewDidLoad method が呼ばれるので、ここでは YES を設定しておけばよい。

また、navigationItem.title が、なぜか Master となってしまうので、これは MasterViewController の awakeFromNib method でタイトルを指定してやることに。

ちなみに、textView の例文まで表示されてしまうのは、Main.storyboard に配置した textView の inspector で、例文が入っているのでカットすることで解決。

何度も言いますが、原因が分かれば直しようもあるのですが、原因がわかるまでが大変なもので、今回のも解決までに 3 日ぐらいかかりましたね。ふぅぅぅ。

App を提出したら却下されたので、新しい build を iTunesConnect に提出

App を提出したら却下。理由は、多様なデバイスに対応する必要があります、ついては、Developer conference の Auto Layout のビデオでも見て習得してください、とのメールが・・・

ビデオ見て学習しましたが、正直サッパリでした。ので、『よくわかる Auto Layout』購入して、みっちり学習しました、身につきました。でも、それを前後して、Xcode のバグのせいで、Main.storyboard が逝ってしまい、再度、作り直すハメに・・・layout 調整が必要だったのでいい勉強になりますよ、method の組み方も思い出しながらやったら復習になってよかったですと言い聞かせながら・・・

その後ようやく仕上がり、さて、App の実機テストでもするかと思い、どうやるのだ?とつまずきました。理由は、Xcode で新たに Project を作っていたからで、Project 名とか変えているので、iTunesConnect に登録する方法がよくわからなかったのですね。また、iTunesConnect で見ると、却下のままになっているので果たしてここに新しい build を登録できるのか疑問だったんですが、結論を言うと大して苦労なく新しい build を登録できました。

provisioning profile とかを新たに登録し、bundle identifier を前と同じにすれば、Project を新規に登録していても別に問題なく、新しい build 番号をつけて、Archive してアップロードできました。その後、iPhone の Test Flight でもダウンロードできましたので、さあ、明日は実機でテストしてみるか。

 

第二回御前山トレイルラン大会に参加

去年出ようかなと思ったけど、無料バスは水戸駅 7 時集合で一番早い時間でも 7 時に着けないため断念。今年は車で行くことにして、キャンプ場で後泊することに。朝0530 に起きて 6 時前に出発。結局 0730 頃現地に到着。道の駅隣の駐車場はほぼ満車。エントリーを済ませて参加賞がすごい。大きな梨 3 個。これはうまそうだ。参加賞は T シャツよりもこういうものの方がいいね。

9 時に開会式で 0930 号砲。コースは、いわゆる山道は多くなく、半分ぐらいがアスファルト。走れないほどの急な登りは少なく、大体走ることができました。と言っても、足へのダメージは確実にきて、最後の御前山からのくだりはほとんど歩いてしまった。3 時間 20 分ぐらいでゴール。順位もちょうど半分ぐらいだろうか。練習の時、27 Km 走をもっかいやっておいた方がよかったなぁ。距離表示が少ないので、もっとあるといいかも。

ゴール後は、青少年旅行村に宿泊。結構古い建物で、暖房がないのでとても寒い。来年泊まるとしたら、ストーブ借りることにしよう。