Выполнение фоновой загрузки
Как только пользователь завершит свою запись и нажмет кнопку «Отправить», расширение должно загрузить контент в какой-нибудь веб-сервис.Для целей этого примера URL-адрес конечной точки содержится в свойстве контроллера представления:
let sc_uploadURL = "http://requestb.in/oha28noh"
Это URL-адрес для службы запросов, которая дает вам временный URL-адрес, позволяющий вампроверить сетевые операции.Вышеприведенный URL-адрес (и тот, что в примере кода) не будет работать для вас, но если вы посетите requestb.in, вы можете получить свой собственный URL-адрес для тестирования.
Как упоминалось ранее, это важноэти расширения очень ограничивают системные ресурсы.Следовательно, в тот момент, когда нажата кнопка «Post», нет времени для выполнения синхронной сетевой операции переднего плана.К счастью, NSURLSession
предоставляет простой API для создания фоновых сетевых операций, и это то, что вам нужно здесь.
Метод, который вызывается, когда пользователь нажимает на сообщение, - didSelectPost()
, и в его простейшей формеэто должно выглядеть так:
override func didSelectPost() {
// Perform upload
...
// Inform the host that we're done, so it un-blocks its UI.
extensionContext?.completeRequestReturningItems(nil, completionHandler: nil)
}
Настройка NSURLSession
довольно стандартна:
let configName = "com.shinobicontrols.ShareAlike.BackgroundSessionConfig"
let sessionConfig = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(configName)
// Extensions aren't allowed their own cache disk space. Need to share with application
sessionConfig.sharedContainerIdentifier = "group.ShareAlike"
let session = NSURLSession(configuration: sessionConfig)
Важная часть, на которую следует обратить внимание в приведенном выше фрагменте кода, - это строка, которая устанавливаетsharedContainerIdentifier на конфигурации сеанса.Здесь указывается имя контейнера, который NSURLSession может использовать в качестве кэша (поскольку расширения не имеют собственного доступа к диску для записи).Этот контейнер должен быть настроен как часть хост-приложения (т.е. ShareAlike в этой демонстрации), и его можно выполнить с помощью Xcode:
- Перейти на вкладку возможностей целевого приложения
- Включить группы приложений
- Создать новую группу приложений с названием что-то подходящее.Она должна начинаться с группы. В демоверсии группа называется group.ShareAlike
- Пусть XCode проходит процесс создания этой группы для вас.
![enter image description here](https://i.stack.imgur.com/26DVY.png)
Затем вам нужно перейти к цели расширения и выполнить тот же процесс.Обратите внимание, что вам не нужно создавать новую группу приложений, а вместо этого выберите ту, которую вы создали для своего хост-приложения.
![enter image description here](https://i.stack.imgur.com/QeUrs.png)
Эти приложениягруппы регистрируются под вашим идентификатором разработчика, и процесс подписания гарантирует, что только ваши приложения могут получить доступ к этим общим контейнерам.
Xcode создаст файл разрешений для каждого из ваших проектов, и он будет содержать имяобщего контейнера, к которому он имеет доступ.
Теперь, когда вы правильно настроили сеанс, вам нужно создать URL-запрос для выполнения:
// Prepare the URL Request
let request = urlRequestWithImage(attachedImage, text: contentText)
Это вызывает методкоторый создает запрос URL, который использует HTTP POST для отправки некоторого JSON, который включает содержимое строки и некоторые свойства метаданных об изображении:
func urlRequestWithImage(image: UIImage?, text: String) -> NSURLRequest? {
let url = NSURL.URLWithString(sc_uploadURL)
let request = NSMutableURLRequest(URL: url)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPMethod = "POST"
var jsonObject = NSMutableDictionary()
jsonObject["text"] = text
if let image = image {
jsonObject["image_details"] = extractDetailsFromImage(image)
}
// Create the JSON payload
var jsonError: NSError?
let jsonData = NSJSONSerialization.dataWithJSONObject(jsonObject, options: nil, error: &jsonError)
if jsonData {
request.HTTPBody = jsonData
} else {
if let error = jsonError {
println("JSON Error: \(error.localizedDescription)")
}
}
return request
}
Этот метод фактически не создает запрос, который загружает изображение, хотя это может быть адаптировано для этого.Вместо этого он извлекает некоторые подробности об изображении, используя следующий метод:
func extractDetailsFromImage(image: UIImage) -> NSDictionary {
var resultDict = [String : AnyObject]()
resultDict["height"] = image.size.height
resultDict["width"] = image.size.width
resultDict["orientation"] = image.imageOrientation.toRaw()
resultDict["scale"] = image.scale
resultDict["description"] = image.description
return resultDict
}
Наконец, вы можете попросить сеанс создать задачу, связанную с созданным вами запросом, а затем вызвать resume () длячтобы запустить его в фоновом режиме:
// Create the task, and kick it off
let task = session.dataTaskWithRequest(request!)
task.resume()
Если вы выполните этот процесс сейчас, с вашим собственным URL-адресом requestb.in, вы можете ожидать увидеть результаты, подобные этому:
![enter image description here](https://i.stack.imgur.com/NEoZj.png)