Как создать NSNumberFormatter Singleton в Swift (1.2 и 1.1) — дополнение к Заданию 2

Мне было необходимо использовать класс NSNumberFormatter для изменения вида представления числа в  моем  CalculatorBrain в Задании 2 стэнфордского курса «Разработка iOS 8 приложений на Swift. Winter 2015», например, с 2324.00 на 2 324 без десятичных знаков, то есть придать универсальному NSNumberFormatter некоторую нужную мне конфигурацию. Из-за того, что инициализация NSNumberFormatter может быть экстремально дорогой операцией в iOS, способной «поставить на колени» отдельные приложения, не хотелось бы, чтобы производительность приложения зависела от этого, особенно если используется одна и та же конфигурацию  NSNumberFormatter всюду в моем приложении. Будем использовать Singleton ( синглтон ) — ровно один экземпляр некоторого класса, глобально  доступный всем клиентам.

Singleton (синглтон) — это популярный паттерн (шаблон ) проектирования. Если вы новичок в Swift, вам будет интересно, как можно в Swift создать Singleton. В Objective-C, возможно, вы уже пробовали для создания синглтона dispatch_once из Grand Central Dispatch.

В настоящее время существует прекрасный пост в  stack overflow, в котором рассматриваются все пути создания Singleton в Swift, хотя этот пост не снабжен каким-то «глубоким» практическим примером. Класс  NSNumberFormatter широко используется и пример использования Singletons в классе  NSNumberFormatter будет очень полезен.

Читать далее

Дополнение к Лекции 7: Изменение адаптивности Popover в iOS 8.3

Эта тема важна для Лекции 7, в которой рассматривается Popover для iPhone и iPad, и для демонстрационного примера «Psychologist Popover«, который доступен на сайте  Stanford. Этот демонстрационный пример в части Popover  на iPhone будет работать в iOS 8.3 не так, как планировалось. Вариант исправленного демонстрационного примера «Psychologist Popover« для iOS 8.3 доступен на  Github. Ниже дается пояснение проблемы.

Адаптивность до  iOS 8.3

Само по себе Popover — не UIViewController. Он появляется на экране, используя так называемый механизм Presentation Controller. Popover на iPad “всплывает” так, как вы видели на рисунке выше для iOS 8.2. В виде маленького окошка со стрелкой. На iPhone Popover адаптируется и превращается вместо маленького окошка в модальное окно на полный экран. Оно не “всплывает” как что-то маленькое на iPhone. Что касается iPhone 6 Plus, то в портретном режиме он ведет себя как iPhone ( модальное окно на весь экран), а в ландшафтном режиме как iPad ( маленькое «всплывающее» окно). Такая Адаптация делается автоматически. iOS 8 автоматически делает эту адаптацию также, как автоматически адаптируется Split View и Navigation Controller для iPhone.
Перед iOS 8.3, Адаптивность Popover работала, когда горизонтальный size class изменяется от Regular к Compact.

Читать далее

Вышла версия Swift 1.2 : долгожданные изменения.

Screen Shot 2015-04-12 at 10.28.29 AM

;

 

Версия Swift 1.2.принесла очень существенные и долгожданные изменения языка Swift :

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

— улучшенные сообщения об ошибках и повышение стабильности в Xcode

— “static” методы и свойства ( properties) теперь разрешены в classes (как псевдоним для “class final”). Теперь вам разрешается декларировать как «static» хранимые свойства (stored properties) в  classes, которые сохраняются глобально и  lazily инициализируются при первом доступе (то есть как глобальные переменные).

Screen Shot 2015-04-13 at 4.00.39 PM
Теперь очень легко создавать Singletons — буквально одной строкой кода.

Screen Shot 2015-04-18 at 5.13.34 PM

— в протоколах (Protocols) теперь требуется декларировать тип как “static” вместо “class

— появился новый тип  Set, который является взаимозаменяемым (bridging) с Objective-C классом  NSSet, также, как и  String, Array и Dictionary — взаимозаменяемы ( bridging) с их соответствующими  Objective-C классами. Вы можете делать с Set в Swift все, что вы ожидаете делать с множествами вообще: проверять принадлежность значения к множеству, перечислять все элементы множества, выполнять операции union и intersect и т.д. Это существенное дополнения в стандартную библиотеку, которое закрыло огромную абстрактную «дыру», так как   NSSet не чувствовал себя комфортно в Swift

Screen Shot 2015-04-12 at 4.45.14 PM
Screen Shot 2015-04-12 at 4.52.51 PMЖдем того же от  NSDate и других.

— изменен глобальный метод countElements на count

-приоритет (precedence) оператора ?? повышен, чтобы привязать его более жестко, чем логические операции и операции сравнения, но ниже, чем преобразование и операторы диапазона ( range). Это обеспечивает более полезное поведение выражений подобных этому:

Screen Shot 2015-04-13 at 4.03.09 PM

Читать далее

Лекция 7 CS193P Winter 2015 — Множественные MVC (Split View, Tab Bar, Navigation Controller и Popover)

