Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

RDSDataSource: Promises

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Promises

YouTube-Videos werden auf SlideShare nicht mehr unterstützt.

Original auf YouTube ansehen

Promises
• Что это?
Wird geladen in …3
×

Hier ansehen

1 von 81 Anzeige

RDSDataSource: Promises

Herunterladen, um offline zu lesen

Михаил Рахманов рассказывает о паттерне Promise и его использовании в iOS разработке.

Краткие тезисы:
- Что такое promises?
- Использование promises в iOS разработке (существующие библиотеки и подходы)
- Реализация promises библиотекой PromiseKit (основные методы, цепочки promises, обработка ошибок)
- Какие задачи можно решить с помощью promises, а какие - нельзя
- Использование promises на примере приложения: драм-машины с возможностью сохранять аудио-дорожки
- Подведение итогов: преимущества и недостатки.

RDSDataSource - внутренние пятничные митапы iOS-команды RAMBLER&Co.

Михаил Рахманов рассказывает о паттерне Promise и его использовании в iOS разработке.

Краткие тезисы:
- Что такое promises?
- Использование promises в iOS разработке (существующие библиотеки и подходы)
- Реализация promises библиотекой PromiseKit (основные методы, цепочки promises, обработка ошибок)
- Какие задачи можно решить с помощью promises, а какие - нельзя
- Использование promises на примере приложения: драм-машины с возможностью сохранять аудио-дорожки
- Подведение итогов: преимущества и недостатки.

RDSDataSource - внутренние пятничные митапы iOS-команды RAMBLER&Co.

Anzeige
Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (16)

Anzeige

Ähnlich wie RDSDataSource: Promises (20)

Weitere von RAMBLER&Co (15)

Anzeige

Aktuellste (20)

