2016-01-30 1 views
5

Я использую CloudKit в своем приложении, чтобы дистанционно удалять данные. Одна из моих записей имеет свойство CKAsset, которое содержит изображение. Когда я собираю записи, я понял, что для завершения запроса требуется столько времени. После нескольких тестов я пришел к выводу, что при запросе записей CloutKit загружает весь файл Asset с объектом записи. Следовательно, когда вы получаете Asset из объекта записи и запрашиваете файл fileURL, он дает URL-адрес локального пути к файлу, а не URL-адрес типа HTTP. Это как проблема для меня, потому что вы должны позволить пользователю подождать так много времени, чтобы все записи были загружены (со связанными ими изображениями) до завершения запроса. Исходя из фона Parse, Parse используется для предоставления вам URL-адреса HTTP, и запрос выполняется достаточно быстро, чтобы загрузить пользовательский интерфейс с объектами при загрузке изображений async. Мой вопрос в том, как я могу добиться того, что делает «Парс»? Мне нужно ограничить запросы от загрузки данных Assets и получить ссылку для загрузки изображений асинхронно.Получение URL-адреса CKAsset без загрузки данных

+0

нет http-адреса http. Вы можете получить только локальный URL. Как и ответ ниже, вы можете запрашивать данные без актива. –

ответ

1

Сделайте два отдельных вызова для одной записи. Первый вызов должен получить все требуемые поля NON-активов, а затем второй запрос должен получить требуемые активы.

Что-то вроде:

let dataQueryOperation = CKQueryOperation(query: CKQuery(predicate: myPredicate) 
dataQueryOperation.desiredKeys = ["name", "age"] // etc 
database.addOperation(dataQueryOperation) 

let imageQueryOperation = CKQueryOperation(query: CKQuery(predicate: myPredicate) 
imageQueryOperation.desiredKeys = ["images"] 
database.addOperation(imageQueryOperation) 

Если необходимо, реорганизовать это в метод, так что вы можете легко сделать новый CKQueryOperation для каждого актива, содержащего поле.

Счастливые охоты.

0

Как и другие, вы не можете получить URL-адрес CKAsset. Таким образом, ваши лучшие варианты: 1. Используйте операцию выборки с прогрессом на каждый UIImageView. Я создал пользовательский, который показывает прогресс для пользователя. Кэш не включен, но вы можете создать класс и принять NSCoding и сохранить всю запись в кэше. Здесь вы можете увидеть выборку, в которой у меня есть завершение, чтобы отправить объект обратно туда, где я его вызываю, чтобы объединить его с моими другими данными.

 // only get the asset in this fetch. we have everything else 

Пусть операция = CKFetchRecordsOperation (recordIDs: [myRecordID])

operation.desiredKeys = ["GameTurnImage"] 
     operation.perRecordProgressBlock = { 
      record,progress in 

      dispatch_async(dispatch_get_main_queue(), { 
       self.progressIndicatorView.progress = CGFloat(progress) 
      }) 

     } 

    operation.perRecordCompletionBlock = { 
     record,recordID,error in 
     if let _ = record{ 
      let asset = record!.valueForKey("GameTurnImage") as? CKAsset 

      if let _ = asset{ 

        let url = asset!.fileURL 
        let imageData = NSData(contentsOfFile: url.path!)! 
       dispatch_async(dispatch_get_main_queue(), { 

        self.image = UIImage(data: imageData) 
        self.progressIndicatorView.reveal() 

       }) 
       completion(asset!) 
      } 
     } 

    } 
    CKContainer.defaultContainer().publicCloudDatabase.addOperation(operation) 

Другой вариант для хранения изображений на сервере AWS или что-то сравнимого, а затем вы можете использовать что-то вроде SDWebImage делать все кеширования или тяжелого подъема и сохранить строку в CKRecord для изображения.

Я попросил нескольких людей о функции CKAsset, чтобы выставить URL-адрес. Я не знаю о JS Api для CloudKit, но может быть способ сделать это с этим, но я позволю другим пообщаться с этим.

3

Вы можете использовать JavaScript CloudKit для доступа к URL-адресу актива. Вот пример;

Alamofire и SwiftyJSON)

func testRecordRequest() -> Request { 
    let urlString = "https://api.apple-cloudkit.com/database/1/" + Constants.container + "/development/public/records/query?ckAPIToken=" + Constants.cloudKitAPIToken 
    let query = ["recordType": "TestRecord"] 
    return Alamofire.request(.POST, urlString, parameters: ["query": query], encoding: .JSON, headers: nil) 
} 

JSON-ответ содержит "downloadURL" для данного актива.

"downloadURL": "https://cvws.icloud-content.com/B/.../${f}?o=AmVtU..." 

"$ {f}" похоже на переменную, поэтому измените ее на все, что угодно.

let downloadURLString = json["fields"][FieldNames.image]["value"]["downloadURL"].stringValue 
let recordName = json["recordName"].stringValue 
let fileName = recordName + ".jpg" 
let imageURLString = downloadURLString.stringByReplacingOccurrencesOfString("${f}", withString: fileName) 

И теперь мы можем использовать этот urlString создать NSURL и использовать его с любым изображением & решений кэша, таких как Kingfisher, HanekeSwift и т.д. (Вы также можете сохранить изображение типа png/jpg)

+0

Удивительный трюк @anilgoktas, у меня есть сомнения, что такое [Keys.image]? – drdrdrdr

+1

@drdrdrdr [Keys.image] -> имя поля изображения в типе записи. Вы можете проверить его на панели CloudKit. Это было странно, просто изменило его. Спасибо – anilgoktas

+0

@anilgoktas Этот запрос возвращает '' serverErrorCode = "AUTHENTICATION_REQUIRED"; "' с redirectURL на веб-страницу входа в систему. Как вы это преодолели? –