Лекция 7 продолжает тему множественных MVC, начатую в конце лекции 6. Очень подробно рассматриваются принципы функционирования Navigation Controller, который помимо основных функциональных возможностей, является адаптивной версией Split View для iPhone.

Связи между MVC осуществляются segues. Они всегда создают новый экземпляр вызываемого MVC и нуждаются в инициализации этого MVC, например, с использованием метода prepareForSegue. В лекции рассматриваются все типы  segues.

Далее в лекции приводится большой демонстрационный пример Psychologist, в котором показывается создание адаптивного Split View как для iPad, так и для iPhone. Дан шаблон универсального кода для метода prepareForSegue в этом случае. Приводится пример выполнения segue в коде. Конечно, у Пола Хэгерти в курсе cs193p Winter 2015 ни один демонстрационный пример не обходится без применения Autolayout, и этот пример не исключение: вы узнаете новые приемы работы с Autolayout.

Читать далее

Задание 2. Решение — Возвращаем enum Result (дополнительные пункты 2, 3) Swift 1.2 и Swift 2.0

Screen Shot 2015-03-31 at 5.32.05 PM
Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на

Задание 2 iOS 8_new.pdf

Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github.

Это окончание решения Задания 2- дополнительные пункты 2 и 3, предыдущие пункты можно посмотреть:

Задание 2. Решение — обязательные пункты 1-4. 

Задание 2. Решение — обязательные пункты 5-8. 

Задание 2. Решение — обязательные пункты 9-12. 

Задание 2. Решение — Убираем лишние скобки. Дополнительный пункт 1. 

Окончательный вариант кода (включая все обязательные и дополнительные пункты) для Задания 2  можно найти на Githubиспользование паттерна проектирования Singleton для NSNumberFormatter можно посмотреть в посте

Как создать NSNumberFormatter Singleton в Swift (1.2  и 1.1) —  дополнение к Заданию 2, а код на Github

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

Добавьте “Undo” к вашему калькулятору: в дополнительном пункте Задания 1 вы добавляли  кнопку  “backspace”, если пользователь ввел неверную цифру. Теперь мы говорим о комбинации “backspace” и реального “Undo” в единственной кнопке. Если пользователь находится в середине ввода числа, то это кнопка работает как  “backspace”. Если пользователь не находится  в середине ввода числа, то должно выполняться Undo последней вещи, которая была выполнена в CalculatorBrain.     

Читать далее

Задание 2. Решение — Убираем лишние скобки (дополнительный пункт 1) Swift 1.2 и Swift 2.0

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на

Задание 2 iOS 8_new.pdf

Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github.

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

Сделайте так, чтобы ваша description имела как можно меньше круглых скобок для бинарных операций.

Теоретическая часть согласно подсказке в Задании 2 потребует добавления концепции “приоритета (precedence) операций” в Op вашего CalculatorBrain

Заметим, что все нижеприведенные рассуждения касаются только перевода нашего стэка, записанного в форме обратной польской записи (RPN), не требующей применения скобок, в инфиксную форму со скобкамиИнфиксная форма нужна только для представления описания стэка в привычной для пользователя форме var description и не влияет на вычисления нашего калькулятора.

Читать далее

Задание 2. Решение — продолжение (обязательные пункты 9-12) Swift 1.2 и Swift 2.0

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на

Задание 2 iOS 8_new.pdf

Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github.

Пункт 9 обязательный

Добавьте две новых кнопки на цифровую клавиатуру вашего калькулятора  Calculator:→M и M. Эти две кнопки устанавливают и получают соответственно переменную в CalculatorBrain, называемую M.

  • →M  устанавливает значение переменной M в CalculatorBrain в текущее значение на дисплее.
  • →M не должна автоматичски выполнять↵ (хотя она должна переустановить  “пользователь в середине печати числа”)
  • Касание M должно помещать (push) переменную M в стэк (не значение M) в CalculatorBrain
  • Касание любой другой кнопки должно показывать оценку  CalculatorBrain (то есть результат evaluate()) на дисплее.
  • →M и M являются механизмом Controller, а не механизмом Model (хотя они оба используют механизм “переменных” Model).
  • Это не выдающаяся кнопка “memory” на нашем калькуляторе, но она является хорошим инструментом для тестирования правильно ли работает наша переменная функция, реализованная выше.

Примеры …

7 M + √ ⇒ description имеет вид (7+M)display — пустой, та как M не установлена

9 →M  display показывает 4 (квадратный корень 16), description все еще показывает (7+M)

14 + ⇒ display показывает 18description теперь (7+M)+14

Делаем словарь variableValues с переменными private, а в API калькулятора добавляем non-private методы setVariablegetVariable и clearVariable

Читать далее

Задание 2. Решение — продолжение (обязательные пункты 5-8) Swift 1.2 и Swift 2.0

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на

Задание 2 iOS 8_new.pdf

Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github.

Начало решения Задания 2 находится здесь.

Пункт 5 обязательный

