Текст Домашнего задания на английском языке доступен на iTunes в пункте “Developing iOS 8 app: Programming: Project 2″. Текст Домашнего задания на русском языке доступен на Результаты выполнения задания можно обсуждать на форуме Swift[ru] . Ваше решение может быть лучше и интереснее. Выкладывайте его в Github, давайте ссылку на Dropbox или используйте другие системы управления версиями. Xcode работает напрямую с Github.
Пункт 1 обязательный
Все изменения, сделанные с калькулятором Calculator на лекции, должны быть внесены в код вашего Задания 1. Сделайте полученный Calculator полностью функционирующим прежде, чем вы приступите к выполнению остальных обязательных заданий. И, как и в прошлый раз “печатайте” изменения в коде, а не используйте copy / paste.
В этом пункте мы должны совместить изменения в коде, сделанные на Лекции 3, когда происходит разделение на Модель и Controller, и калькулятор, который получился при выполнении Задания 1 без разделения на Модель и Controller. Это калькулятор описан в посте.
Код можно посмотреть на Github.
Пункт 2 обязательный
Ничего не меняйте в non-private API в CalculatorBrain и продолжайте использовать enum в качестве основной внутренней структуры данных.
Здесь стоит привести наш non-private API в CalculatorBrain.
У меня это:
[js]
func pushOperand(operand: Double) -> Double?
func performOperation(symbol: String) -> Double?
func evaluate() -> Double?
func displayStack() -> String?
[/js]
Пункт 3 обязательный
Ваш пользовательский интерфейс (UI) должен быть всегда синхронизирован с вашей Моделью (CalculatorBrain).
Пользовательский интерфейс, который нужно синхронизировать с Моделью, соcтоит из двух меток: метка display (дисплей нашего калькулятора) и метка history (историей ввода операндов и операций).
Синхронизация метки display и Модели осуществляется через «вычисляемую» переменную displayValue, значение которой мы задаем на основании результатов использования функций API нашего калькулятора pushOperand и performOperation. Эти функции API возвращают Optional значения, следовательно, переменная displayValue также должна быть Optional
и мы плавно переходим к пункту 4, который у нас уже выполнен в Задании 1.
Метка history устанавливается синхронно с установкой значения displayValue в set {}
с использованием функции displayStack из API нашей Модели
В дополнительном пункте 2 Задания 1 нас просили добавить в конце метки history знак «=», если число на дисплее показывает результат вычисления, а не только что введенное число. Мы должны это сделать при получении результатов выполнения любой операции
Пункт 4 обязательный
Дополнительное задание с прошлой недели превратить displayValue в Double? ( то есть сделать его Optional, а не Double) теперь является обязательным. displayValue должен возвращать nil, если содержимое display не может интерпретироваться как Double. Установка displayValue в nil должна очищать display.
После объявления displayValue как Double? мы можем в get{ } использовать цепочки Optional, а в set{ } — очищать display в случае установки в nil. Режим get{} работает при передачи числа с экрана в CalculatorBrain с помощью API функции pushOperand , а режим set{ } работает при выводе на экран результата, полученного с помощью API функции performOperation.
Одновременно в set{ } вы должны модифицировать метку history с историей ввода операндов и операций
history.Text = brain.displayStack ?? » «
Функция addHistory, используемая в Задании 1 большее нужна, так как полный список операндов и операций мы получаем из класса CalculatorBrain с помощью функции displayStack из API нашей Модели.
C numberFormatter(), используемом в вычисляемой переменной displayValue, мы получим интересные результаты. Например, для стэка [1.0, 0.0, ÷] деления 1.0 на 0.0 результат будет устанавливаться в «бесконечность».
А нам бы хотелось получать значение nil, чтобы очищать экран и сообщать об ошибке в строке history, поэтому внесем небольшие коррективы в код функции evaluate() нашего API в Модели CalculatorBrain
Код для Swift 1.2 и iOS 8.4 можно посмотреть на Github.
Код для Swift 2.0 и iOS 9 можно посмотреть на Github.
Наш новый калькулятор с разделенными Моделью и Controller должен работать абсолютно также, как и калькулятор в Задании 1.
Теперь мы готовы к добавлению новых функциональных возможностей к нашему калькулятору.
Продолжение следует…