私はIOS開発に不慣れです。現時点では、Web サービスからデータを取得してコア データベースに保存し、NSFetchedResultController を使用してテーブルビューに表示する iPad アプリを作成しています。
何が問題ですか。IOS6 では魅力的に動作し、IOS 5.0 ではデータを保存しますが、テーブルビューには表示しません。次のエラーが発生します。
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. The NIB data is invalid. with userInfo (null)
そして、IOS 5.1 でテストしても何もしません。テーブルビューにデータが表示されず、データがコア データベースに保存されていません。
これが私がすることです。私のビューには、使用できるドキュメントがあるかどうかを確認するように表示されました。
if (!self.genkDatabase) { // we'll create a default database if none is set
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Default appGenk Database"];
self.genkDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; // setter will create this for us on disk
}
それから私のセッターに行きます。次に、usedocument でドキュメントがどの状態かをチェックします。
- (void)setGenkDatabase:(UIManagedDocument *)genkDatabase
{
if (_genkDatabase != genkDatabase) {
_genkDatabase = genkDatabase;
[self useDocument];
}
NSLog(@"Comes in the setdatabase methode.");
}
- (void)useDocument
{
NSLog(@"Comses in the use document");
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.genkDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.genkDatabase saveToURL:self.genkDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(@"create");
[self setupFetchedResultsController];
NSLog(@"create 2");
[self fetchNewsIntoDocument:self.genkDatabase];
NSLog(@"create 3");
}];
} else if (self.genkDatabase.documentState == UIDocumentStateClosed) {
NSLog(@"closed news");
// exists on disk, but we need to open it
[self.genkDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateNormal) {
NSLog(@"normal");
// already open and ready to use
[self setupFetchedResultsController];
}
}
最後に、次の関数を使用してドキュメント内のデータをフェッチします。
- (void)fetchNewsIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchNews = dispatch_queue_create("news fetcher", NULL);
dispatch_async(fetchNews, ^{
NSArray *news = [GenkData getNews];
[document.managedObjectContext performBlock:^{
int newsId = 0;
for (NSDictionary *genkInfo in news) {
newsId++;
[News newsWithGenkInfo:genkInfo inManagedObjectContext:document.managedObjectContext withNewsId:newsId];
NSLog(@"news inserted");
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
}];
});
dispatch_release(fetchNews);
}
IOS 5.0 の問題は、これが私の NSFetchResultController メソッドです。
- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"News"];
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES],nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.genkDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
私は、スタンフォード大学のポール・ヘガティの例のようにこれを行っています。Photomaniaのサンプルはこちらでご覧いただけます。
誰でも私を助けてくれることを願っています!
敬具