RDSDataSource: Promises

  1. 1. Promises
  2. 2. Promises • Что это?
  3. 3. Promises • Что это? • Зачем они нужны?
  4. 4. Promises Метод (GET запрос)
  5. 5. Promises Метод (GET запрос) Promise Контейнер для записи результата метода (или ошибки)
  6. 6. Promises Метод (GET запрос) Promise Контейнер для записи результата метода (или ошибки) Future (результат) Объект, содержащий результат
  7. 7. Promises Метод (GET запрос) Promise Контейнер для записи результата метода (или ошибки) Future (результат) Получатель 2 Получают значение только после выполнения promise Получатель 1 Объект, содержащий результат
  8. 8. Promises Метод (GET запрос) Promise Контейнер для записи результата метода (или ошибки) Future (результат) Получатель 2 Получают значение только после выполнения promise Получатель 1 В некоторых реализациях promise и future - единая сущность Объект, содержащий результат
  9. 9. Цепочка promises RecordPromise
  10. 10. Цепочка promises RecordPromise ExportPromise
  11. 11. Цепочка promises RecordPromise ExportPromise UploadPromise
  12. 12. Цепочка promises RecordPromise ExportPromise UploadPromise Показываем пользователю, что все загрузилось
  13. 13. • promise - контейнер/средство для записи или передачи результата
  14. 14. • future - объект, содержащий результат • promise - контейнер/средство для записи или передачи результата
  15. 15. • future - объект, содержащий результат • promise выполняется только один раз • promise - контейнер/средство для записи или передачи результата
  16. 16. • future - объект, содержащий результат • promise выполняется только один раз • future и promise часто представляют единую сущность (Javascript и PromiseKit в Swift) • promise - контейнер/средство для записи или передачи результата
  17. 17. Состояния promise • выполнено (fulfilled)
  18. 18. Состояния promise • выполнено (fulfilled) • в процессе выполнения (pending)
  19. 19. Состояния promise • выполнено (fulfilled) • ошибка в процессе выполнения (rejected) • в процессе выполнения (pending)
  20. 20. Зачем нужны promises? • Декларативное описание проблемы (что надо сделать, а не как это сделать)
  21. 21. Зачем нужны promises? • Удобно создавать цепочки асинхронных операций • Декларативное описание проблемы (что надо сделать, а не как это сделать)
  22. 22. Зачем нужны promises? • Удобно создавать цепочки асинхронных операций • Декларативное описание проблемы (что надо сделать, а не как это сделать) • Легко обрабатывать ошибки
  23. 23. Краткая иллюстрация
  24. 24. func getAnImageFromServer(url : NSURL) -> Future<UIImage> { let promise = Promise<UIImage>() dispatch_async(...) { // загружаем картинку... let image = UIImage() promise.completeWithSuccess(image) } return promise.future } Краткая иллюстрация
  25. 25. Использование promises в iOS
  26. 26. Библиотеки • PromiseKit (Swift + ObjC) - 5714
  27. 27. Библиотеки • PromiseKit (Swift + ObjC) - 5714 • BrightFutures (Swift) - 1156
  28. 28. Библиотеки • PromiseKit (Swift + ObjC) - 5714 • BrightFutures (Swift) - 1156 • FutureKit (Swift) - 458
  29. 29. PromiseKit
  30. 30. PromiseKit Логика работы - стандарт Promises/A+
  31. 31. Cтандарт Promises/A+ (Javascript) • 3 состояния и логика перехода между ними
  32. 32. Cтандарт Promises/A+ (Javascript) • 3 состояния и логика перехода между ними • логика поведения then
  33. 33. Cтандарт Promises/A+ (Javascript) • 3 состояния и логика перехода между ними • логика поведения then • логика разрешения последующих promises
  34. 34. Создание Promise<T> public init(@noescape resolvers: (fulfill: (T) -> Void, reject: (ErrorType) -> Void) throws -> Void)
  35. 35. Создание Promise<T> public init(@noescape resolvers: (fulfill: (T) -> Void, reject: (ErrorType) -> Void) throws -> Void) let promise = Promise<UIImage> { fulfill, reject in // some async download code here fulfill(image) }
  36. 36. Свойства Promise • fulfilled (Bool)
  37. 37. Свойства Promise • fulfilled (Bool) • pending (Bool)
  38. 38. Свойства Promise • fulfilled (Bool) • pending (Bool) • resolved (Bool)
  39. 39. Свойства Promise • fulfilled (Bool) • pending (Bool) • rejected (Bool) • resolved (Bool)
  40. 40. Свойства Promise • fulfilled (Bool) • value (T?) • pending (Bool) • rejected (Bool) • resolved (Bool)
  41. 41. Свойства Promise • fulfilled (Bool) • value (T?) • pending (Bool) • rejected (Bool) • resolved (Bool) • error (ErrorType)
  42. 42. Основные операторы • when public func when<T>(promises: Promise<T>...) -> Promise<[T]>
  43. 43. Основные операторы • then public func then<U>(on q: dispatch_queue_t = PMKDefaultDispatchQueue(), _ body: (T) throws -> U) -> Promise<U>
  44. 44. Основные операторы • always public func always(on q: dispatch_queue_t = PMKDefaultDispatchQueue(), _ body: () -> Void) -> Promise
  45. 45. Основные операторы • recover public func recover(on q: dispatch_queue_t = PMKDefaultDispatchQueue(), _ body: (ErrorType) throws -> Promise) -> Promise
  46. 46. Основные операторы • error func error(policy policy: ErrorPolicy = .AllErrorsExceptCancellation, _ body: (ErrorType) -> Void)
  47. 47. Основные операторы • race public func race<T>(promises: Promise<T>...) -> Promise<T>
  48. 48. Основные операторы • after public func after(delay: NSTimeInterval) -> Promise<Void>
  49. 49. Категории • MapKit
  50. 50. Категории • MapKit • AVAudioSession
  51. 51. Категории • MapKit • AVAudioSession • NSURLSession
  52. 52. Категории • MapKit • AVAudioSession • NSURLSession • и многие другие библиотеки
  53. 53. Пример firstly { UIApplication.sharedApplication() .networkActivityIndicatorVisible = true }.then { _ -> Promise in let locater = CLLocationManager.promise() return when(locater) }.then { location -> Void in //… }.always { UIApplication.sharedApplication() .networkActivityIndicatorVisible = false }.error { error in //… }
  54. 54. Promises+Delegates • Создаем tuple let (playerPromise, playerFulfill, playerReject) = Promise<Void>.pendingPromise()
  55. 55. Promises+Delegates • Создаем tuple let (playerPromise, playerFulfill, playerReject) = Promise<Void>.pendingPromise() • Возвращаем playerPromise
  56. 56. Promises+Delegates • Создаем tuple let (playerPromise, playerFulfill, playerReject) = Promise<Void>.pendingPromise() • Возвращаем playerPromise • В методе делегата вызываем playerFulfill func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) { playerFulfill() }
  57. 57. Примеры из практики (драм - машина)
  58. 58. Изменение положения девайса Use case No 1 => изменение бита
  59. 59. Изменение положения девайса Use case No 1 => изменение бита
  60. 60. => сохранение на сервер Нажата кнопка «Сохранить» => проигрывание 4х квадратов => преобразование файла Use case No 2
  61. 61. => сохранение на сервер Нажата кнопка «Сохранить» => проигрывание 4х квадратов => преобразование файла Use case No 2
  62. 62. Use case No 2 • на уровне ViewModel
  63. 63. Use case No 2 func didTapRecordButton() { sampler.recordSound().then { data in self.networkClient.uploadFileWithData(data, andName: DADefaultRecordingName) }.error { error in // Обработка ошибки } } • на уровне ViewModel
  64. 64. Use case No 2 • на уровне сервиса AudioEngine
  65. 65. Use case No 2 func recordFrom(start: Promise<Void>, until finish: Promise<Void>) -> Promise<NSData> { return when(start) .then(startRecording) .then { when(finish) } .then(stopRecordingAndExtractAudioFile) .then(export) } • на уровне сервиса AudioEngine
  66. 66. Нажата кнопка «Проиграть» => загрузка случайного бита => остановка секвенсора => проигрывание бита => запуск секвенсора Use case No 3
  67. 67. Нажата кнопка «Проиграть» => загрузка случайного бита => остановка секвенсора => проигрывание бита => запуск секвенсора Use case No 3
  68. 68. Use case No 3 • на уровне ViewModel
  69. 69. Use case No 3 • на уровне ViewModel func didTapPlayRandomFileButton() { networkClient.downloadRandomFile() .then(sampler.playFileFromNSData) }
  70. 70. Use case No 3 • на уровне сервиса NetworkClient
  71. 71. Use case No 3 • на уровне сервиса NetworkClient func downloadRandomFile() -> Promise<NSData> { return firstly(self.allPFObjectsFromServer) .then(self.downloadRandomFileFromPFObjects) }
  72. 72. Use case No 3 • на уровне сервиса AudioEngine
  73. 73. Use case No 3 • на уровне сервиса AudioEngine func playFileFromNSData(data: NSData) -> Promise<Void> { return Promise { fulfill, reject in self.avAudioPlayer = try AVAudioPlayer(data: data) self.avAudioPlayer.delegate = self self.avAudioPlayer.prepareToPlay() self.avAudioPlayer.play() fulfill() }.then { (self.playerPromise, self.playerFulfill, self.playerReject) = Promise<Void>.pendingPromise() return self.playerPromise }
  74. 74. Когда/где стоит использовать promises? • На уровне сервисов/ интерактора
  75. 75. Когда/где стоит использовать promises? • Когда есть цепочка из нескольких асинхронных операций • На уровне сервисов/ интерактора
  76. 76. Когда/где стоит использовать promises? • Когда есть цепочка из некоторых асинхронных операций • На уровне сервисов/ интерактора • Когда требуется понять статус выполнения какой-либо операции
  77. 77. Когда/где стоит использовать promises? • Когда есть цепочка из некоторых асинхронных операций • На уровне сервисов/ интерактора • Когда требуется понять статус выполнения какой-либо операции • Есть много различных ошибок
  78. 78. Когда/где не стоит использовать promises? • На уровне вью (он будет знать о бизнес-логике)
  79. 79. Когда/где не стоит использовать promises? • Когда есть постоянно повторяющиеся действия (например, motion updates) • На уровне вью (он будет знать о бизнес-логике)
  80. 80. Когда/где не стоит использовать promises? • Когда есть постоянно повторяющиеся действия (например, motion updates) • На уровне вью (он будет знать о бизнес-логике) • Когда цепочки операций достаточно маленькие

×