38

これを自分の個人的なコードの参照として使用しようとしている人を支援するために、これを更新し始めます。

最新のアップデート

  • デバイス同士の通信が停止したら、デバイスを再同期する方法を見つけたと確信しています。以下の回答をすべての詳細で更新します。これが皆さんのお役に立てば幸いです。これを理解するのに、試行錯誤のほぼ 2 か月かかりました。したがって、これを参照して、iCloud を介してデバイスを再び相互に通信させる同様の問題を抱えている他のユーザーと共有してください。これをすべて理解するのにとてつもなく時間がかかったので、できるだけ多くの他の開発者を自分でその場しのぎの修正を作成する必要から救うことができて、とてもうれしく思います。

正しく設定するためのもう 1 つの追加機能

  • iCloud データがアカウントに関連付けられているアプリを更新した後、アプリを開いたときにクラッシュが発生する可能性があることがわかりました。これは、iCloud データがデバイス (デバイスがまだ永続ストアをセットアップしていない場所) にすぐにマージしようとするためです。 にとを追加 @property (nonatomic, readwrite) BOOL unlocked;しました。次に、メソッドとメソッドを変更しました。両方を以下に示します (永続ストアのセットアップの場合は中央、iCloud マージ メソッドの場合は下部)。本質的には、アプリが永続的なストアをセットアップするまで、iCloud がデータをマージしないようにアプリに指示しています。そうしないと、読み取り不能な障害が原因でアプリがクラッシュする可能性があります。AppDelegate.h@synthesize unlocked;AppDelegate.m- (NSPersistentStoreCoordinator *)persistentStoreCoordinator- (void)mergeChangesFrom_iCloud

以下は、persistentStoreCoordinator のセットアップ方法です。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }


    // here is where you declare the persistent store is not prepared;
    self.unlocked = NO;

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Maintain_My_Car.sqlite"];

    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];   

    NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSDictionary *options = nil;

        NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];

        NSString *coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"data"];

        if (coreDataCloudContent.length != 0) {
            // iCloud enabled;

            cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];
            options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, @"<bundleIdentifier>.store", NSPersistentStoreUbiquitousContentNameKey, cloudURL, NSPersistentStoreUbiquitousContentURLKey, nil];

        } else {

            // iCloud not enabled;
            options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

        }

        NSError *error = nil;

        [psc lock];

        if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

            NSLog(@"bad things %@ %@", error, [error userInfo]);
            abort();

        }
        [psc unlock];

        // the store is now prepared and ready for iCloud to import data;
        self.unlocked = YES;


        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"iCloud persistent store added");

            [[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil];

        });
    });

    return __persistentStoreCoordinator;
}

<myAppKey>もちろん、<bundleIdentifier>実際の値です。このコードを共有する目的でそれらをマスキングしています。

一部の人々がまだこれに問題を抱えていることを知っており、この質問を参考にして、独自の iCloud 対応の Core Data アプリケーションをセットアップする方法を知っているので、個人コードを変更するたびにこれを更新して、皆さんは私のために働くコードを使うことができます。今回の更新では、最初の cloudURL を から に変更[fileManager URLForUbiquityContainerIdentifier:@"<TeamIdentifier>.<bundleIdentifier>"][fileManager URLForUbiquityContainerIdentifier:nil]、コンテナー情報が資格ファイルから収集されるようにしました。

追加のメソッド _notificationArrayは次のように定義されています。 @property (nonatomice, strong) NSMutableArray *notificationArray; @synthesize notificationArray = _notificationArray;

- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
    if (self.unlocked) {
        NSManagedObjectContext *moc = [self managedObjectContext];

        if (self.notificationArray.count != 0) {
            for (NSNotification *note in _notificationArray) {
                [moc performBlock:^{
                    [self mergeiCloudChanges:note forContext:moc];
                }];
            }
            [_notificationArray removeAllObjects];
            [moc performBlock:^{
                [self mergeiCloudChanges:notification forContext:moc];
            }];
        } else {
            [moc performBlock:^{
                [self mergeiCloudChanges:notification forContext:moc];
            }];
        }
    } else {
        if (_notificationArray == nil) {
            _notificationArray = [[NSMutableArray alloc] init];
        }
        [_notificationArray addObject:notification];
    }
}

