UITableView
「HomeViewController」というビューを更新して、追加した新しいオブジェクトを表示しようとしています。しかし、NSFetchedResultsController
新しいものを作成した後、更新されません。さまざまなドキュメントに次のコードがあります。
HomeViewController.h
- (void)saveNewShindyToDatabaseForName:(NSString *)name
details:(NSString *)details
dateAndTime:(NSDate *)dateAndTime
location:(CLLocation *)location
timePosted:(NSDate *)postedTime
{
if (!self.shindysDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
self.shindysDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
}
dispatch_queue_t saveQ = dispatch_queue_create("Shindy Creator", nil);
dispatch_async(saveQ, ^{
[self.shindysDatabase.managedObjectContext performBlock:^{
[Shindy setupShindyForSaveToDatabaseForName:name
details:details
dateAndTime:dateAndTime
location:location
timePosted:postedTime
inManagedObjectcontext:self.shindysDatabase.managedObjectContext];
}];
});
NSError *error = nil;
if (![self.shindysDatabase.managedObjectContext save:&error]) {
NSLog(@"%@", error.userInfo);
}
}
- (void)setupFetchedResultsController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Shindy"];
NSSortDescriptor *nameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor *photoSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"photo" ascending:YES];
NSSortDescriptor *detailSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"details" ascending:YES];
NSSortDescriptor *dateAndTimeSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dateAndTime" ascending:YES];
NSSortDescriptor *timePostedSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"timePosted" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:nameSortDescriptor, photoSortDescriptor, detailSortDescriptor, dateAndTimeSortDescriptor, timePostedSortDescriptor, nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.shindysDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
Shindy+SQL.m (NSManagedObject
エンティティ「Shindy」のサブクラス)
+ (Shindy *)setupShindyForSaveToDatabaseForName:(NSString *)name
details:(NSString *)details
dateAndTime:(NSDate *)dateAndTime
location:(CLLocation *)location
timePosted:(NSDate *)postedTime
inManagedObjectcontext:(NSManagedObjectContext *)context
{
Shindy *shindy = [NSEntityDescription insertNewObjectForEntityForName:@"Shindy" inManagedObjectContext:context];
__block NSString *nameString = name;
__block FBProfilePictureView *profileImage = nil;
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
nameString = user.name;
profileImage.profileID = user.id;
}
}];
}
NSData *imageData = nil;
for (NSObject *obj in [profileImage subviews]) {
if ([obj isMemberOfClass:[UIImageView class]]) {
UIImageView *objImg = (UIImageView *)obj;
imageData = UIImagePNGRepresentation(objImg.image);;
break;
}
}
shindy.name = name;
shindy.dateAndTime = dateAndTime;
shindy.timePosted = postedTime;
shindy.details = details;
shindy.photo = imageData;
return shindy;
}
メソッド- (void)setupFetchedResultsController:
は、ビューが最初に読み込まれるときに呼び出されます (ただし、viewDidLoad
orviewWillAppear
メソッドでは呼び出されません)。- (void)saveNewShindyToDatabaseForName:
ユーザーがデータの入力を完了すると、私の関数は別のView Controllerで呼び出されます。つまり、これは公開 API ですが、 for 委任NSManagedObjectContext
内に残ります。HomeViewController
また、コードのデリゲートとデータ ソースが適切に設定されています。
私はあらゆる種類のフェッチを強制しようとしました。managedObjectContext 経由か、fetchedResultsController 経由か。NSLog
また、データが確実に に到達するように、コードのさまざまな場所に を設定しましたHomeViewController
。またNSLog
、fetchedResultsController と managedObjectContext の両方がnil
.
すべてがチェックアウトされているようで、現在コード内にある他のデフォルト エラーからのエラーは発生しません。
NSSortDescriptor
これが私のメソッドにある s で何かをしなければならないのではないかと心配してい- (void)setupFetchedResultsController:
ますが、さまざまな方法でそれらを構成しようとしても役に立ちませんでした。私の managedObjectContext と私の fetchedResultsController にも明確な接続があるので、それは問題ではありません。
私は単に試してみることを使い果たしました。おそらく、ここにいる誰かが何らかの洞察を持っています。
ジャータートンの場合...
- (void)saveNewShindyToDatabaseForName:
最初にそこにあったすべてのコードの後に、メソッドに次のコードを実装しました。次のようになります。
- (void)saveNewShindyToDatabaseForName:(NSString *)name
details:(NSString *)details
dateAndTime:(NSDate *)dateAndTime
location:(CLLocation *)location
timePosted:(NSDate *)postedTime
{
// All of the code originally in this method is here...
if ([self.fetchedResultsController managedObjectContext] == self.shindysDatabase.managedObjectContext) {
NSLog(@"MOC's are the same.");
}
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Shindy"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"details" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *detailsArray = [self.shindysDatabase.managedObjectContext executeFetchRequest:request error:&error];
if (error) {
NSLog(@"error: %@", error.userInfo);
}
NSLog(@"details: %@", detailsArray);
}
このすべてが返すのは、2 番目の可能な答えに答えるために、MOC は間違いなく同じであるということです。ただし、新しいオブジェクトが実際には Core Data に保存されていないように見えます。または、適切に引き戻していません。
認識できないセレクター エラーを発生させずに Core Data の内容をログに記録する唯一の方法は、正しいエンティティに対する新しい要求を作成し、フェッチを実行して、そのフェッチの結果をログに記録することでした。場合、何も返されませんでした。
私の問題は、新しいオブジェクトを Core Data に保存しないコードにあると仮定します。そうは言っても、これらのオブジェクトをコンテキストに適切に保存していない場所を特定して、後で取得するために Core Data モデルに配置できるようにできますか? または、コア データに保存されているものをログに記録するように要求する以外に、別の方法を設定する必要がありますか?