Задание 4. CS193P Spring 2016. Smashtag Mentions (клиент Twitter). Решение — дополнительные пункты 1-5.

Screen Shot 2016-07-20 at 6.47.01 AM

Содержание

Текст Домашнего Задания 4 на английском языке доступен на  iTunes в пункте “Programming: Project 4: Smashtag Mentions″На русском языке вы можете скачать здесь:

Задание 4 iOS 9.pdf

iOS 9 Задания


Для выполнения Задания 4 необходим материал  Лекции 8 и Лекции 9. Исходное приложение Smashtag L9 находится на сайте Стэнфорда для Xcode 7 и Swift 2.2. Если вы установили Xcode 8, то для Swift 2.3 код находится на Github, а для Swift 3 — также на Github.

Начало решения Задания 4 находится в постах:

CS193P Spring 2016. Smashtag Mentions (клиент Twitter). Решение — обязательные пункты 1- 7.
Задание 4. CS193P Spring 2016. Smashtag Mentions (клиент Twitter). Решение — обязательные пункты 8 — 10.

В данном посте представлено решение Дополнительных пунктов  1 — 5 Задания 4.

Код для Обязательных пунктов 1- 7 находится на Github для Xcode 7 и Swift 2.2.
Код для Обязательных пунктов 1- 10 находится на Github для Xcode 7 и Swift 2.2.
Код для Дополнительных пунктов 1- 5 находится на Github для Xcode 7 и Swift 2.2.

Если вы установили Xcode 8, то для Swift 2.3 код находится на Github, а для Swift 3 — также на Github.

Пункт 1 дополнительный

В секции Users вашего нового UITableViewController представьте список не только  пользователей, users, упомянутых в твите, но также и пользователей users, которые послали твит в первое место.

Мы уже это сделали при инициализации меншенов в классе MentionsTableViewController

Screen Shot 2016-07-19 at 3.56.07 PM

Вначале мы помещаем в массив userItems тех пользователей, которые послали твит в первое место, снабдив их лидирующим знаком «@», затем добавляем тех, кто упомянут в этом твите.
Код можно найти на Github.

Пункт 2 дополнительный

Когда вы кликаете на user в секции Users, ищите не только те твиты, в которых “упоминается” этот user, но и твиты, где это пользователь user посылает твиты.

Используя синтаксис запросов в Twitter, мы изменим строку поиска, которая формируется при выборе элементов секции Users в в классе MentionsTableViewController в методе prepareForSegue

Screen Shot 2016-07-19 at 4.00.54 PM
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
В результате получаем желаемый результат

Screen Shot 2016-07-19 at 4.06.27 PM

Код можно найти на Github.

Пункт 3 дополнительный

Пользовательский интерфейс (UI) вашего приложения может проникать очень глубоко в стэк UINavigationController (когда вы “преследуете” меншены все дальше и дальше). Добавьте некоторый элемент UI, который позволил бы пользователю в любое время “сбросить” весь стэк до корневого rootViewController вашего UINavigationController.

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

Screen Shot 2016-07-19 at 11.32.52 AM

Для того, чтобы добавить кнопку Stop, нужно вытянуть из Палитры Объектов кнопку Bar Button Item (это не обычная кнопка UIButton,  а именно панельная кнопка UIBarButtonItem) и добавить ее на навигационную панель:

Screen Shot 2016-07-19 at 5.36.10 PM

Панельная кнопка Stop — системная кнопка и нам больше ничего не нужно делать с ее внешним видом, но может быть и пользовательская.
Теперь создадим Action  для этой кнопки с помощью CTRL-перетягивания от кнопки в код и называем его toRootViewController:

Screen Shot 2016-07-19 at 5.47.45 PM

Это очень простой  Action — он возвращает нас в корневой View Controller:

Screen Shot 2016-07-19 at 5.51.34 PM

Надо заметить, что на схеме, представленной в самом начале этого дополнительного пункта, выделен экранный фрагмент TweetTableViewController, который из-за петель, образованных segues, может выступать как в роли корневого View Controller, так и участника «преследования меншенов«. Пользовательский интерфейс (UI), относящийся к “сбросу стэка” (“pop back”), очевидно, не должен появляться, когда вы находитесь на  корневом View Controller.
Поэтому для  TweetTableViewController мы создаем кнопку Stop в коде в зависимости от обстоятельств:

screen-shot-2016-09-12-at-7-12-23-am