- (void)resetStore {
    [self saveContext];
    __persistentStoreCoordinator = nil;
    __managedObjectContext = nil;
    // reset the managedObjectContext for your program as you would in application:didFinishLaunchingWithOptions:
    myMainView.managedObjectContext = [self managedObjectContext];
    // the example above will rebuild the MOC and PSC for you with the new parameters in mind;
}

次に、mergeiCloudChanges:forContext:方法があります:

- (void)mergeiCloudChanges:(NSNotification *)note forContext:(NSManagedObjectContext *)moc {
    // below are a few logs you can run to see what is being done and when;
    NSLog(@"insert %@", [[note userInfo] valueForKey:@"inserted"]);
    NSLog(@"delete %@", [[note userInfo] valueForKey:@"deleted"]);
    NSLog(@"update %@", [[note userInfo] valueForKey:@"updated"]);
    [moc mergeChangesFromContextDidSaveNotification:note];

    NSNotification *refreshNotification = [NSNotification notificationWithName:@"RefreshAllViews" object:self userInfo:[note userInfo]];
    [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
    // do any additional work here;
}

初期の問題

  • iOS 5.0.1 で iCloud を使用していると、永続ストアに関するエラーが時々発生します。実験を通じて見つけた新しい情報でこれを更新し続けますが、これまでのところ、私が提供した解決策は、アプリを再び適切に機能させる唯一の方法です (残念ながら、jlstrecker の解決策は私にはうまくいきませんでした)。次のようなエラーが表示され始めます。

    -NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:: CoreData: Ubiquity: Ubiquity ルート URL を読み込もうとしてエラーが発生しました: file://localhost/private/var/mobile/Library/Mobile%20Documents/./data/. エラー: エラー Domain=LibrarianErrorDomain Code=1 「操作を完了できませんでした。(LibrarianErrorDomain エラー 1 - アイテムのダウンロードを開始できません。)」 UserInfo=0x176000 {NSURL=file://localhost/private/var/mobile/Library /Mobile%20Documents/./data/, NSDescription=アイテムのダウンロードを開始できません。}

    私の人生では、なぜ突然これを見ているのか、どうすればそれを止めることができるのかわかりません。両方のデバイスからアプリを削除し、以前にそれらの間で同期していた iCloud データを削除し、アプリに関するバックアップからすべてのデータを削除しました。Xcode を再起動し、両方のデバイスを再起動し、Xcode プロジェクトをクリーンアップしましたが、エラーが表示されるのを止めるものは何もありません。私はこれまでこのエラーを見たことがなく、それを突き止める方法についてオンラインで何かを見つけることができませんでした.

    ここでアプリがクラッシュします。

    if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
    
        NSLog(@"bad things %@ %@", error, [error userInfo]);
        abort();
    
    }
    

    ログはヒットせず、アボートもありません。上記のエラーが表示され、アプリ自体が応答しなくなります。誰かが私を正しい方向に向けるのを助けることができれば、私は非常に感謝しています.

以前の問題/質問

  • これは、ベータ版から 5.0.1 のパブリック リリースへの更新後も続くようです。最後に起こったのは、マネージド コンテキスト データ モデルを変更した後です。まだアプリをリリースしていないことを考えると、わざわざ新しいバージョンのモデルをマージする必要はありませんでした。デバイスでアプリを削除して再インストールしたところ、iCloud コンテナーに保存されているデータとの連携が拒否されました。つまり、ストアがアイテムをダウンロードできないというエラーが表示されました。これは、データ モデル タイプの競合が原因であると考えられますが、これは完全に理にかなっています。したがって、コンテナーを削除せずに、iCloud コンテナー内のデータを削除するだけでよいようです。iCloud データを削除すると、コンテナと App ID が無効になり、すべてが無効になるようです。シンプルに見えたので、jlstrecker の提案に従って新しいコンテナーを作成しようとしましたが、残念ながら、これはまったく役に立ちませんでした。そのため、もう一度、回答で概説した手順を実行する必要がありましたが、これもうまくいきました. しかし、毎回新しいアプリ ID を作成し、プロビジョニング プロファイルを更新しなければならないことの煩わしさを考えると、潜在的に原因を絞り込み、より迅速な解決策にたどり着くために、学んだことを更新することが最善であると考えました。

    iCloud > Storage & Backup > Manage Storage に移動し、アプリを削除することがデータを空にする最善の解決策のように見えますが、これを行うとコンテナーが破損し、上記のエラーが発生するようです。そして、これを成功させた後、何度アプリを削除してデバイスに再インストールしても (デバイスに初めて表示されるように見せ、できればコンテナを再作成するため)、アプリを表示することはできません。 [ドキュメントとデータ] リストに再び表示されます。これは、iCloud からデータを削除すると、iCloud がアプリで二度と機能しなくなることを意味する場合、やや懸念されます。これまでのところ、アプリで開発プロファイルのみを使用しているため、おそらく配布プロファイルを使用すると多少の違いが生じる可能性がありますが、確かなことを言う前にそれをテストする必要があります.