Добавьте способности вашему CalculatorBrain  помещать “переменные”  в его  внутренний стэк. Сделайте это путем реализации следующего API в вашем CalculatorBrain …

func pushOperand (symbol:String) -> Double?

var variableValues:Dictionary<String, Double>

Это должно делать точно то, что говорят названия : первая функция “толкает” “переменную” во внутренний стэк CalculatorBrain (например, pushOperand (“x”)  будет помещать переменную с именем х), а вторая переменная ввиде словаря позволит пользователю CalculatorBrain установить любое значение для любой переменной (например, brain.variableValues [“x”] = 35.0) . pushOperand должен вернуть результат evaluate() после помещения переменной в стэк (как pushOperand делает в других случаях).

В нашей Модели CalculatorBrain добавляем в перечисление enum вариант для переменных Variable:

Screen Shot 2015-03-26 at 2.57.03 PM
Функция func pushOperand (symbol:String) -> Double? для переменных будет выглядеть точно также, как и уже существующая, только вместо операнда мы будем добавлять в стэк переменную

Читать далее

Задание 2. Решение — начало (обязательные пункты 1-4) Swift 1.2 и Swift 2.0

Текст Домашнего задания на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 2″.  Текст Домашнего задания на русском  языке доступен на 

Задание 2 iOS 8_new.pdf

Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode  работает напрямую с Github.

Пункт 1 обязательный

Все изменения, сделанные с калькулятором Calculator на лекции, должны быть внесены в код вашего Задания 1. Сделайте полученный Calculator полностью функционирующим прежде, чем вы приступите к выполнению остальных обязательных заданий. И, как и в прошлый раз “печатайте” изменения в коде, а не используйте copy / paste.

В этом пункте мы должны совместить изменения в коде, сделанные на Лекции 3, когда происходит разделение на Модель и Controller, и калькулятор, который получился при выполнении Задания 1 без разделения на Модель и Controller. Это калькулятор описан в посте.

Код можно посмотреть на Github.

Читать далее

Лекция 6 CS193P Winter 2015 — Протоколы и делегирование, распознавание жестов

Пол Хэгерти начинает Лекцию 6 с небольшой демонстрации великолепных возможностей Xcode по работы с пользовательскими UIViews: @IBDesignable и  @IBInspectable. Затем добавляется Модель в MVC, разработка которого началась на прошлой лекции.

Extensions 

Далее рассматривается такая концепция Swift как extensions (расширения). Пол Хэгерти подчеркивает, что рассказывает об extensions не потому, что это очень важная возможность Swift, а потому что это немного опасная возможность Swift. Реализация extensions в Swift очень простая. Совсем чуть-чуть синтаксиса для добавления методов и свойств к существующим classesstructures и enums. Вам не нужно даже иметь код этой вещи, к которой вы хотите добавлять расширения. Вы можете добавлять столько методов и свойств, сколько хотите. Именно простота синтаксиса может привести к злоупотреблениям применения этой концепции.

Протоколы и делегирование

Пол Хэгерти рассказывает о том, что Swift имеет очень любопытный синтаксис для протоколов. Затем следует  подробная теория протоколов и делегирования, излагаемая на слайдах. Четко очерчивается процедура разработки делегирования как со стороны того, кто (обычно View) делегирует свою ответственность другим, так и со стороны того, кто берет на себя роль делегата (по обстоятельствам может быть и View, и Controller). Простота Модели в очень подробном демонстрационном примере приводит к такому понятному изложению сложной для понимания концепции делегирования, что удобно держать этот замечательный пример как прототип для проектирования делегирования в любых других сложных обстоятельствах.

Жесты 

Рассказывается  как нужно работать с самыми разными жестами: pinch (стягивание), pan (движение по экрану), rotation (вращение), swipe  (смахивание), tap (стук) и в разных условиях: на storyboard  и в коде. Большое внимание уделяется как распознаванию различных жестов, так и их обработки как в случае управления экранно-зависимыми элементами UI, так и Моделью.

Демонстрационный пример показывает работу с двумя совершенно различными жестами :  pinch и panОдин — с двумя пальцами, другой — с одним. Один жест мы добавили на storyboard, а другой — в коде. Один обрабатывает наш Controller, а другой —  наш View. Система IOS великолепно определяет разницу между жестами, когда один сменяет другой.

В конце лекции Пол Хэгерти переходит к большой теме «Множество MVC«, которая будет продолжена на Лекции 7.

Лекция и слайды на английском языке iTunes название “6. Protocols and Delegation, Gestures”.  Код Демо «Happiness»  для Swift 1.2 доступен на сайте  Stanford.  Код демонстрационного примера  «Happiness» для Swift 2.0 доступен на Github.

Русский неавторизованный конспект лекции 6, хронометрированный через каждые 5 минут, представлен в PDF — файлах.

Лекция 6 CS193P Winter 2015 iOS 8 1.pdf

Лекция 6 CS193P Winter 2015 iOS 8 2.pdf

Лекция 6 CS193P Winter 2015 iOS 8 3.pdf