Все кнопки Stop в других Controller «подвязываем» к аналогичным Action toRootViewController.
Есть соблазн поместить код «появления» кнопки Stop в viewDidload, но там он работать не будет, так как свойство navigationController в методе viewDidLoad равно nil. До тех пор, пока вы не сработало push для UIViewController, его свойство navigationController будет nil, а метод viewDidLoad всегда вызывается ПЕРЕД push. Так что в методе viewDidLoad свойство navigationController не определено и равно nil.
К тому времени, когда вызываются методы viewWillAppear и viewDidAppear, push прошел, navigationController определен и не nil, так что navigationController?.viewControllers.count будет считаться правильно.
Запускаем — все работает. Вы видите. что на стартовом экране кнопки Stop НЕТ, а на экранах, которые появились в результате «погони за меншенами» кнопка Stop появилась.

Screen Shot 2016-07-19 at 6.06.42 PM

Если появятся новые Controller мы будем поступать точно также.
Код можно найти на Github.

Пункт 4 дополнительный

Вместо открытия urls в Safari, покажите их в вашем приложении путем “переезда” ( segueing) на Сontroller с UIWebView. Вам понадобиться обеспечить по крайней мере простейшее “управление браузером” с помощью элементов UI, которые приходят вместе с UIWebView (например, кнопка “назад” (“back button”)). Помните, что UINavigationController может показывать кнопки внизу с помощью метода toolbarItems во вставленном (embedded) MVC..

С помощью UIWebView мы сможем, во-первых, менять внешний облик возвратной кнопки, а, во-вторых» вмешиваться с помощью делегата в сам процесс загрузки web страницы, например, добавляя индикатор активности в виде маленького «вращающегося колесика».
Итак, приступим. Добавляем из палитры объектов новый View Controller на storyboard. Добавляем также из палитры объектов Web View и Activity Indicator View на новый View Controller и устанавливаем необходимые ограничения с помощью механизма Autolayout. А также кнопку Stop на навигационную панель для возврата на корневой экранный фрагмент

Screen Shot 2016-07-19 at 9.08.39 PM

Добавляем segue от Mentions к Web View (заметьте, что НЕ ОТ cell, а ОТ самого View Controller) с идентификатором «Show URL«.

Screen Shot 2016-07-19 at 9.28.44 PM

Создаем новый класс WebViewController для нового Web View и не забываем его установить в Инспекторе Идентичности.

Screen Shot 2015-07-11 at 8.04.25 PM

Добавляем outlets для Web View и Activity Indicator.

Screen Shot 2016-07-19 at 9.33.00 PM

Как только outlets webView установлен, загружаем web страницу с заданным URL, который является  Public API для этого класса :

Screen Shot 2016-07-19 at 9.39.13 PM

Кроме того, мы добавили на навигационную панель слева пользовательскую кнопку back для возврата на предыдущую web страницу, предварительно загрузив для нее иконку:

Screen Shot 2016-07-20 at 5.57.24 AM

Кнопка будет возвращать нас на предыдущую web страницу:

Screen Shot 2016-07-20 at 6.00.45 AM

Делаем так, чтобы наш новый класс подтверждал протокол UIWebViewDelegate и делаем его делегатом Web View, чтобы использовать его методы для старта и завершения загрузки web страницы.

Screen Shot 2016-07-20 at 6.10.58 AM

Мы используем методы делегата для запуска и остановки как индикатора активности, расположенного в центре экрана, так и для сетевого индикатора на статусной панели.
В классе MentionsTableViewController, обслуживающем таблицу меншенов, мы вместо вызова Safari выполняем метод performSegueWithIdentifier

Screen Shot 2016-07-20 at 6.19.37 AM

В структуру Storyboard добавляем константу для идентификатора segue для Web View Controller:

Screen Shot 2015-07-11 at 8.54.46 PM

Запускаем приложение и получаем замечательный результат.

Screen Shot 2016-07-20 at 6.47.01 AM

Код можно найти на Github.

Пункт 5 дополнительный

Сделайте таблицу с “недавними поисковыми терминами” редактируемой (то есть позвольте пользователю использовать жест Swipe влево для удаления терминов, которые ему не нравятся).

В классе RecentsTableViewController реализуем метод делегата Table View, поддерживающий редактирование таблицы

Screen Shot 2016-07-20 at 6.55.47 AM

Вначале удаляем строку из Модели, а затем непосредственно из таблицы. Модель, структура RecentSearches  поддерживает удаление элемента с заданным индексом

Screen Shot 2016-07-20 at 6.59.25 AM

В результате получаем возможность удалять строки из таблицы с “недавними поисковыми терминами”.

Screen Shot 2016-07-20 at 7.05.39 AM

Код можно найти на Github.
Продолжение следует…