2017-02-23 5 views
1

リモートファイルからダウンロードしたデータを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でNSFe​​tchrequestに述語を追加することの理解

私はこのコードをこのように構造化しました。最初に場所に関する情報を受け取ることができ、その後に学校に関する情報を受け取ることができます。

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)") 
     } 

    } 
+0

%@は一般的に述語のオブジェクトまたは文字列を表すのに使用されていませんか?今すぐ簡単にチェックすることはできませんが、私はあなたのIDがIntとしてより良く一致するかどうかチェックします。おそらく%iまたは%d – Magnas

+0

ドキュメントには次のように記載されています。 "%@は、オブジェクト値のvar arg置換(文字列、数値、または日付)です。さらに、3つの述語はすべて等しくフォーマットされていますが、3番目のものだけがエラー – KvdLingen

+0

になります。または、述語= NSPredicate(形式: "id ==%@"、IDはNSNumber) – Magnas

答えて

1

正確に。 %@は引数としてFoundationオブジェクトを期待していますが、Intはオブジェクトではありません。したがって、あなたのid(ゼロに設定されている)はゼロとして解釈されます。これは、なぜあなたの述語2が何も返さない理由と、それをコメントアウトするときに結果を取得する理由です。 3つ目の述部だけが実行時エラーをスローしますが、実際には3つすべての述部が正しく機能していません。最初の2つはすぐに見えなくなります。 %dに%@を代入しようとしましたか?

そして、符号なし整数として%uを指摘します。

関連する問題