これらの新しいアップデートが、ストアのセットアップに問題を抱えている可能性があるすべての人に役立つことを願っています. これまでのところ、私にとってはうまく機能しています。より良い修正や、プロセスをより目立たなくするものを見つけた場合は、必ずさらに更新します.

4

5 に答える 5

13

デバイスを再同期するための更新された回答 何ヶ月にもわたっていじり回した結果、根本的な問題が何であるかを突き止めました (私は信じています)。問題は、デバイスが同期しなくなった後、デバイスが再び相互に通信できるようにすることです。原因ははっきりとは言えませんが、トランザクション ログが破損しているか、(より可能性が高い) ログ自体のコンテナーが再作成されている可能性が高いと思われます。これは、デバイス A がコンテナー A に変更を投稿し、デバイス B が同じことを行うのと同じように、両方がコンテナー C に投稿し、そこでログの読み取り/書き込みができるのとは対照的です。

問題がわかったので、次は解決策を作成します。さらにいじくり回すと、次のことがわかりました。と呼ばれるメソッドがresetiCloudSync:(BOOL)isSourceあります。これは、元の質問の上記のメソッドの修正版です。

- (void)resetiCloudSync:(BOOL)isSource {
    NSLog(@"reset sync source %d", isSource);
    NSManagedObjectContext *moc = self.managedObjectContext;

    if (isSource) {
        // remove data from app's cloud account, then repopulate with copy of existing data;

        // find your log transaction container;
        NSURL *cloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
        NSString *coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"store"];
        cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];
        NSError *error = nil;

        // remove the old log transaction container and it's logs;
        [[NSFileManager defaultManager] removeItemAtURL:cloudURL error:&error];

        // rebuild the container to insert the "new" data into;
        if ([[NSFileManager defaultManager] createFileAtPath:coreDataCloudContent contents:nil attributes:nil]) {

            // this will differ for everyone else. here i set up an array that stores the core data objects that are to-many relationships; 
            NSArray *keyArray = [NSArray arrayWithObjects:@"addedFields", @"mileages", @"parts", @"repairEvents", nil];

            // create a request to temporarily store the objects you need to replicate;
            // my heirarchy starts with vehicles as parent entities with many attributes and relationships (both to-one and to-many);
            // as this format is a mix of just about everything, it works great for example purposes;
            NSFetchRequest *request = [[NSFetchRequest alloc] init];
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"Vehicle" inManagedObjectContext:moc];
            [request setEntity:entity];
            NSError *error = nil;
            NSArray *vehicles = [moc executeFetchRequest:request error:&error];

            for (NSManagedObject *object in vehicles) {
                NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:object.entity.name inManagedObjectContext:moc];
                // check regular values;
                for (NSString *key in object.entity.attributesByName.allKeys) {
                    [newObject setValue:[object valueForKey:key] forKey:key];
                }

                // check relationships;
                NSMutableSet *relSet = [[NSMutableSet alloc] init];
                for (NSString *key in object.entity.relationshipsByName.allKeys) {
                    [relSet removeAllObjects];

                    // check to see relationship exists;
                    if ([object valueForKey:key] != nil) {

                        // check to see if relationship is to-many;
                        if ([keyArray containsObject:key]) {
                            for (NSManagedObject *toManyObject in [object valueForKey:key]) {
                                [relSet addObject:toManyObject];
                            }
                        } else {
                            [relSet addObject:[object valueForKey:key]];
                        }

                        // cycle through objects;
                        for (NSManagedObject *subObject in relSet) {
                            NSManagedObject *newSubObject = [NSEntityDescription insertNewObjectForEntityForName:subObject.entity.name inManagedObjectContext:moc];
                            // check sub values;
                            for (NSString *subKey in subObject.entity.attributesByName.allKeys) {
                                NSLog(@"subkey %@", subKey);
                                [newSubObject setValue:[subObject valueForKey:subKey] forKey:subKey];
                            }
                            // check sub relationships;
                            for (NSString *subRel in subObject.entity.relationshipsByName.allKeys) {
                                NSLog(@"sub relationship %@", subRel);
                                // set up any additional checks if necessary;
                                [newSubObject setValue:newObject forKey:subRel];
                            }
                        }
                    }
                }   
                [moc deleteObject:object];
            }
            [self resetStore];
        }
    } else {
        // here we remove all data from the current device to populate with data pushed to cloud from other device;
        for (NSManagedObject *object in moc.registeredObjects) {
            [moc deleteObject:object];
        }
    }
    [[[UIAlertView alloc] initWithTitle:@"Sync has been reset" message:nil delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil] show];
}

