Study CoreData 14 ~目に見えるしあわせ~

 
みなさん、こんばんわ〜。

いきなりですが、今日は前置きにちょっとした
『開発に使えるツール』を紹介したいと思います。
 
 
紹介するのは『Developer Color Picker』というフリーのプラグインです。

どんなツールかと言うと、Mac標準のカラーパネルに追加されるプラグインで
画像などからピックアップした色をそのままコードに変換してくれるという素晴らしいツールです!!
※UIColor, CGColorRef, NSColorに加え、HTML, CSSにも対応。
 

 

ちなみに僕はこんな感じで使ってます。

1. Xcodeから[⌘+T]でフォントパネルを開き、そこからカラーパネルを開き
“Developer Color Picker”を選択。
2. Previewなどで画像を開いておき、カラーパネルの虫眼鏡を使って画像内の色をピックアップ。
3. それを[Copy]してコードにペースト。
 
 
ね?
かなり便利そうでしょ?

興味のある方はこちらをどうぞ。
[ダウンロード先]  Developer Color Picker
[レビュー:使い方] Developer Color Picker – カラーパネルにRGBやWebカラーのコードを取得・コピーできるピッカーを追加 – 気分が良くて何が悪い?
 
 
以上、お気に入りツールの紹介でした。
それでは、本題へ参りましょう!

注意:投稿者自身もCoraDataについて勉強中のため、このシリーズには誤りが含まれている可能性があります。もし、間違いに気付かれた方はコメント欄もしくはtwitterなどでご指摘いただけると幸いです<(_ _)>
また、開発環境はXcode3.2.3 iPhone SDK 4です。実機でのテストなどは自己責任でお願いいたします。

 
 

1. もっと効率よく

前回はDetailViewControllerでのセルの表示までやったので、
今回はセルの選択時の処理[didSelectRowAtIndexPath:]から始めていきたいと思います。
 
 
『TodoCore』ではこんな感じにしてましたね。

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

	if (indexPath.row != 3) {
		
		EditableViewController *editViewController = [[EditableViewController alloc] 
													  initWithEditType:indexPath.row 
													  editableObject:self.managedObject];
		editViewController.delegate = self.delegate;
		editViewController.title = @"Edit Task";
		
		[self.navigationController pushViewController:editViewController animated:YES];
		[editViewController release];
	}
	else {
		[[tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:NO];
	}
}

 
ここで、あらためて今回の画面遷移について考えてみましょう。

 
もうお分かりのように、
遷移先は[EditValueController]のふたつのサブクラスのどちらかになりますね。

で、その際に
DetailViewから渡す[Task]オブジェクトから値を取り出して表示するには
Keyデフォルト値が必要ですね。
それと、遷移先がEditableViewController(画像左)の場合にはセルのタイトル
(@”Title:”など)も。

けど、これってすべて例の[ConvenientArrays]でセットしているものと同じ
それをまた次のコントローラでも取得するってのはもったいないと思いません?
 
 
…ってワケで、せっかくですので
ここでも例の便利Arrayから次のコントローラでも使うオブジェクトを取り出して渡しちゃいましょう!

ただ、全部のオブジェクト用にプロパティを用意するのもアレなので、今回はNSDictionaryを使うことにしました。

そのためにまず、[EditValueController]をいじります。

 
ここでは、[_controllerInfo]というDictinaryプロパティを宣言して
ついでにこの辞書から取り出すのに使うKeyをdefineで設定してます。
(実装ファイルでのsythesizeもお忘れなく!)
 
あと[dealloc]も。

- (void)dealloc {
	
	self.delegate = nil;
	self.editingTask = nil;
	self.textField = nil;	
	self.controllerInfo = nil;
	
    [super dealloc];
}

 
ここまで出来ればDetailViewの[didSelectedRowAtIndexPath:]の実装ができますね。

 
簡単に説明をば。

まず、選択されたセルのセクション番号が0以外の場合は、
選択状態を解除してこのメソッドを抜けます。

0の場合には以下の処理へ。

どちらの編集用コントローラに移動するのかを決めるために、
まずNSStringにクラス名を入れます。
そしてそのクラス名に[Class NSClassFromString(NSString *aClassName);]という関数を使う事で、文字列をクラス型に変換します。

変換された[class]オブジェクトを使って遷移先のコントローラ初期化します。

