2016-12-26 3 views
0

Выполнение приведенного ниже кода для получения данных из Cloudkit, на данный момент занимает много времени, чтобы заполнить таблицуView, в зависимости от того, сколько результатов есть, но если есть более 15 результатов, это занимает 10 секунд плюс , Могут ли они ускорить это?Cloudkit Fetch очень медленно

Это моя выборка FUNC:

func loadData() { 
     venues = [CKRecord]() 
     let location = locationManager.location 

     let radius = CLLocationDistance(500) 

     let sort = CKLocationSortDescriptor(key: "Location", relativeLocation: location!) 

     let predicate = NSPredicate(format: "distanceToLocation:fromLocation:(%K,%@) < %f", "Location", location!, radius) 

     let publicData = CKContainer.defaultContainer().publicCloudDatabase 

     let query = CKQuery(recordType: "Venues", predicate: predicate) 

     query.sortDescriptors = [sort] 

     publicData.performQuery(query, inZoneWithID: nil) { (results:[CKRecord]?, error:NSError?) in 
      if let venues = results { 
       self.venues = venues 
       dispatch_async(dispatch_get_main_queue(), { 
        self.tableView.reloadData() 
        self.refreshControl.endRefreshing() 
        self.tableView.hidden = false 
       }) 
      } 
     } 
    } 

Это мой Tableview FUNC:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! NearMe2ViewCell 

     if venues.count == 0 { 


      return cell 
     } 

     let venue = venues[indexPath.row] 




     print(indexPath.row) 


     let venueLocation = venue["Location"] as? CLLocation 
     let venueTitle = (venue["Name"] as! String) 
     let venueImages = venue["VenuePhoto"] as! CKAsset 

     let userLocation = locationManager.location 
     let distanceBetween: CLLocationDistance = (venueLocation!.distanceFromLocation(userLocation!)) 
     self.venueDistance = String(format: "%.f", distanceBetween) 

     cell.venueDistance?.text = venueDistance 
     cell.venueName.text = venueTitle 
     cell.venueImage?.image = UIImage(contentsOfFile: venueImages.fileURL.path!) 


     return cell 


    } 

ответ

1

Вы должны искать ключи записи первых, так fetchOperation будет включать эту директиву.

fetchOperation.desiredKeys = ["record.recordID.recordName"] 

Это должно быть быстрее. Перерыв возвращенных ключей в размер, который вы можете отобразить на экране, и получить их только. После того, как вы их отобразите, перейдите к следующей партии в фоновом потоке, когда вы получили следующую партию на фоне и т. Д. И т. Д.

Следует добавить, возможно, что выборка актива должна быть выполнена по отдельному потоку, если это возможно, обновляя таблицу, когда вы извлекаете активы, повторно перегружая таблицу.

Вот метод поиска и возврата ключей.

func zap(theUUID:String) { 
    var recordID2Zap: String! 
    let predicate = NSPredicate(format: "(theUUID = %@)",theUUID) 
    let query = CKQuery(recordType: "Blah", predicate: predicate) 
    let searchOperation = CKQueryOperation(query: query) 
    searchOperation.desiredKeys = ["record.recordID.recordName"] 
    searchOperation.recordFetchedBlock = { (record) in 
     recordID2Zap = record.recordID.recordName 
    } 

     if error != nil { 
      print("ting, busted",error!.localizedDescription) 
     } else { 
      print("ok zapping") 
      if recordID2Zap != nil { 
       self.privateDB.delete(withRecordID: CKRecordID(recordName: recordID2Zap), completionHandler: {recordID, error in 
        NSLog("OK or \(error)") 
       }) 
      } 
     } 

    } 

    searchOperation.qualityOfService = .background 

    privateDB.add(searchOperation) 
    theApp.isNetworkActivityIndicatorVisible = true 
} 

} 

Что касается вашего Tableview, и изображений ... использовать завершение в коде ICloud отправить уведомление табличных.

database.fetchRecordWithID(CKRecordID(recordName: recordId), completionHandler: {record, error in 
    let directDict = ["blah": "whatever"] as [String : String] 
NotificationCenter.default.post(name: Notification.Name("blahDownloaded"), object: nil, userInfo: directDict) 
} 

И в VC вы регистрируете указанное уведомление.

NotificationCenter.default.addObserver(self, selector: #selector(blahDownloaded), name: Notification.Name("blahDownloaded"), object: nil) 

func blahDownloaded(notification: NSNotification) { 
    if let userInfo = notification.userInfo as NSDictionary? as? [String: Any] { 

//update you cell 
//reload your table 
} 

Это все имеет смысл?

+0

Я совершенно новый для облачного. Есть ли вероятность, что вы могли бы написать какой-то примерный код о том, как я должен это делать? –

1

Ваша операционная система qualityOfService по умолчанию равна .utility.

Существует важное замечание в documentation for CKOperation, который гласит:

CKOperation объекты имеют качество по умолчанию уровень обслуживания NSQualityOfServiceUtility (см qualityOfService). Операции на этом уровне считаются дискреционными и запланированы системой для оптимального времени, основанного на уровне заряда батареи и других факторах.

Поскольку CKOperation унаследован от NSOperation вы можете настроить qualityOfService свойство, когда ваш пользователь ждет на запрос, чтобы закончить. Вот несколько примеров кода основаны от твоего выше:

let queryOperation = CKQueryOperation(query: query) 
queryOperation.recordFetchedBlock = ... 
queryOperation.queryCompletionBlock = ... 

queryOperation.qualityOfService = .userInteractive 

publicData.add(queryOperation) 

Обратите внимание, что этот пример явно создает CKQueryOperation вместо того, чтобы использовать удобство API, потому что тогда дает вам возможность полностью настроить операции, прежде чем епдиеие их быть отправляется на сервер.

В этом случае вы можете установить qualityOfService в .userInteractive, потому что ваш пользователь активно ждет завершения запроса, прежде чем он сможет использовать ваше приложение.Узнать больше о возможных значениях можно здесь: https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html