このコードには、2 つの異なるパスがあります。1 つは、同期されておらず、ソース デバイスからデータをインポートする必要があるデバイス用です。そのパスが行うことは、メモリをクリアして、そこにあるはずのデータを準備することだけです。

もう一方の ( isSource = YES) パスは、多くのことを行います。通常、破損したコンテナは削除されます。次に、新しいコンテナーを作成します (ログが存在する場所を持つため)。最後に、親エンティティを検索してコピーします。これが行うことは、そこにあるはずの情報をトランザクション ログ コンテナーに再入力することです。次に、元のエンティティを削除して、重複しないようにする必要があります。最後に、永続ストアをリセットしてアプリのコア データを「更新」し、すべてのビューとfetchedResultsControllers.

これが素晴らしく機能することを証明できます。isSource = NO何ヶ月もプライマリ デバイス (データが保持されている) と通信していないデバイス ( ) からデータを消去しました。次に、プライマリ デバイスからデータをプッシュすると、すべてのデータが数秒以内に表示されるのを喜んで見ていました。

繰り返しになりますが、iCloud との同期で問題が発生したすべての人に、これを参照して共有してください。

元の質問への回答。iOS 5.1 が登場した後は影響を受けなくなり、設定でアプリの iCloud ストレージを削除した後のクラッシュが修正されました。

これを整理するために何時間もあらゆることを試した後、新しいアプリIDを作成し、アプリに関連付けられたプロビジョニングプロファイルを更新し、iCloudコンテナフィールドを変更して新しいプロファイルに一致させ、すべてが再び機能する. なぜこれが起こったのかはまだわかりませんが、その App ID に関連付けられた iCloud ストレージが破損したようですか?

要するに、これが他の誰かに起こった場合は、次の手順に従ってください。

  1. プロビジョニング ポータルで新しいアプリ ID を作成します。
  2. アプリに関連付けられているプロビジョニング プロファイルを見つけます。[編集] -> [変更] をクリックし、アプリ ID を作成したばかりのものに変更します。
  3. 変更を送信し、Xcode の既存のプロファイルを作成したプロファイルに置き換えます。
  4. のすべてのインスタンスを<bundleIdentifier>新しいアプリ ID に合わせて変更します (これらは、メインのアプリの [概要] ページ、iCloud コンテナーと iCloud キー バリュー ストアの資格、および私のコードのように永続的なストアを作成している AppDelegate ファイルにあります)。その上)。
  5. プロビジョニング プロファイルに関する情報を変更したため、Xcode を再起動します (それ以外の場合は文句を言い、デバイスでの実行を拒否します)。
  6. アプリをインストールするデバイスに新しいプロファイルがあることを確認してから、ビルドして実行します。この時点で、すべてが正常に機能するはずです。
于 2011-11-07T03:32:50.007 に答える
7

別の説明: iOS 6.0.1 および 6.1 ベータ 2 でデバイスをテストしているときに、同様の状況が発生しました。

@Slev が述べているように、iOS 5.1 では完全には修正されていません。1 つのデバイスは、iCloud の永続ストアにアクセスしようとして約 80 秒間完全にフリーズしますが、そこに保存されている情報に実際にアクセスすることはありませんでした。

これは、デバイスの OS のログ ファイルが破損しているためだと思います。デバイス上のアプリまたは iCloud データを削除しても、フリーズ/iCloud ストアへのアクセス不能は修正されませんでした。

私が見つけた1つの修正はreset all settings、デバイスで(すべてのコンテンツ作品も消去する)ことでした.settings->general->reset.

そうして初めて、そのデバイスのアプリで iCloud のデータに再びアクセスできるようになりました。これが、非常に苛立たしいバグの解決策を探してここに来た他の誰かに役立つことを願っています.