コントローラの[title]は[_titles]から取り出します。
“controllerInfo”には、各便利Arrayから取り出したオブジェクトと多応するKeyを入れておきます。

最後に[pushViewController]して完了!

これで、編集用ビュー側でもそのままオブジェクトを流用できるようになりました!
 
 

2. 私もいるんですけど…

意味ありげなタイトルですが^^;
もうひとつ変更しとかなきゃいけないトコがありますね。

忘れちゃかわいそ〜ですよっ。
RootViewControllerの[showModalAddTitleView]です。

 
それと、ついでに[addButton]のアクションセレクタも[showModalAddTitleView]に変更しておきましょう。
 
さ、これでOKですねっ!
次行きます。
 

3. コピペ

これから取りかかるのは[EditableViewController]になります、
まず、[dueDate]編集用にUIDatePickerのインスタンス変数宣言を追加しておいてください。

インスタンス変数名は“_datePicker”です。
 
 
で、セクション関係はTodoCoreと一緒でOKですね。

#pragma mark -
#pragma mark Table view data source

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
	return 80.f;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	return @" ";
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

※[numberOfSectionsInTableView:]は親クラスで実装してあるので削除します。
 
あとセクションフッターも。

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
	return 75.f;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
	
	UIView *footerView = [UIView new];
	footerView.frame = CGRectMake(10.f, 0.f, 300.f, [self tableView:tableView heightForFooterInSection:section]);
	
	UIButton *moreButton = [UIButton buttonWithType:102];
	moreButton.tag = TAG_SUB_BUTTON;
	[moreButton addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
	[footerView addSubview:moreButton];
	
	if (self.isFirstEdited == YES)
		[moreButton setTitle:@"Add Details" forState:UIControlStateNormal];
	else
		[moreButton setTitle:@"Save & Show List" forState:UIControlStateNormal];
	
	moreButton.center = CGPointMake(310.f - moreButton.bounds.size.width / 2, 
									10.f + moreButton.bounds.size.height / 2);
	
	
	return [footerView autorelease];
}

※moreButtonのアクションはまだ用意していないのでnilにしてあります。
 
続けて[loadView]をオーバーライドして、
ボタン類とDatePickerの表示とかを設定します。

- (void)loadView {
	[super loadView];
	
	// ナビゲーションバーにボタンを追加
	UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] 
									 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
									 target:self action:nil];
	cancelButton.tag = TAG_CANCEL;
	self.navigationItem.leftBarButtonItem = [cancelButton autorelease];
	
	UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] 
								   initWithBarButtonSystemItem:UIBarButtonSystemItemSave 
								   target:self action:nil];
	saveButton.tag = TAG_SAVE;
	self.navigationItem.rightBarButtonItem = [saveButton autorelease];
	
	if (_editType == EditTypeDueDate) {
		_datePicker = [[UIDatePicker alloc] init];
		[_datePicker addTarget:self action:nil forControlEvents:UIControlEventValueChanged];
		_datePicker.minuteInterval = 30;
		_datePicker.minimumDate = [NSDate date];
		_datePicker.datePickerMode = UIDatePickerModeDateAndTime;
		[_datePicker setLocale:[NSLocale currentLocale]];
		[_datePicker setDate:[NSDate date] animated:NO];
		self.tableView.tableFooterView = _datePicker;
		[_datePicker release];
	}
	
	[self.tableView setAllowsSelection:NO];
	self.tableView.scrollEnabled = NO;	// テーブルビューのスクロールを不可に。
}

※ここでも_datePickerのアクションはnilにしてます。
 
…と、こんな感じで一気にコードを直接載せましたが、この辺りは過去の説明とかぶるトコロだったり、CoreDataには関係なかったりするので。
(別に手抜きではありませんよ(^〜^;))
 
 

4. セルの構成

それでは、セルの構成に入りたいのですが、スミマセン…
その前に、EditValueController.mでインポートしていた”Task.h”をヘッダファイルでのインポートに変更しておいてください。
※ヘッダでインポートしとかないとサブクラスの方で反映されないみたいです
 
 
それでは、お待たせしました!
やっとこさ、EditableViewControllerの[configureCell: atIndexPath:]の実装です。

こんな感じにしてみてくださいね。

・ textLabelには、”_controllerInfo”から取り出した[valueTitle]を表示。

