リモートファイルからダウンロードしたデータをCoreDataに保存したい。彼のデータは既にダウンロードされているかもしれませんし、変更をコアデータに追加する必要があります。 ここに表示されているコードを使用します。 3つの場所では、データがすでにデータベースに入っているかどうかを確認するためにFetchrequestを使用します。私はその要求に述語を使用します。コードでは、それらを区別するためのコメントを追加しました。アイテムがすでにcoreDataにある場合はデータを更新し、そうでない場合は新しいアイテムをインスタンス化します。アイテムをコアデータに追加するコードは、クラス内の便利なinitにあります。これは正常に動作します。私が得ている問題は次のとおりです。 このコードの最初のidは0であり、schoolFetchが実行されます。述語nr 1を追加するとエラーは発生せず、学校のクラスはそのIDを0に設定してインスタンス化されます。 2回目のID = 1。これは、場所が学校の一部であるlocationItemがチェックされてインスタンス化されることを意味します。場所を学校に追加するには、schoolInstanceを取得するためにfetchrequestが実行されます。述語2が使用されます。以前に追加されたschoolInstanceは取得されませんが、述部が使用されない場合(コメントアウトされている場合)はエラーは発生しません。 schoolInstanceが取得された後、私はfetchrequestを使用して、その場所がすでにcoredataにあるかどうかを確認します。それがインスタンス化されていない場合は、そのデータが更新されます。述語nr 3は、EXC_BAD_ACCESS(コード= 1、アドレス= 0x1)以外の何も記述しない実行時エラーを与えます。デバッガウィンドウにエラーの説明はありません。 2つの質問があります: a)なぜ述語nr 2は前に挿入された項目を返さないのですか? b)なぜ述語nr 3でエラーが発生するのですか?swiftでNSFetchrequestに述語を追加することの理解
私はこのコードをこのように構造化しました。最初に場所に関する情報を受け取ることができ、その後に学校に関する情報を受け取ることができます。
if id == 0 {
//get school
let schoolFetch = NSFetchRequest<StreekgidsSchool>(entityName: "School")
schoolFetch.predicate = NSPredicate(format: "locationId == %@", id) // predicate 1
do {
let fetchedSchool = try streekgidsModel?.context.fetch(schoolFetch)
if let school = fetchedSchool?.first{
school.name = name
school.locationId = id
school.colorValue = color
schoolInstance = school
}
else {
//create new entry in coredata for school
schoolInstance = StreekgidsSchool(name: name, context: (streekgidsModel?.context)!)
schoolInstance?.locationId = id
schoolInstance?.colorValue = color
}
} catch {
fatalError("Failed to fetch Schooldata: \(error)")
}
}
else {
//check if school already is defined
let schoolFetch = NSFetchRequest<StreekgidsSchool>(entityName: "School")
schoolFetch.predicate = NSPredicate(format: "locationId == %@", 0) //predicate 2
do {
let fetchedSchool = try streekgidsModel?.context.fetch(schoolFetch)
if let school = fetchedSchool?.first{
schoolInstance = school
}
else {
//create new entry in coredata for school
schoolInstance = StreekgidsSchool(id: 0, context: (streekgidsModel?.context)!)
}
} catch {
fatalError("Failed to fetch Schooldata: \(error)")
}
//get location
let locationFetch = NSFetchRequest<StreekgidsLocation>(entityName: "Location")
locationFetch.predicate = NSPredicate(format: "locationId == %@", id) //predicate 3
do {
let fetchedLocation = try streekgidsModel?.context.fetch(locationFetch)
if let location = fetchedLocation?.first{
location.name = name
location.locationId = id
location.colorValue = color
location.school = schoolInstance
}
else {
//create new entry in coredata for location
let locationInstance = StreekgidsLocation(name: name, context: (streekgidsModel?.context)!)
locationInstance.locationId = id
locationInstance.colorValue = color
}
} catch {
fatalError("Failed to fetch Schooldata: \(error)")
}
}
%@は一般的に述語のオブジェクトまたは文字列を表すのに使用されていませんか?今すぐ簡単にチェックすることはできませんが、私はあなたのIDがIntとしてより良く一致するかどうかチェックします。おそらく%iまたは%d – Magnas
ドキュメントには次のように記載されています。 "%@は、オブジェクト値のvar arg置換(文字列、数値、または日付)です。さらに、3つの述語はすべて等しくフォーマットされていますが、3番目のものだけがエラー – KvdLingen
になります。または、述語= NSPredicate(形式: "id ==%@"、IDはNSNumber) – Magnas