于 2012-11-19T23:02:44.943 に答える
3

1 つのデバイスを 5.0.1 beta 1 で使用し、もう 1 つのデバイスを 5.0.0 で使用しているときに、このエラーが発生しました。

iCloudコンテナの名前を変更することでエラーを取り除きました。iCloud コンテナー リストでは、最初のコンテナーがアプリ ID と一致する必要がありますが、別の名前のコンテナーを追加することができます。

(アプリ ID を変更する slev のソリューションと同様に、これはアプリがまだリリースされていない場合にのみ有効なソリューションです。)

于 2011-11-10T01:40:04.310 に答える
0

すみません、私はあなたがアプリがクラッシュすると言ったときと同じ問題を抱えています.iCloudデータがデバイスにすぐにマージしようとするためです(デバイスは永続的なストアをまだセットアップしていません)が、私はできます.これをどのように解決したのか理解できません。

あなたのコードは次のとおりです。

- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
    if (self.unlocked) {
       NSManagedObjectContext *moc = [self managedObjectContext];
        [moc performBlock:^{
            [self mergeiCloudChanges:notification forContext:moc];
        }];
    }
}

まだ試していませんが、このコードを見ると、「unlocked」が false の場合に届く通知はどうなるのだろうと思います。それらを緩めますか?

「ロック解除された」プロパティをテストし、プロパティが true になるまでの時間を費やす while ループを作成する方がよいのではないでしょうか?


私の非常に下手な英語を理解してくれることを願っています... :) Daveありがとう

于 2012-05-14T11:28:04.730 に答える
0

アップデート:

誰もが WWDC 2012 の iCloud Core Data セッション 227 を実際に見てみる必要があります。彼らが提供するソース コードは、iCloud ベースのソリューションの優れた出発点です。彼らがしていることを実際に時間をかけて見てください。あるストアから別のストアへのオブジェクトのコピーや重複排除など、いくつかの穴を埋める必要があります。migratePersistentStoreそうは言っても、ローカルストアとiCloudストアの間を移動するために、以下で説明するアプローチを使用しなくなりました.


私の元の答え:

Slev から、ストアをローカル コピーから iCloud に移行し、再び移行するためのコードを投稿するように依頼されました。このコードは実験的なものであり、本番環境では使用しないでください。ここでは、共有して前進するための参照としてのみ提供されています。Apple が適切なリファレンス アプリケーションをリリースしたら、パターンとプラクティスについて参照する必要があります。

-(void) onChangeiCloudSync
{
    YourAppDelegate* appDelegate = (YourAppDelegate*) [[UIApplication sharedApplication] delegate];
    NSFileManager *fileManager = [NSFileManager defaultManager];

    if ([iCloudUtility iCloudEnabled])
    {
        NSURL *storeUrl = [[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourApp2.sqlite"];
        NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
        NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"data"];
        cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];

        //  The API to turn on Core Data iCloud support here.
        NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@"com.yourcompany.yourapp.coredata", NSPersistentStoreUbiquitousContentNameKey, cloudURL, NSPersistentStoreUbiquitousContentURLKey, [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];

        NSPersistentStore* store = [appDelegate.persistentStoreCoordinator.persistentStores objectAtIndex:0];
        NSError* error;
        if (![appDelegate.persistentStoreCoordinator migratePersistentStore:store toURL:storeUrl options:options withType:NSSQLiteStoreType error:&error])
        {
            NSLog(@"Error migrating data: %@, %@", error, [error userInfo]);
            //abort();
        }
        [fileManager removeItemAtURL:[[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourApp.sqlite"] error:nil];
        [appDelegate resetStore];
    }
    else
    {
        NSURL *storeUrl = [[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourApp.sqlite"];

        //  The API to turn on Core Data iCloud support here.
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                 nil];

        NSPersistentStore* store = [appDelegate.persistentStoreCoordinator.persistentStores objectAtIndex:0];
        NSError* error;
        if (![appDelegate.persistentStoreCoordinator migratePersistentStore:store toURL:storeUrl options:options withType:NSSQLiteStoreType error:&error])
        {
            NSLog(@"Error migrating data: %@, %@", error, [error userInfo]);
            //abort();
        }
        [fileManager removeItemAtURL:[[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourApp2.sqlite"] error:nil];
        [appDelegate resetStore];
    }
}
于 2012-02-19T21:14:07.857 に答える