・ _textFieldがなければ…
  1. textFieldを作りcontentViewへadd。
   (frameはCGRectMake(80.f, 10.f, 220.f, 24.f) その他delegateなども設定)
  2. defaultValueを取り出す。
  3. valueString(値を文字列化したもの)を取り出す。
  4. プレースフォルダにはdefaultValueを。
  5. valueStringがdefaultValueと同じでなければ、textFieldに表示。
  6. [dueDate]編集時にはtextFieldをタップ不可に。
  7. [title]編集時にはキーボードを表示

 
 
どうです?
僕はこんな感じにしてみました。

 
 
一応、補足を。

textFieldのリターンキーのタイプは”Done”にしました。
clearButtonModeってのはフィールドに表示される×ボタンですね。
編集中だけ表示させます。

あと、textFieldのタップはキーボードが表示可になっている時だけってコトで
_textField.userInteractionEnabled = _editingInfo.showKeybord;
にしてます。
キーボードの表示(becomeFirstResponder)も同様です。
 
 
そこまで出来たら、そろそろビルドして確認したいですよね。
なので、とりあえず『新規Taskの作成』だけでも出来るようにしましょうか。
 

5. ビルドに向けて

表示確認用のビルドに向けて
まずはSave/Cancelボタンが押された時に呼び出されるメソッドを。

このメソッドでやる事は、『TodoCore』の時とそんなに違わないと思いますが
ただTodoの場合、タイトルが“No Title”なんて事はありえないですよね。
なので、もしテキストフィールドに文字列が入れられなかった場合はアラートを表示させることにします。

…で、[_editingTask]に値を入れたら
デリゲートメソッドに送って、dismissModalViewする。

簡単ですね。

メソッド名は[judgeButtonTapped:]にしました。
あと、各ボタンのアクションメソッドも入れておきます。

ここで注意しておく事は
アラートを出した後すぐに[return;]でメソッドを抜けるようにする。
って事くらいですかね。
これをしておかないと、その後に書いたコードも実行されてしまうので。
 
 
で、AlertView上のボタンのアクションを設定しておきましょう。
そのためにまず、親クラスであるEditValueControllerのヘッダファイルにデリゲートを追加しておきます。

@interface EditValueController : UITableViewController
<UITextFieldDelegate, UIAlertViewDelegate> {

ボタン押下時の処理はこんな感じ。

// アラート処理
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
	
	if (buttonIndex == alertView.cancelButtonIndex) {
		if ([_textField canResignFirstResponder])
			[_textField resignFirstResponder];
		
		[self judgeButtonTapped:nil];
	}
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
	textField.tag = TAG_SAVE;
	[self judgeButtonTapped:textField];
	return YES;
}

※ついでにキーボードのリターンボタンのアクションも設定しました。
 
キャンセルボタンが押されたら、
テキストフィールドのフォーカスを外して、元のメソッドに返してます。
この時に引数を[nil]にする事で
ナビバーのCancelボタンが押された時と同じように処理される事になります。

リターンキーが押された時にも[judgeButtonTapped:]を送ります。
送る前にテキストフィールドのtagを“TAG_SAVE”にしているので
こちらはSaveボタンが押された時と同じ処理になります。
 
 
それじゃ、早速ビルド…
…といきたいところですが、実はまだRootViewの準備ができていません…(>o<;)

なので、そちらを先に…<(_ _;)>
 
 

6. もうすぐビルドできそう!

RootViewController.mを開いたら、まずテーブルビューの表示から仕上げていきましょう。

セクションの数とセクションの行数は自動生成されてますが、
まだ、セクションタイトルを返していませんでした。
それと、今回使っているカスタムセルはデフォルトの高さだとうまいこと表示されないので、セルの高さも変えておきましょう。

※cellStyleを変更し忘れていたので、subTitleに変更してます<(_ _;)>

 
 
もうちょっとですかねぇ〜。
念のため追加ボタンのアクションである“showModalAddTitleView”も確認しときましょうか。
 
 
あっっっっっ!!

[_addTitleViewController]のデリゲート設定してないぢゃないですかぁ!

そうでしたね。
初めにこのメソッドを用意した時はまだ
EditValueControllerDelegateを実装する前でしたからね。

ってコトで、初期化後のところで
_addTitleViewController.delegate = self;
しといてください。
 
 
次に、自動生成された初期状態からまだ手を付けていなかった部分を。

