2016-04-26 10 views
0

Ich versuche, von Parse zu CloudKit zu wechseln und habe mein Beispiel so weit gebracht. bekam ich einen CLoudKitModel, die wie folgt aussieht:CloudKit langsame Reaktionszeit?

class CloudKitModel { 
    let container: CKContainer 
    let privateDB: CKDatabase 
    let publicDB: CKDatabase 

    init() { 
     container = CKContainer.defaultContainer() 
     privateDB = container.privateCloudDatabase 
     publicDB = container.publicCloudDatabase 
    } 

    func getPlayers(completionHandler: (data: [CloudKitPlayers]?, success: Bool) ->()) { 
     var playerArray = [CloudKitPlayers]() 
     let predicate = NSPredicate(value: true) 
     let sort = NSSortDescriptor(key: "sortID", ascending: true) 
     let query = CKQuery(recordType: "Player", predicate: predicate) 
     query.sortDescriptors = [sort] 

     let operation = CKQueryOperation(query: query) 

     operation.recordFetchedBlock = { (record) in 
      let players = CloudKitPlayers() 
      players.age = record["age"] as! Int 
      players.name = record["name"] as! String 
      players.nickname = record["nickname"] as! String 
      players.position = record["position"] as! String 

      let imageData = record["image"] as! CKAsset 
      players.image = UIImage(contentsOfFile: imageData.fileURL.path!) 

      playerArray.append(players) 
     } 

     operation.queryCompletionBlock = { (cursor, error) in 
      if error == nil { 
       print("Fetched all players") 
       if playerArray.count > 0 { 
        completionHandler(data: playerArray, success: true) 
       } else { 
        completionHandler(data: nil, success: false) 
       } 
      } 
     } 

     self.publicDB.addOperation(operation) 
    } 
} 

und nenne ich getPlayers(completionHandler:) Funktion in einem UITableViewController:

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    let cloudKit = CloudKitModel() 
    cloudKit.getPlayers { (data, success) in 
     if success { 
      if let playerArray = data { 
       self.players = playerArray 
       dispatch_async(dispatch_get_main_queue(), { 
        self.tableView.reloadData() 
       }) 
       print("reloaded tableView") 
      } 
     } else { 
      print("no success") 
     } 
    } 
} 

Das Problem ist: Es dauert im Durchschnitt etwa 10 Sekunden, um die Namen anzuzeigen, in das TableView. Es ist nicht so, dass ich wie tausend Datensätze gleichzeitig bekomme, das sind nur 8 Datensätze, die ich von iCloud lade. Ich lese, dass ich die tableView.reloadData() auf dem Hauptthread durchführen sollte, aber das half auch nicht.

Gibt es noch etwas, das ich vermisse oder einen bestimmten Weg, um dies zu debuggen? Verglichen mit der Parse ist diese Lösung wie 10x langsamer ...

Danke für jede Idee!

+1

Was zeigt die Ausgabe von 'Time Profiler'? Welcher Teil Ihres Codes ist langsam? Oder ist das Problem das Netzwerk? Bevor Sie das Problem beheben können, müssen Sie das Problem verstehen, indem Sie es messen. –

+0

Der 'Time Profiler' hat nichts besonderes gesagt. Mein Netzwerk sollte auch nicht das Problem sein (verbunden mit dem WiFi zu Hause). Siehst du irgendetwas Seltsames in meinem Code? – heikomania

Antwort

1

Können Sie versuchen, die QOS einzustellen?

operation.qualityOfService = .UserInitiated 
+0

Fühlt sich an wie das gleiche, aber ich werde es mir merken. Vielen Dank. – heikomania

0

die meisten Geschwindigkeit zu bekommen, werden Sie wahrscheinlich wollen Sie die CKAsset Bilder asynchron, so wickeln Sie die Spieler Bild lädt in einem Hintergrundthread Betriebsblock zu laden. Hier

und als Beispiel von meinem Code, der Fotos holt, die Sie von extrapolieren können:

var backgroundQueue = NSOperationQueue() 

func fetchPhoto(completion:(photo: UIImage!) ->()) { 

    backgroundQueue.addOperationWithBlock() { 
    let image = self.record["Photo"] as? CKAsset 
    if let ckAsset = image { 
     let url = ckAsset.fileURL 
     if let imageData = NSData(contentsOfURL:url) { 
     self.photo = UIImage(data: imageData) 
     } 
    } 

    completion(photo: self.photo) 
    } 
} 

Dann für die Tischbelastung in cellForRowAtIndexPath Sie das Bild über den Abschluss Block laden können, aber Sie müssen alle UI setzen auf dem Hauptthread oder Sie werden zufällige Abstürze erleben, wie in:

object.fetchPhoto { 
    image in 
    dispatch_async(dispatch_get_main_queue()) { 
    cell.photo.image = image 
    } 
}