Це справді гарне запитання. Ваш підхід цілком справедливий. Однак Alamofire насправді може допомогти вам ще більше впорядкувати це.
Ваш приклад розподілу черги відправлення коду
У вашому прикладі коду ви переходите між такими чергами відправлення:
- Черга відправлення NSURLSession
- TaskDelegate черга відправлення для перевірки та обробки серіалізатора
- Основна черга відправлення для виклику обробника завершення
- Черга з високим пріоритетом для обробки JSON
- Головна черга відправлення для оновлення інтерфейсу користувача (за необхідності)
Як бачите, ви стрибаєте всюди. Давайте подивимось на альтернативний підхід, що використовує потужну функцію всередині Alamofire.
Черги відправлення відповіді Alamofire
Alamofire має оптимальний підхід, вбудований у власну обробку на низькому рівні. Єдиний response
метод, який в кінцевому підсумку викликається усіма спеціальними серіалізаторами відповідей, має підтримку власної черги відправлення, якщо ви вирішите її використовувати.
Хоча GCD дивовижно перестрибує між чергами відправлення, ви хочете уникнути переходу до черги, яка зайнята (наприклад, основний потік). Усунувши перехід до основного потоку в середині асинхронної обробки, ви можете значно пришвидшити процес. Наступний приклад демонструє, як це зробити за допомогою логіки Alamofire прямо з коробки.
Alamofire 1.x
let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
queue: queue,
serializer: Request.JSONResponseSerializer(options: .AllowFragments),
completionHandler: { _, _, JSON, _ in
println("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
println(JSON)
dispatch_async(dispatch_get_main_queue()) {
println("Am I back on the main thread: \(NSThread.isMainThread())")
}
}
)
Alamofire 3.x (Swift 2.2 та 2.3)
let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
queue: queue,
responseSerializer: Request.JSONResponseSerializer(options: .AllowFragments),
completionHandler: { response in
print("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
print(response.result.value)
dispatch_async(dispatch_get_main_queue()) {
print("Am I back on the main thread: \(NSThread.isMainThread())")
}
}
)
Alamofire 4.x (Свіфт 3)
let queue = DispatchQueue(label: "com.cnoon.response-queue", qos: .utility, attributes: [.concurrent])
Alamofire.request("http://httpbin.org/get", parameters: ["foo": "bar"])
.response(
queue: queue,
responseSerializer: DataRequest.jsonResponseSerializer(),
completionHandler: { response in
print("Parsing JSON on thread: \(Thread.current) is main thread: \(Thread.isMainThread)")
print(response.result.value)
DispatchQueue.main.async {
print("Am I back on the main thread: \(Thread.isMainThread)")
}
}
)
Розбивка черги відправлення Alamofire
Ось розподіл різних черг відправлення, що беруть участь у цьому підході.
- Черга відправлення NSURLSession
- TaskDelegate черга відправлення для перевірки та обробки серіалізатора
- Черга одночасного диспетчерського керування для обробки JSON
- Головна черга відправлення для оновлення інтерфейсу користувача (за необхідності)
Резюме
Усунувши перший стрибок назад до основної черги відправлення, ви усунули потенційне вузьке місце, а також зробили весь запит та обробку асинхронними. Чудово!
З урахуванням сказаного, я не можу підкреслити, наскільки важливо ознайомитись із внутрішніми характеристиками того, як насправді працює Alamofire. Ви ніколи не знаєте, коли ви можете знайти щось, що справді може допомогти вам вдосконалити ваш власний код.
response
методу зараз називається,responseSerializer
а неserializer
(в Alamofire 3.0). Це спричинилоCannot call value of non-function type 'NSHTTPURLResponse?'
помилку, яка мене трохи заплутала.