Калькулятор

+7 (499) 350-07-79

Чего ждать iOS-разработчикам: итоги Apple WWDC 2017

10.08.2017

3328


Эта заметка писалась по итогам Всемирной конференции разработчиков WWDC. В ней представлена выжимка значимых обновлений для iOS, с примерами кодов. Мы вынесли за скобки другие новинки и заметные изменения: смарт-динамик HomePod, обновление процессоров, клавиатуры, и прочее. Обо всем этом и так достаточно публикаций в отраслевой прессе.  

apple wwdc 2017

  1. К этой заметке прилагаются коды, для чего на вашем Mac должна быть установлена последняя версия операционной системы (не бета High Sierra, которая появится осенью).
  2. Скачайте Xcode 9 (нужен бесплатный аккаунт разработчика)
  3. Перейдите на тот же веб-сайт и установите iOS 11 Beta Configuration Profile . Так вы загрузите iOS 11 Beta и установите через обычный механизм обновления iOS.

разработка мобильных приложений

iOS Cocoa Touch и системные обновления

Одно из главных обновлений для облегчающих создание приложений для iOS drag and drop . Теперь в iOS присутствует встроенная поддержка этой функции: мультивыбор, анимация по умолчанию и стандартные взаимодействия. На iPad «перетаскивание» работает между разными приложениями. Кому-то это покажется излишним, но ведь и возможность копипаста появилась только с выходом iPhone OS 3.

Еще одно новшество — файловая система. Теперь документы можно просматривать в отдельном приложении Files app.

Drag and Drop

Реализована новая система взаимодействий drag-and-drop: в любой вид добавляется UIDragInteraction, затем реализуются соответствующие делегаты. В месте переноса также должны быть реализованы делегаты для приема данных.

На iPad элементы можно переносить из одного приложения в другое, но drag and drop на iPhone работает только для файлов какого-то одного приложения.

Интересный нюанс: если вид уже «знает», как принимать скопированные данные, элементы такого же типа будут приниматься автоматически.

UITextView автоматически принимает текст, и не нужно добавлять в приложение что-либо еще.

Брюс Найло, один из технических директоров по UIKit наглядно продемонстрировал, как это работает:

ссылка на видео

Вы также можете скачать demo app .

Ссылка на сервис vimeo.com

В фотоальбоме drag and drop используется чтобы:

  • Упорядочить фотографии,
  • Переместить одно фото в другой альбом,
  • Переместить все фотографии альбома в другой альбом
  • Скопировать изображения между приложением и другими альбомами.
  • Главное, на что стоит обратить внимание, — PhotoCollectionViewController.swift

В том же приложении (которое вы можете скачать):

  • UIViewController с коллекцией элементов (collection view) должен реализовать
  • UICollectionViewDragDelegate , чтобы перетянуть (drag) и
  • UICollectionViewDropDelegate , чтобы бросить (drop).

class PhotoCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDragDelegate, UICollectionViewDropDelegate {

Дальше нужно определить делегаты drag and drop для self в viewDidLoad.

collectionView?.dragDelegate = self

collectionView?.dropDelegate = self

Единственный требующийся метод протокола делегатов для drop создает массив UIDragItem, когда начнется перетаскивание. Элемент, который перетаскивается, содержит данные.

func collectionView(_ collectionView: UICollectionView, itemsForBeginning

session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {

let dragItem = self.dragItem(forPhotoAt: indexPath)

return [dragItem]

}

Что касается drop, вам нужно уточнить, возможно ли принимать данные:

func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool {

    guard album != nil else { return false }

   return session.hasItemsConforming(

       toTypeIdentifiers: UIImage.readableTypeIdentifiersForItemProvider)

}

В данном случае return true, если переносимый элемент можно превратить в изображение. При drop нужно скопировать и переместить фотографии в коллекцию элементов (collection view).

func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {

  guard album != nil else { return }

  let destinationIndexPath = coordinator.destinationIndexPath ?? IndexPath(item: 0, section: 0)

  switch coordinator.proposal.operation {

  case .copy:

      // Receiving items from another app.

      loadAndInsertItems(at: destinationIndexPath, with: coordinator)

  case .move:

      move(items: coordinator.items, with: coordinator)

  default: return

  }

}

Другие обновления Cocoa Touch

Если ваше iOS-приложение доступно и в качестве веб-приложения, у вас в распоряжении будут учетные данные пользователей, по которым они логинятся в приложение автоматически.

Для поддержки функций, которые были до iOS 11 (например, универсальные ссылки), у вас, вероятно, уже есть файл apple-app-site-association, чтобы связать веб-сайт и приложение (если нет, необходимо это сделать). Все, что нужно как дополнение, это установить тип контента имени пользователя и пароля UITextFields как .username и .password, соответственно.
self.userNameField.textContentType = .username

self.passwordField.textContentType = .password
Затем при появлении экрана для ввода данных iOS предложит вписать сохраненные данные пользователя.

мобильные приложения 2017

Автозаполнение пароля

Более подробно об этом в Introducing Password AutoFill for Apps .

Новое приложение Files дает возможность просмотра файлов. Но если для разработки приложений для iOS , нужны файлы из других приложений, можно выбрать вид для выбора документов (document-picker view), аналогично тому, как использовался нужный вид для выбора изображений.

let docs =

UIDocumentBrowserViewController(forOpeningFilesWithContentTypes: [kUTTypePDF])

docs.delegate = self // implement UIDocumentBrowserViewControllerDelegate

self.present(docs, animated: true)

Чтобы обработать выбранный документ, используйте метод протокола UIDocumentBrowserViewControllerDelegate

Этот аспект подробно освещался во время сессии File Provider Enhancements.

Swift

Swift 4 — язык программирования с открытым исходным кодом. Детали можно просмотреть в GitHub. На конференции WWDC Apple представила новую особенность — протокол Codable, который позволяет кодировать структуру посредством классов NSCoding.

Все, что нужно сделать, согласиться с протоколом Codable, и Swift реализует это по умолчанию:

struct WWDCVideo : Codable {

  let title: String

  let presenters: [String]

  let videoURL: URL

}

Добавится автоматическая поддержка JSON.

Кодированная структура выглядит примерно так:

let swiftVideo = WWDCVideo(

     title: «What’s New in Swift»,

     presenters: [

         «Doug Gregor»,

         «Bob Wilson»,

         «Ben Cohen»,

         «John McCall»,

     ],

     videoURL: URL(string: «https://developer.apple.com/videos/play/wwdc2017/402/»)!

)

let jsonData = try JSONEncoder().encode(swiftVideo)

Раскодирование:

let vid = try JSONDecoder().decode(WWDCVideo.self, from: jsonData)

Также Codable поддерживает специальное кодирование и раскодирование, если это требуется, есть простой способ сделать простые альтерации (CodingKeys).

Больше об этом по ссылке What’s New in Swift .

Core ML

Одна из презентаций WWDC была посвящена вопросу о том, как Apple использует машинное обучение (ML) в системах и приложениях.

Siri watchface стал первым примером, но представители Apple анонсировали множество функций, в основе которых ML, в том числе и CoreML, новый фреймворк, который реализует фазу прогона ML-моделей, таких как нейронные сети.

На самом высоком уровне машинное обучение используется для реализации функций, которые отображают входные данные в выходной информации. Маппинг задается не напрямую, система этому «обучается» по образцам данных. В iOS машинное обучение используется для идентификации по чертам лица, OCR, распознавания рукописного текста, автоматического ввода текста, Siri и много другого.

CoreML задает спецификации файла специальной модели машинного обучения. Этот файл создается заранее с помощью обучающего ПО, чтобы задать множество примеров входной информации и получить ожидаемый результат на выходе. По прошествии времени софт может предсказывать выходные данные для новых входных значений. Можно сделать экспорт такого «понимания», чтобы моделировать файлы уже в других программах.

Файл модели помещается в проект Xcode, создается класс Swift, чтобы представить простую функцию, которая используется для управления моделью по входным значениям.

Примером входных значений служит фотография, а результат на выходе — прямоугольное пространство на фото.

Примерно так:

let kittenFinder = KittenFinder()

let r: CGRect = kittenFinder.findKitten(image: imageView.image)

Точный интерфейс генерируется из файла модели.

К примеру, моделям, в основе которых изображения, обычно необходим специфический размер и пиксельный формат (цвет или шкала уровней серого). CoreML автоматически превращает любое изображение, которое вы отправите, в то, что нужно для модели (поддерживаются все способы репрезентации изображений в iOS).

Модель проста в использовании. Разработчики могут создавать такие модели (это как упражнение для разработчика), существует и множество открытых моделей, у Apple также имеется ряд готовых моделей для приложений. Есть открытая библиотека Python , которая помогает конвертировать форматы. Судя по всему, ML-сообщество в ближайшее время разработает еще больше моделей в таком формате.

Больше информации по ссылке: Introducing Core ML .

Но Apple этого было мало. В довершение всего разработчики компании написали еще два фреймворка, которые упрощают некоторые простые задачи. Фреймворк Vision предназначен для распознавания объектов в потоковом видео, автоматически считывает изображения с помощью объекта AVCaptureSession. Разрабатываются другие модели, например более точный детектор лиц, который фиксирует детали лица (глаза, нос, рот).

Пока еще нет примера приложения или документации для распознавания лиц, но все-таки из представленного на конференции во время сессии Vision удалось кое-что собрать: GitHub .

В типичном приложении с объектом AVCaptureSession добавьте импорт Vision в свой View Controller.

import Vision

Добавьте свойство, чтобы создать запрос на распознавание лиц.

var requests: [VNDetectFaceRectanglesRequest] = []

Инициализируйте в этой функции, которая вызывается в viewDidLoad:

func setupVision() {

  let faceDetectionRequest = VNDetectFaceRectanglesRequest(completionHandler: self.handleFaces)

  self.requests = [faceDetectionRequest];

}

В реализации captureOutput добавьте код:

guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

// Make the Face Detection Request

var requestOptions: [VNImageOption: Any] = [:]

if let cameraIntrinsicData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {

   requestOptions = [.cameraIntrinsics: cameraIntrinsicData]

}

// The orientation should be determined from the phone position, but assume portrait (1) for now

let imageRequestHandler =

   VNImageRequestHandler(cvPixelBuffer:imageBuffer, orientation: 1, options: requestOptions)

do {

    try imageRequestHandler.perform(self.requests)

} catch {

    // handle this

}

После идентификации лица будет вызвана функция:

func handleFaces(request: VNRequest, error: Error?) {

       DispatchQueue.main.async {

           self.hideFaceBox()

           guard let result = (request.results as? [VNFaceObservation])?.first else { return }

           let bb = result.boundingBox

           if let imgFrame = self.imageView?.frame {

               // Bounding Box is a 0..<1.0 normlized to the size of the input image and

               // the origin is at the bottom left of the image (so Y needs to be flipped)

               let faceSize = CGSize(width: bb.width * imgFrame.width, height: bb.height * imgFrame.height)

               self.drawFaceBox(frame:

                   CGRect(x: imgFrame.origin.x + bb.origin.x * imgFrame.width,

                          y: imgFrame.origin.y + imgFrame.height — (bb.origin.y * imgFrame.height) — faceSize.height,

                          width: faceSize.width,

                          height: faceSize.height)

               )

           }

       }

}

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

Приложение доступно на GitHub .

Этот девайс направлен на экран компьютера и фиксирует лицо Тима Кука:

Ссылка на сервис vimeo.com

Боле подробно об этом по ссылке Vision Framework: Building on CoreML и в документации Vision .

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

Подробно в презентации Natural Language Processing and Your Apps .

Дополненная реальность

Еще одной новостью во время WWDC стал ARKit, новый фреймворк, который открывает для приложений возможности технологии дополненной реальности. Если вам приходилось создавать какой-то контент, используя SceneKit (для 3D-игр) или SpriteKit (для 2D), тогда вы оцените преимущества ARKit.

В Xcode сейчас присутствует шаблон приложения для дополненной реальности:

мобильные приложения ios

AR-шаблон в Xcode

После выбора этого шаблона на следующем экране вам понадобится выбрать контентную технологию (SceneKit, SpriteKit or Metal). Выберите SceneKit, и приложение будет готово к запуску.

Код, который установлен по умолчанию, позволяет видеть космический корабль. Добавлять 3D-модели очень просто.

Сделайте импорт одной из них и обновите эту линию:

let scene = SCNScene(named: «art.scnassets/ship.scn»)!

sceneView.scene = scene

Вы можете добавить 3D-геометрию с помощью различных узлов SceneKit.

Например, замените две верхние линии этим:

self.sceneView.autoenablesDefaultLighting = true

let scene = SCNScene()

let sphereNodes = SCNNode()

scene.rootNode.addChildNode(sphereNodes)

addSphere(to: sphereNodes, pos: SCNVector3Make(0, 0, -2.0))

addSphere(to: sphereNodes, pos: SCNVector3Make(-0.3, 0.2, -2.4))

addSphere(to: sphereNodes, pos: SCNVector3Make(0.3, 0.2, -2.8))

AR-шаблон отключает стандартное освещение, но нужно, чтобы сферы зажигались таким же светом, как и освещение видеоряда, которое ARKit фиксирует. Все координаты в пределах одного метра действительного пространства.

Эта функция создает и добавляет сферы на экран:

func addSphere(to node: SCNNode, pos: SCNVector3) {

  let sphere = SCNSphere(radius: 0.1)

  let sphereNode = SCNNode(geometry: sphere)

  sphereNode.position = pos

  node.addChildNode(sphereNode)

}

Во время запуска сферы будут выглядеть примерно так:

Ссылка на сервис vimeo.com

Больше подробностей по ссылке Introducing ARKit: Augmented Reality for iOS и в документации по ARKit .

Итог

Xcode 9 существенно изменился по сравнению с Xcode 8.2 : полностью обновленный редактор, поддержка рефакторинга в Swift. Можно запускать множество эмуляторов, доступна столь необходимая функция отладки по Wi-Fi, поддержка языков с письмом справа налево и динамический тип размеров.

У Swift Playgrounds два обновления. Одно вы можете загрузить сейчас, но также есть бета-версия 2.0 в TestFlight . Новая версия позволяет экспериментировать со всеми функциями iOS 11, такими как ARKit и Swift 4.

В сентябре ожидается релиз всего этого, наряду с очередным iPhone. В общем, просматривайте видеоролики и готовьте свои приложения к iOS 11.

    Подпишись на рассылку

    Расскажите про свой проект

    Pуcтам Myxамедьянов

    Руководитель студии

    Имя

    Компания

    E-mail

    Телефон

    Сообщение

    Планируемый бюджет

    ₽ 500 000

    ₽ 1 500 000

    ₽ 2 500 000

    Для отправки нажмите чекбокс с условиями