まず、[viewDidLoad]ですがこのメソッドはそもそも
『xibファイルが読み込まれた後に呼ばれるメソッド』なので、
IBを使わない場合は基本的に[loadView]を使う方が良いようです。
(TodoCoreではそのまま使ってましたが…^^;)

なので、これを変更してついでに[self.title]も入れてボタンアクションを変更。
あと[viewWillAppear:]も。

こんな感じでOKかと。

あとは[didEditProvisinalTask: saveType:]も確認しておきましょうね。

大丈夫そうですかね?
(あとセクション数や行数をまだ設定していないViewControllerには適当に数字を入れておいてください。)
 
 
では、久しぶりの…

ビルダンゴーっ!!
 
 

7. 白く塗れ!

 
……あ…
 
ま……まっしろ…
 
 
…ですね……
 
 
ま…まさかぁって思って一旦終了してもう一度ビルドすると…
 
あっ! 表示された!!
 
 
でも、エラーが出てますね^^;
しかもチェックボックスをタップすると消えるし…

NSFetchedResultsController ERROR: A section returned nil value for section name key path ‘category’. Objects will be placed in unnamed section

意訳:セクション名のキーパスである’category’はnilを返しました。
オブジェクトは、名前のないセクションに入れられます。
 
 
そーですよぉ。
Categoryオブジェクト作ってないですから<(_ _;)>

 
 

8. ケアレスミス。そしてデバッグ。

 
…ってなワケで、気を取り直してデバッグを。
(念のためシミュレータからdotodoを削除しといてください。)

まずは、RootViewController.mで[Category.h]をインポートしてください。

関連のエンティティの作り方は『TodoCore』でもやりましたね。
これを追加すれば今度こそオッケーです!

ここで間違えちゃいけないのが、
[editedTask.managedObjectContext]にインサートするってトコだと思います。

これを[self.managedObjectContext]とか
[fetchedResultsController managedObjectContext]とかにしてしまうと
[editedTask]とは別のコンテクストにインサートされてしまうからです。
(editedTaskのコンテクストは[_provisionalContext])
 
 
これできっと大丈夫なハズですっ!

せぇ〜のっ!

うんっ♬
タップにもちゃんと対応して、順番も入れ替わりますね!

あと、タイトル未入力でSaveした時にアラートが表示されるか?とか
ちゃんとキャンセルされるか?とかも試してみてくださいね。
 
 
やっぱり、
こうして目に見える形になってくると楽しいもんですね♪

どうでしょう?
まだ新規作成処理だけですが
Todoアプリっぽくなってきたんじゃないでしょうか?

でも、
ここまで来るのはみなさんも結構大変だったんじゃないかなぁと思います。
とりあえずお疲れさまでした!
 
 
ってトコで、今回はここまでです。

明日は詳細ビューも見えるといいですね!
それじゃ、また明日も楽しくがんばりましょ。

広告

