2016-12-08 8 views
0

私は並列性が本当に頭痛であることを知っています。サーバデータを解析してコアデータに保存する方法については非常に多くの記事があります。しかし、多くのチュートリアルは、しかし、私たちがアプリケーションを開発するときには、マルチスレッドが必要です。背景には、重複をチェックする必要がある 4.Thenはフェッチ -サーバデータをバックグラウンドスレッドの問題でコアデータに保存する

マイアプリのプロセスがされているがURLSession
コアデータへ 2.Andパース
3.Saveを使用してサーバから

し1.Getデータを以下のデータ
5. UIを更新します。

アムは、コアデータに保存する第三ステップで立ち往生 - 背景には、私はURLSessionは、バックグラウンドスレッドで実行されている、ことを読んで重複

をチェックする必要があります。りんごが言うようにperformblockを使用する必要がありますか? https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html

私はフォローアップの方法で試しました。しかし、いつかはクラッシュしました。誰でもプログラミングの正しい流れを提案する方が良いでしょう。これに関して多くの質問がありますが、この問題では正しい解決策はありません。

func DownloadFrom_server(dict:Any,urlstring_get:String) { 
    if JSONSerialization.isValidJSONObject(dict) { 
     do{ 
      let json:Data = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions.prettyPrinted) 

      var urlString = urlstring_get 
      urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlPathAllowed)! 
      var httpRequest = URLRequest(url: URL(string: urlString)!) 
      httpRequest.httpMethod = "POST" 
      httpRequest.httpBody = json 
      let sessionConfig = URLSessionConfiguration.default 
      sessionConfig.httpAdditionalHeaders = ["Accept" : "application/json", "api-key" : "API_KEY"] 
      let session = URLSession(configuration: sessionConfig) 
      let task = session.dataTask(with: httpRequest) { data, response, error in 
       guard let data_get = data, error == nil else{// check for fundamental networking error 
        print("data nil\(error)") 
        //1.network connection lost 
        //save offline data 
        return 
       } 
       do { 
        let jsonResult = try JSONSerialization.jsonObject(with: data_get, options: JSONSerialization.ReadingOptions.mutableContainers) 
        print("cloud data",jsonResult) 
        self.Save_server_Data_ToCoreData(jsonResult: jsonResult) 
       } 
       catch { 
        print("json result parsing error ",error) 
       } 
      } 
      task.resume() 
     } 
     catch{ 
      print("InValidJSONObject json:Data error - ",error) 
     } 
    } 
} 

そして

func Save_server_Data_ToCoreData(jsonResult:Any) { 
    let context = getContext() 
    let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) 
    privateMOC.parent = context 
    privateMOC.perform { 
     if let data = jsonResult as? [[String: AnyObject]]{ 
      //Heree prepare MOC 
      // if i need to check data alredy exits or not means how can i check 
     } 
     do { 
      try privateMOC.save() 
      context.performAndWait { 
       do { 
        try context.save() 
       } catch { 
        fatalError("Failure to save context: \(error)") 
       } 
      } 
     } catch { 
      fatalError("Failure to save context: \(error)") 
     } 
    } 

    DispatchQueue.main.async(execute: { 
         print("update main") 
        }) 
} 

は私が道

   DispatchQueue.global(qos: .background).async { 
//saving core data 
//fetching data 
DispatchQueue.main.async { 
    //update UI 
} 
    } 

使用する必要がどの文脈わからない、プライベートまたは以下にすることの第二の考えを持って次のようにコアデータへのサーバーjosnを保存しますこの質問に答えた人は、私のようなマルチスレッドの初心者にとっては役に立ちます。

+0

MagicalRecordを試してください:https://github.com/magicalpanda/MagicalRecord – iDhaval

答えて

0

idなどの独自のフィールドで新しいものを確認または作成する機能を使用できます。すでにレコードが存在するとすると、フィールドをスキップまたは更新できますが、新しいレコードを作成することはできません。コアデータで二枚舌チェックするためのサーバAPI

func findOrCreate(byId objectId: String) -> NSManagedObject { 
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Document") 

    // Create a new predicate that filters out any object that equal to this id 
    print("looking for id: \(objectId)") 

    let predicate = NSPredicate(format: "objectId == %@", objectId) 

    // Set the predicate on the fetch request 
    fetchRequest.predicate = predicate 

    do { 

     // if found in core data 
     let results = try managedObjectContext.fetch(fetchRequest) 
     if !results.isEmpty { 
      return results.first as! NSManagedObject 
     } 

    } catch let error as NSError { 
     print("Could not create object \(error), \(error.userInfo)") 
    } 

    // else create new object 
    let entity = NSEntityDescription.entity(forEntityName: "DocumentEntity", in:managedObjectContext) 

    let newObject = NSManagedObject(entity: entity!, insertInto: managedObjectContext) 

    return newObject 
} 
+0

ありがとうございます。しかし、マルチスレッドについて話しています。重複をチェックするのではありません。 – Lydia

1

から受信したデータをループするとき

あなたはこれを呼び出すことができます(あなたのエンティティが主キーの一意のフィールドを持っていることを確認してください)。 ios9の上には、Coredataに固有の制約機能があります。

IDなどのエンティティの記述の制約で設定したプロパティ名を、名前など

enter image description here

とmanagedobjectcontextセットでNSMergeByPropertyObjectTrumpMergePolicy

にポリシーをマージ

managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

上記のことを覚えておいてくださいエンティティに関係がある場合、二重性チェック機能は動作しません(xcodeでチェックしています) 7.3)。

+0

ありがとうございます。これは便利です。 – Lydia

関連する問題