Мобильные приложения и просмотр контента в сети сейчас повсеместно распространены. В течение многих лет разработчикам iOS было поручено либо создать собственный опыт просмотра веб-страниц внутри своего приложения, либо передать URL-адрес Safari. Оба этих подхода имеют недостатки, которые ранее были неизбежны.
Это все изменилось с iOS 9 и введением класса SFSafariViewController
. С его помощью вы теперь можете обеспечить полноценный просмотр веб-страниц внутри своего приложения, не тратя на это значительное время разработки.
1. Демонстрационный обзор
Прежде чем мы начнем, я собираюсь изложить подход, который я использовал с демонстрационным приложением, которое идет вместе с этим руководством. Как вы увидите позже, с использованием контроллера представления Safari на самом деле не так много кода. Настоящая ценность контроллера представления Safari заключается в понимании того, когда его использовать, и, что более важно, почему .
Параметры для отображения веб-контента
Начиная с iOS 9, у разработчиков есть три варианта отображения веб-контента для пользователя:
- Safari: используйте
openURL(_:)
чтобы показать страницу внутри safari, заставив пользователя покинуть ваше приложение. - Пользовательский опыт просмотра: вы можете использовать
WKWebView
илиUIWebView
чтобы создать опыт просмотра с нуля. -
SFSafariViewController
: СSFSafariViewController
вы можете использовать практически все преимущества просмотра веб-контента в Safari, не заставляя пользователей покидать ваше приложение.
До iOS 9 первые два варианта были единственными вариантами для разработчиков. Знание того, когда вам нужно было использовать один или другой, зависело от контекста представленного контента. Работая над демо-приложением, мы собираемся использовать все три варианта.
Теперь, когда мы знаем, как может отображаться контент, давайте рассмотрим, почему он может отображаться в приложении. На iOS есть два основных варианта использования для просмотра веб-контента.
- Пользовательский веб-контент: это контент, не предназначенный для просмотра. Это может быть отчет или нечто подобное, сгенерированное из API или сервера. Здесь пользователь просматривает один фрагмент контента и больше ничего не делает.
- Просмотр веб-сайтов: это наиболее распространенный сценарий. Пользователь должен на мгновение просматривать веб-страницы, чтобы войти в службу или перейти на веб-сайт.
Также имейте в виду, что существует третий вариант использования, веб-аутентификация. В этом уроке мы не будем фокусироваться на этом сценарии.
Пользовательский веб-контент
Если степень использования веб-интерфейса вашего пользователя внутри вашего приложения попадает в первый вариант использования, контроллер представления Safari, вероятно, не то, что вам нужно. В этих случаях вы отображаете контент, которым вы владеете и которым управляете, и вам может потребоваться его обширная настройка.
Если вы обнаружите, что ваше приложение подходит к этому сценарию, используйте WKWebView
. Это преемник UIWebView
и включает в себя несколько улучшений, таких как использование движка Nitro JavaScript . Такой подход позволяет создать весь пользовательский интерфейс с нуля. У вас также есть другие возможности, такие как безопасная загрузка файлов и использование WKWebsiteDataStore
для запросов файлов cookie.
Просмотр сайтов
Тем не менее, большинство приложений просто должны обеспечивать общий просмотр веб-страниц. Это идеальный сценарий для контроллера Safari View. До выхода iOS 9 разработчики тратили время на создание собственного пользовательского интерфейса для просмотра веб-страниц, что может привести к проблемам для пользователей.
Работа в разных приложениях несовместима, что может сбить пользователя с толку. В некоторых интерфейсах также может отсутствовать то, чего ожидают пользователи, например индикатор выполнения, показывающий, сколько страниц загружено.
Кроме того, у вас нет доступа ко всем функциям Safari. Это включает в себя представление читателя, цепочку ключей iCloud для возможностей автозаполнения и многое другое. Если вы хотели использовать эти функции до iOS 9, вы были вынуждены заставить пользователя полностью покинуть ваше приложение, открыв его содержимое в Safari. Класс SFSafariViewController
решает все эти проблемы.
2. Запустите демо-приложение
Для начала соберите и запустите демонстрационное приложение. Вам будет представлен очень минимальный пользовательский интерфейс с тремя вариантами. Каждый параметр соответствует одному из методов, упомянутых ранее, для представления веб-контента.
3. Открытие контента в Safari
Первый вариант, который мы продемонстрируем, — это более традиционный маршрут, который передает URL-адрес Safari. Откройте ViewController.swift и обратите внимание на свойство urlString
в верхней части файла. Это определит то, что представлено в следующих примерах, поэтому не стесняйтесь устанавливать все, что вы пожелаете.
1
|
private var urlString:String = «https://google.com»
|
Важно отметить, что в iOS 9 TLS 1.2 применяется по умолчанию. Если сервер, к которому вы пытаетесь подключиться, не поддерживает это, вы можете увидеть следующую ошибку в консоли:
Есть способы обойти это, например, добавить ключ в файл Info.plist вашего приложения. Это было изменение, сделанное Apple для повышения безопасности при просмотре веб-страниц. Двигаясь дальше, добавьте следующий код в действие openInSafari(_:)
:
1
2
3
4
5
|
@IBAction func openInSafari(sender: AnyObject)
{
let url = NSURL(string: self.urlString)!
UIApplication.sharedApplication().openURL(url)
}
|
Создайте и запустите приложение. Когда вы нажимаете верхнюю кнопку «Открыть в Safari», операционная система покидает ваше приложение и открывает URL-адрес в Safari.
Хотя эта опция, безусловно, жизнеспособна, мы заставили пользователя покинуть наше приложение. Как разработчики, в идеале мы хотим, чтобы опыт оставался внутри нашего приложения. Одно из улучшений, которое iOS 9 сделала с этим подходом, это небольшая кнопка возврата в верхнем левом углу:
Нажатие на эту кнопку вернет пользователя в приложение, которое передало URL-адрес Safari. Чтобы решить проблему с тем, что пользователь был вынужден покинуть наше приложение, давайте перейдем к следующему подходу.
4. Открытие контента в Webkit или WebView
Теперь мы откроем тот же URL внутри нашего приложения. Для этого мы будем использовать встроенный UIWebView
. Логика для этого простого веб-браузера находится в классе CustomWebViewController
.
Поскольку нам не нужны какие-либо расширенные функции WebKit, мы просто откроем страницу в веб-представлении. В классе ViewController замените код в prepareForSegue(_:sender:)
следующим образом:
1
2
3
4
5
6
7
8
|
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if let navVC = segue.destinationViewController as?
{
let cwvc = navVC.topViewController as!
cwvc.urlString = self.urlString
}
}
|
Идите вперед и запустите приложение. Нажмите среднюю кнопку «Открыть с помощью веб-просмотра», и страница должна загрузиться внутри приложения.
Несмотря на то, что пользователь остается в приложении, недостатки этого подхода очевидны. Без наших дополнительных усилий по разработке с нашей стороны не будет индикации загрузки, адресной строки и других вещей, ожидаемых пользователями при просмотре веб-страниц. Давайте теперь используем класс SFSafariViewController
для решения этих проблем.
5. Открытие содержимого в Safari View Controller
Прежде чем мы сможем использовать класс SFSafariViewController
, нам нужно импортировать Safari Services . В верхней части ViewController.swift добавьте следующий оператор импорта под оператором импорта для UIKit:
1
|
import SafariServices
|
Затем обновите реализацию openWithSafariVC(_:)
как показано ниже:
1
2
3
4
5
|
@IBAction func openWithSafariVC(sender: AnyObject)
{
let svc = SFSafariViewController(URL: NSURL(string: self.urlString)!)
self.presentViewController(svc, animated: true, completion: nil)
}
|
Запустите приложение и коснитесь нижней кнопки «Открыть с помощью контроллера представления SFSafariViewController
», чтобы увидеть содержимое, которое теперь отображается внутри экземпляра SFSafariViewController
.
Теперь мы позволили пользователю оставаться внутри нашего приложения, и у него есть все преимущества Safari. Общие листы доступны на панели вкладок вместе с возможностью добавить страницу в избранное или открыть содержимое в Safari.
Есть ряд интересных конфигураций, которыми можно воспользоваться. Например, мы могли бы позволить пользователю легко запустить браузер в режиме чтения, передав true
в entersReaderIfAvailable
.
1
2
3
4
5
|
@IBAction func openWithSafariVC(sender: AnyObject)
{
let svc = SFSafariViewController(URL: NSURL(string: self.urlString)!, entersReaderIfAvailable: true)
self.presentViewController(svc, animated: true, completion: nil)
}
|
Кроме того, контроллер представления Safari учитывает цвет оттенка. Это облегчает сохранение фирменного стиля вашего приложения при сохранении привычного пользовательского интерфейса Safari.
Однако одна проблема, которую нам нужно решить, заключается в том, что пользователь в настоящее время не может закрыть контроллер представления. Давайте исправим это сейчас.
6. Протокол SFSafariViewControllerDelegate
Чтобы отклонить контроллер представления, нам нужно соответствовать протоколу SFSafariViewControllerDelegate
. Откройте ViewController.swift и ViewController
класс ViewController
соответствие с протоколом SFSafariViewControllerDelegate
.
1
2
3
4
|
class ViewController: UIViewController, SFSafariViewControllerDelegate
{
…
}
|
Затем добавьте следующий метод делегата в класс ViewController
:
1
2
3
4
|
func safariViewControllerDidFinish(controller: SFSafariViewController)
{
controller.dismissViewControllerAnimated(true, completion: nil)
}
|
Этот метод делегата вызывается, когда пользователь нажимает кнопку « Готово» в контроллере представления Safari. Он должен использоваться, чтобы закрыть контроллер представления и вернуться в ваше приложение.
Осталось только назначить наш контроллер представления делегатом контроллера представления Safari. Обновите реализацию метода openWithSafariVC(_:)
как показано ниже:
1
2
3
4
5
6
|
@IBAction func openWithSafariVC(sender: AnyObject)
{
let svc = SFSafariViewController(URL: NSURL(string: self.urlString)!)
svc.delegate = self
self.presentViewController(svc, animated: true, completion: nil)
}
|
Если вы запустите приложение и откроете контроллер представления Safari, вы увидите, что теперь вы можете закрыть контроллер представления Safari, нажав кнопку « Готово» в правом верхнем углу.
Вывод
Контроллер Safari View невероятно прост в использовании. Фактически, это один из самых маленьких API, которые я видел только с двумя инициализаторами и двумя методами делегатов. Несмотря на это, он предоставляет все функции, которые пользователи ожидают от Safari, для вашего приложения.
Возможно, еще более увлекательно то, что разработчикам больше не придется тратить время на создание пользовательских веб-браузеров. Для первоклассного просмотра веб-страниц в вашем приложении требуется несколько строк кода с классом SFSafariViewController
.