Study CoreData 14 ~目に見えるしあわせ~」への12件のフィードバック

  1. ピンバック: [夕刊]ヒーローオブスパルタ2の動画公開。これはすげーぞ!

  2. ピンバック: 頭と尻尾はくれてやる!

  3. Jacminikさんこんばんは
    再び出来の悪い生徒です。新規のTitleを入力しsaveを押すとTodoListは表示されますがデータは何も表示されません、何度もプログラムを見直しするのですが、エラーも警告も出てなくよくわかりません。ビルドログを見ると
    Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath: with userInfo (null)となってます。またeditedTaskの中でtags = “”;となってますが、これって関係ありますか?
    私は何が理解出来てないのでしょうか、よろしくご指導お願いします。

  4. 前文訂正
    editedTaskの中でtags = “”;となってますが、これって関係ありますか?
    ーーー
    editedTaskの中で tags = となってますが、これって関係ありますか?
    ーーー
    なぜか中身が抜けました。

  5. なぜか =の後がうまく表示されませんでした。
    もう一度テキストだけにします
    前文訂正
    editedTaskの中でtags = “”;となってますが、これって関係ありますか?
    ーーー
    editedTaskの中で tags = relationship fault 0x6536e10 tagsとなってますが、これって関係ありますか?
    ーーー

    • aonsさん、またまた返信がおそくなってしまいました<(_ _;)>

      まず、コメントに
      >> エラーも警告も出てなく(以下略)
      とありますが、ログに出力されてるものもエラーですのでエラーは出ていますね。こういう場合はまず、エラーを翻訳してみましょう。
      今回は大体こんな感じかと。
      “[controllerDidChangeContent:]までの間にエラー。UITableVIewのデータソースは[tableView:cellForRowAtIndexPath:]とuserInfoがセルを返さなければいけません。”

      つまり、新規セルが作られる時にテーブルビューとデータがうまく更新されていないようですね。正直コレだけの情報だと僕の方でエラーを限定するのは難しいです…<(_ _;)>

      なので、まずは一旦シミュレータからこのアプリを削除して再ビルドしてから、同じエラーが出るようなら原因を突き止めていくのが良いと思います。
      実際には[controllerDidChangeContent:]まで行く間のメソッド内で前と同じような感じでmanagedObjectをログ出力させます。
      それでおかしなところが絞られてくるのでは?と。

      それと”relationship fault 0x6536e10 tags”についてはNSManagedObjectにはフォールト(fault)という状態があります。
      簡単に説明すると”まだアクセスされていない保留状態のデータ”で、データにアクセスすればフォールト状態は解除されます。
      なのでそれだけなら問題はないのですが、アクセスしている(例えばcellに表示させようとしている)のにフォールト状態だとすると、何らかの原因でちゃんとアクセスできていない可能性があります。

      その辺りも踏まえて色々と調査してみると良いのではないでしょうか。

      それと、出来るだけ分かりやすく書いたつもりではありますが、当ブログのエントリだけでCoreDataやUITableViewを100%理解するのは不可能だと思います。他の情報もいろいろと参考にされた方がaonsさんにとって良いことだとおもいますよ(^^;)
      でも、こうして頑張られている方がいてくれるのは本当にウレシイです!
       
       
      あとこのブログのコメント欄はHTMLに対応しているようなので文字列を<と>で囲んでしまうと文字列がHTMLタグとして認識されてしまい、表示されないようです。

  6. jacminikさん、こんにちは、ご迷惑をおかけしてます。
    間違い分かりました、また今回も爆笑、大笑いものでした。エラーを見つける為に使われると考えられるコードにLOGを付け、前回作ったTodoCoreにも同じLOGを付け、流れを見比べていきました。そしてあやしい所はcellForRowAtIndexPathからconfigureCellにかけてかなとやっと目星をつけました。そこを一字一字チェックしたら、cellForRowAtIndexPathの中で、if (cell = nil) となってました。そう「=」が一つ足りなかったのです。すぐ下の行もcell = [[[になってたし、今まで全然気にならなかったです。
    爆笑、大笑い!!!!でしょ、笑ってやって下さい。
    直してデータが表示され、チェックマークの画像が変わったり、テキストの色がグレーになるのを見ながらうれし涙が出てきました。「14章〜目に見えるしあわせ〜」をしみじみ感じました。(タイトルの付け方うまいです。)なんてったって、私はこれに1週間以上費やして来ましたから・・・。
    さて、「15章〜未来は僕らの手の中〜」を信じて、気を取り直して先に進みます。また、大笑いネタを提供するかもしれませんがよろしくお願いします。

    • 解決おめでとーございます!

      そうそう、そういう間違いって良くありますね。
      僕も初期化メソッドでよくif (self = [super init])とかしちゃってることがあります^^;
      でも、そうこうしてる間に『自分がミスしやすいポイント』ってのも少しずつ見えてきて、その後はミスを見つけやすくなると思うんですよね。

      ともかくお疲れさまです!
      こちらこそヨロシクです。

  7. お助けください。
    1ヶ月ほど前からこちらのサイトを参考に勉強させていただいています。
    何度も何度もバグをを修正しながら試行錯誤のすえやっとここまできましたが、完璧に行き詰まってしまいました。
    Add New Taskの画面は表示されるのですが、 if (![context save:&error])のところでクラッシュします。

    以下のようなログが表示されます。(意味がよくわかりません)

    2011-06-14 04:38:08.417 DoTodo[610:207] New Task can’t Saved. Error Error Domain=NSCocoaErrorDomain Code=1570 “The operation couldn’t be completed. (Cocoa error 1570.)” UserInfo=0x4da4490 {NSValidationErrorObject= (entity: Task; id: 0x4d4f0b0 ; data: {
    category = “0x4da0420 “;
    completed = nil;
    created = “2011-06-13 19:38:08 +0000”;
    dueDate = “4001-01-01 00:00:00 +0000”;
    priority = 0;
    tags = (
    );
    title = Ty;
    }), NSValidationErrorKey=completed, NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1570.)}, {
    NSLocalizedDescription = “The operation couldn\U2019t be completed. (Cocoa error 1570.)”;
    NSValidationErrorKey = completed;
    NSValidationErrorObject = ” (entity: Task; id: 0x4d4f0b0 ; data: {\n category = \”0x4da0420 \”;\n completed = nil;\n created = \”2011-06-13 19:38:08 +0000\”;\n dueDate = \”4001-01-01 00:00:00 +0000\”;\n priority = 0;\n tags = (\n );\n title = Ty;\n})”;
    }
    Program ended with exit code: 255

    provisionalContextDidSaveが呼ばれないようなのですが、どうしてもその原因がわからず2日間この状態で止まったままです。
    どうかご教授よろしくお願いします。

    • tomtomさん。はじめまして!
      コメントありがとうございます。

      これはお困りのようですね^〜^;
      まず、頂いた内容だけでは僕の方で原因を完璧に突き止めるのは困難ですので
      それを探す手がかりになりそうなことを以下に書いておきますね。

      1. 一旦アプリをシミュレータ(実機?)から削除して再ビルド。
      2. [didEditProvisionalTask: saveType:]内の if (![context save:&error])の直前で保存する内容をログ出力させる。(LOG(@”保存しようとしているタスク: %@”, editedTask);)

      こうすると、当然タスクの内容が出力された後に現状のエラーが出力されると思います。
      そのエラーとログの内容を見比べてみてください。

      ちなみに頂いたエラーの内容はこんな感じかと。

      オペレーションが完了できませんでした。
      UserInfo=0x4da4490 {エラー原因のオブジェクト= (エンティティ: Task; id: 0x4d4f0b0 ;
      Taskの内容: {
category = “0x4da0420 “; (※ここがおかしい)
      
completed = nil; (※ここがおかしい)

      created = “2011-06-13 19:38:08 +0000″;
      
dueDate = “4001-01-01 00:00:00 +0000″; (※ここがおかしい)

      priority = 0;

      tags = なし;
      
title = Ty;
}), 以下略

      ざっとエラー内容だけ見ても3カ所おかしいところがあるのですが、
      恐らく一番の原因は”NSValidationErrorKey=completed,”とあるので
      completedキーに入れている値だと思います。
      実際エラー内容に”completed = nil;”とありますが、completedにはYES(1)かNO(0)が必ず入らなければいけないのでnilということはあり得ません。(ここまでの連載だと必ずNOになっているはず)

      なのでもしかしたらデータモデリングに原因があるかもです。
      (conmpletedのデフォルト値が偽(NO)に設定されていないとか )
      詳細:Study CoreData 3 ~デルモに手を出すなら慎重に…~『5. 今度こそモデリングしてみる^^;』
      https://jacminik.wordpress.com/2010/07/12/study-coredata-3/

      それとカテゴリーが0x4da0420というのもおかしいですね。
      ここまでだとここはnil(No Category?)になっているはずです。
      あとdueDateが4001年になっているのも。。。これもここまでだとnil。(もし進んでいるようならテスト機の設定が元号になっているとか)

      ちなみに[provisionalContextDidSave:]は保存が完了しないと呼ばれないので、この状態では呼ばれません。

      …とそんな感じですが、上記内容を修正してもダメならログ、エラーの内容を元に探ってみてください。
      これで解決できれば幸いです<(_ _)>

  8. jackminik 様

    早速のご回答ありがとうございました。
    ご指摘のとおりconmpletedのデフォルト値が偽(NO)になっていませんでした。
    なんども見なおしたつもりでしたが、これだけ漏れていました。

    おかげさまで、きちんと動くようになりました。
    サンプル画面と同じように表示することができました。感激です!
    ありがとうございました。

    引き続き最後まで頑張りますので、また何かありましたらご指導よろしくお願いいたします。

    • おお!解決しましたか!
      お役に立てて何よりです。

      僕もおかげさまでエラーの読み解き方を勉強できました^〜^;
      今後もヨロシクです<(_ _)>

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中