Лекция 1 CS193P Fall 2017 — Введение в iOS 11, Xcode 9 и Swift 4. Часть 1.

На сайте представлен полный неавторизованный хронометрированный конспект Лекции 1 на русском языке курса  Разработка iOS 11 приложений с помощью Swift 4.

Первая часть — 0 — 50 минута находится в этом посте,
Вторая часть — 50 — 82 минута — находится  здесь.

Код демонстрационного примера для Лекции 1 находится на Github для iOS 11  и на Github для iOS 12 в папке Concentration L1

На Лекции 1 профессор Пол Хэгерти представляет этот курс, предварительные требования для его успешного прохождения и дает беглый обзор iOS 11. Затем полностью погружается в очень большой и продолжительный демонстрационный пример.

Темы демонстрационного примера:

  • Создание проекта Project в Xcode 9
  • Построение пользовательского интерфейса (UI)
  • iOS симуляторы
  • print (вывод на консоль, используя \( ) нотацию)
  • Определение класса в Swift, включая определение переменных экземпляра класса и методов
  • Связывание свойств (переменных экземпляра класса) в Swift коде с элементами пользовательского интерфейса UI (Outlets)
  • Привязка элементов UI к методам в коде Swift (Actions)
  • Доступ к iOS документации из кода
  • Автоматическое выполнение кода при каждом изменении значения свойства
  • Optionals (?, неявное развертывание путем декларирования со знаком !, явное развертывание с помощью ! и if let)
  • Array

За этими сухими пунктами скрывается блестящее изложение основных синтаксических конструкций Swift, начиная от самых элементарных и заканчивая такими сложными и непривычными как Optional и неявно развернутое Optional (implicitly unwrapped  Optional). Очень небольшое количество языков программирования имеет концепцию Optional. Это действительно крутая концепция, которую обязательно нужно понять, ибо в Swift она встречается повсюду, ей пронизаны всех iOS APIs. Но требуется некоторое время, чтобы к ней привыкнуть и эффективно ее использовать.

Попутно профессор подробно рассказывает про среду разработки Xcode 9, симуляторы, и показывает их новые возможности, а также предостерегает от распространенных ошибок, связанных с «подводными камнями» Xcode 9.
Поэтому для начинающих изучать Swift (а не программирование как таковое) Лекции 1 и 2 являются must have. Но даже если вы опытный разработчик iOS, вы все равно обнаружите в Лекции 1 что-то новое для себя.
В Лекции 2 продолжится демонстрационный пример, начатый на этой Лекции.

——————      НАЧАЛО КОНСПЕКТА      ——————————————

Добро пожаловать на курс Стэнфорда CS193P. Это курс Разработка iOS 11 приложений с помощью Swift 4, надеюсь, что вы находитесь в нужном вам месте. Это семестр  Осень 2017 (Fall  2017). Сначала я «промчусь» по нескольким слайдам, а затем сяду и буду показывать вам демонстрационный пример, чтобы вы понимали, что собой представляет разработка приложений для iOS. Потому что лучший способ изучения — это показ того, как это делается. Это краткая повестка дня сегодняшней Лекции.
Что мы будем изучать на этом курсе?
Конечно, мы будем изучать, как создавать замечательные iOS приложения.
Чем же они так замечательны?
По ряду причин.

Что я узнаю на этом курсе?

  • Как построить замечательные приложения
    • Легко создать даже сложные приложения
    • Результат будет жить в вашем кармане или рюкзаке
    • Очень легко распространять приложение через AppStore
    • Очень отзывчивое сообщество разработчиков
  • Объектно-ориентированное программирование в реальной жизни
    • Ядро Cocoa Touch является 100% объектно-ориентированным
    • Применение MVC шаблона конструирования
    • Представлены многие концепции информатики, применяемые в коммерческих платформах разработки: Базы данных, Графика, Мультимедиа, Многопоточность, Анимация, Сети и многое, многое другое!
    • Некоторые студенты смогут разместить свои приложения в AppStore для продажи

Во-первых, они могут располагаться в вашем кармане или рюкзаке, и вы можете показывать их своим друзьям на вашем iPhone или iPad. Кроме того, если вы решили превратить свое приложение в продукт, то сможете очень легко разместить его в AppStore и продать своим потребителям online. Вам даже не нужно упаковывать его в коробку и размещать на полке какого-то магазина. Ваши потребители могут добраться до него очень быстро.
Существует очень активное и отзывчивое сообщество разработчиков iOS приложений, потому что Apple всегда предлагает такие крутые вещи, как “машинное обучение” (machine learning) и “виртуальная реальность” (virtual reality) и много других интересных наработок. В магазине AppStore миллионы приложений, так что огромное множество людей занимаются разработкой приложений на iOS.
На этом курсе вы также будете использовать Объектно-Ориентированное Программирование в реальной жизни. Вы все изучаете другие CS курсы по работе в интернете (networking), с  базами данных, с графикой, с некоторыми мультимедийными вещами, многопоточностью, анимацией и многое другое.  И вы увидите как все это функционирует вместе на реальной платформе.
Возможно, что вы уже прошли многие курсы по этим отдельным направлениям и у вас возникло ощущение оторванности изучаемого предмета от реального мира. На этом курсе через несколько недель после начала вы увидите все это в действии. Поэтому этот курс — своего рода «синтез» других курсов для создания реальных приложений.
Особенно это касается Объектно-Ориентированного Программирования, потому что iOS — абсолютно полностью объектно-ориентированная. Вы не сможете ничего разрабатывать для iOS без серьезного задела по Объектно-Ориентированному Программированию.
И это подводит меня к обязательным требованиям для этого курса, которым является Объектно-Ориентированное Программирование. Предварительные требования в этом курсе действительно важны. Но они достаточно простые — вы должны иметь очень хорошие навыки Объектно-Ориентированного Программирования. Я не буду на этом курсе учить вас объектно-ориентированному программированию, я буду предполагать, что вы полностью и в полном объеме его знаете. И не только знаете, но и имеете некоторый опыт его практического использования.
Именно поэтому Стэнфордские курсы CS106A&B и, возможно, курс CS108, который целенаправленно изучает Объектно-Ориентированное Программирование, являются обязательным предварительным требованием для этого курса.

   Требования

  • Предварительные курсы
    • Опыт Объектно-Ориентированного программирования обязателен
    • Обязательны CS106A&B (или X) и CS107 или CS108 или CS110 также (как минимум) обязательны (или эквивалентные не Стэнфордским градациям)

Другое необходимое требование — вы должны чувствовать себя комфортно при написании кода значительного объема. Все ваши домашние Задания на этом курсе — это совсем немного чтения  о языке программирования, на котором вы собираетесь разрабатывать приложения, в первые несколько недель, но по большей части — это программирование, программирование и еще раз программирование. Поэтому, если вы не чувствуете себя комфортно при написании огромного объема кода, то, может быть, вам стоит взять сначала другие курсы, на которых требуется написание кода, а затем уже наш курс, когда он будет предложен в следующий раз.
Что содержится в iOS, каковы ее части? Чему я собираюсь вас учить?

Вот группы, на которые Apple часто подразделяет iOS. Всего 4 слоя:

  • Core OS — очень близка к hardware,
  • Core Services  — объектно-ориентированная надстройка над Core OS,
  • Media — потому что для устройства, особенно iPod с iPhone, да и для iPad, это важный раздел
  • Cocoa Touch — слой пользовательского интерфейса (UI)

Самый нижний слой, Core OS, наиболее близок к hardware, а наиболее верхний, Cocoa Touch,  наиболее близок к пользователю.

От API слоя, близкого к  hardware, наш путь лежит наверх, к  API слоям, близким к пользователю, а точнее к пользовательскому интерфейсу (UI): кнопки (buttons), ползунки (sliders) и другие подобные вещи.

Исследуя самый нижний уровень, вы, возможно, удивитесь, обнаружив, что iOS — это Unix. Точнее BSD вариант Unix. На этом уровне программные API не являются объектно-ориентированными, сам UNIX написан на C, так что преимущественно это программирование на С. На этом уровне мы не будем программировать на этом курсе. Наш курс полностью ориентирован на объектно-ориентированное программирование, поэтому я не буду учить вас тому, что происходит на этом самом нижнем уровне.
Давайте поднимемся на один уровень абстракции выше, который называется
Core Services слоем.

Здесь есть объектно-ориентированный слой, выстроенный поверх низкоуровневых сервисов. Это тот слой, которому я вас буду учить. Если вы хотите делать такие вещи, как знать, где на планете Земля находится ваш iPhone, или узнать его ориентацию в пространстве или иметь доступ к некоторым файлам, вы будете использовать непосредственно этот слой, и я собираюсь научить вас этому, научить вас работать со слоем Core Services. И мы будем много на нем программировать и изучать.
Поднимаемся к следующему слою, который, по правде говоря, не удовлетворяет требованию строгого разделения iOS на слои. И это Media слой.

Не забывайте, что ваш iPhone, по существу, iPod, с которого можно звонить. Именно поэтому у него множество различных типов медиа:  видео, различного рода изображения и много всего другого.
К сожалению, у меня нет времени останавливаться на этом слое подробно, хотя я хотел бы учить вас тому, что происходит на этом слое, ибо это большая часть того, что делает iOS устройство.  Но я вынужден отсечь многое из того, что находится на этом уровне, и мы не будем слишком много говорить о нем.
Я знаю, что некоторые из вас хотели бы создать крутую 3D звуковую игру. Это возможно, и это достаточно просто сделать, но имея в распоряжении 10 недель, я вынужден очень тщательно выбирать разделы iOS, которым я вас буду учить, и пришел к выводу, что я сосредоточусь преимущественно на слое Core Services.
И, наконец, на топовом уровне находится слой, в котором мы будем проводить большую часть нашего времени, — это Cocoa Touch.

Cocoa Touch — это UI слой iOS. Это объектно-ориентированные APIs для построения пользовательского интерфейса (UI).
Именно на этом слое находятся кнопки (Button), бегунки (Slide) и другие элементы пользовательского интерфейса (UI), но есть и реально очень мощные объекты, такие, как “карта Мира” (Map Kit).  В слое Cocoa Touch объект “карта Мира” представляет единый объект, который вы можете “бросить” на UI вашего приложения и получить полную функциональность карты внутри прямоугольной области, вообще не выполняя никакой работы.
Мы будем говорим о самых различных UI элементах, и я постараюсь рассказать вам о них как можно больше.
Это очень грубый обзор iOS. Невозможно рассказать об iOS за 2 минуты, но у вас уже создалось определенное представление о том, что мы будем делать на этом курсе.

Платформой, на которой мы будем выполнять разработку iOS приложений, является Xcode 9, так что нам необходимо загрузить Xcode 9, которая является бесплатной приложением и может работать исключительно на вашем Mac.

Существует и другое маленькое приложение Instruments, которое позволяет измерять производительность и много всего другого,  но это лишь дополнение к Xcode 9. Реально мы все будем делать в Xcode 9. Это и редактор исходного кода, и отладчик, у него есть управление версиями исходного кода. И в основном мы будем работать в Xcode 9.

Нам придется изучать новый язык программирования. У iOS два языка программирования, на которых вы можете выполнять разработку приложений, это Objective-C и Swift. Swift — это новый язык программирования и именно его мы будем изучать. Все, что вы изучите в Swift относительно iOS, вы сможете применить позже к изучению Objective-C, если захотите, и если компания, в которой вы будете работать все еще пишет на Objective-C, который является вполне приемлемым языком программирования для написания iOS приложений.
——- 5 -ая минута лекции —-
Но Swift — великолепный язык, и думаю, что он вам очень понравится.
Если вы серьезный ученый в области Информатики, изучение другого языка программирования для вас ничего не стоит. “Расскажи мне его синтаксис и ключевые фундаментальные механизмы, с помощью которых я могу конструировать программы, и я изучу его.” Если вы не обладаете таким уровнем знания языков программирования, то вы будете испытывать затруднения в реальном мире как программист.
И, конечно, у нас в iOS миллион того, что называется Frameworks . Frameworks — это просто коллекции объектов.

iOS наполнено множеством frameworks, и мы рассмотрим их. Основной и самый большой framework — это UIKit. Он связан с пользовательским интерфейсом, это в основном библиотеки объектов, которые вы используете как строительные блоки для создания вашего приложения: кнопки, метки, текстовые поля и другие элементы UI. Foundation — это другой большой framework, библиотека слоя Core Services, о котором я говорил, но есть еще множество других frameworks: CoreMotion — для отслеживания движений iOS устройства c помощью гироскопа и акселерометра,  CoreData — для объектно-ориентированной базы данных. Я говорил вам о картах — это фреймворк  MapKit  для работы с картами. Я покажу вам как можно больше frameworks, но их слишком много, чтобы рассмотреть подробно в течение 10 недель.

И, наконец, последняя, но  действительно очень важная часть платформы — это стратегия проектирования iOS приложений, которую вы должны использовать. У вас нет другой опции для стратегии проектирования iOS приложений, вы должны использовать именно эту стратегию, которая называется MVC (Model View Controller). Она используется также и на других платформах. Кто из вас когда-либо на какой-то платформе использовал MVC прежде?  В этом семестре таких не так много, обычно у меня на курсе бывает половина, но я буду учить вас стратегии  MVC.
Я начну в Среду с того, что расскажу о том, что представляет собой MVC и как применить эту методологию в разработке  iOS приложений. Это очень важная вещь, и в 100 % случаев мы должны использовать MVC для разработки  iOS приложений. Нет других способов это сделать. В противном случае вы будете “плыть против течения”, против самой сути iOS. И закончите полной неразберихой в своем приложении. Так что мы будем изучать методологию MVC.

Сейчас я хочу “окунуться” в большой демонстрационный пример, потому что наилучший способ изучения создания iOS приложений — это демонстрационный пример, в котором вы увидите создание iOS приложения с нуля.
Слайд, представленный ниже, предназначен для более позднего просмотра. К этому слайду вы должны обратиться, вернувшись сегодня после Лекции, чтобы убедиться, что поняли все в этом демонстрационном примере. Он не предназначен для чтения прямо сейчас.

   Демонстрационный пример

  • Игра «Концентрация»
    • Все кажется абстрактным до тех пор, пока вы не увидите это в действии.
    • Мы начнем осваивать Swift 4 и Xcode 9 путем создания чего-нибудь прямо сейчас.
    • Демонстрационный пример состоит из 2-х частей. Сегодня — первая часть, а в Среду — окончательная вторая часть.
  • Темы сегодняшней части демонстрационного примера…
    • Создание проекта Project в Xcode 9, включая построение пользовательского интерфейса (UI) и запуск приложения на iOS симуляторе
    • Создание subclasses в Swift, включая определение переменных экземпляра класса и методов
    • Привязка UI элементов к методам в нашем Swift коде (actions)
    • print (вывод на консоль, используя \() нотацию)
    • Связывание свойств (переменных экземпляра класса) в Swift коде с элементами пользовательского интерфейса UI (outlets)
    • Доступ к iOS документации из кода
    • Автоматическое выполнение кода при каждом изменении значения свойства
    • Array
    • Optionals

Так как я не собираюсь возвращаться к слайдам после демонстрационного примера, то позвольте мне рассказать о том, что вас ждет в ближайшее время.

Что нас ожидает?

  • Сегодня
    • Выдача Задания на чтение № 1 R1 (выполнение к следующей Среде)
  • Среда
    • Методология проектирования MVC (Model View Controller)
    • Продолжение демонстрационного примера Concentration
    • Выдача Задания на программирование № 1 P1 (выполнение к следующей Среде)
  • Пятница
    • Советы и подсказки по наиболее эффективному использованию Xcode 9
    • Использование отладчика для отладки Swift кода в Xcode 9
  • Понедельник
    • Swift
    • R1 к Понедельнику
    • P2 будет выложено в следующую Среду

У вас будет Задание на чтение, которое будет выложено сегодня. По существу, это начало чтения «Учебника по языку Swift«, который вы сможете загрузить бесплатно на странице. Именно таким способом вы сможете изучить новый язык программирования Swift. Это будет продолжаться 3, может быть 4 недели, так что вам не придется читать слишком много за один раз. Но эти Задания на чтения будут идти параллельно с Заданиями на программирование. Задание на чтение будет выкладываться в Понедельник и должно быть выполнено к следующему Понедельнику.

Задания на программирование будут выкладываться в Среду и должны быть в большинстве случаев готово к следующей Среде. Мы именно так будем работать в этом семестре.
В Пятницу будет необязательная Секция, что означает необязательное посещение. Там будут рассматриваться дополнительные темы. Например, в эту Пятницу это будет одна из самых больших Секций, на которой мы расскажем о том, как наиболее эффективно пользоваться Xcode 9, включая использование отладчика (debugger). Это будет одна из лучших пятничных Секций и хорошо было бы ее посетить. Если вы никогда не использовали отладчик в Xcode,то вам покажут, как использовать отладчик для решения своих проблем. Я не уверен в отношении времени пятничной секции, но в любом случае посмотрите в форуме на Piazza.
На следующей неделе мы будем говорить о Swift, а затем продолжим говорить об iOS.

Давайте приступим к демонстрационному примеру. Я заранее извиняюсь, что вынужден показывать демонстрационный пример слишком быстро, так как мы должны рассмотреть слишком многое. Так будет всегда на этом курсе, я буду стараться показывать демонстрационные примеры достаточно бегло, так как хочу дать вам как можно больше.
Итак, Xcode — это приложение, которое вы можете получить, зайдя в Mac AppStore и загрузив его на ваш компьютер. Оно бесплатное, оно не стоит мне ни цента, и я могу разрабатывать приложения для iOS. Когда вы первый раз запускаете Xcode, появляется следующий экран «заставки»:

Итак, нам необходимо создать приложение.
Я покажу вам приложение, которое собираюсь создавать. Оно из реальной жизни.
Вы видите здесь карты, с помощью которых можно играть в игру под названием “Concentration” (“Концентрация”, имеется ввиду концентрация внимания).

Кто хоть что-то слышал об этой игре “Concentration” ?
Да, не так много. Игра “Concentration” — это карточная игра. На этих картах, которые лежат “рубашкой” вверх, находятся рисунки, и цель игры заключается в том, что вы должны открыть карты, рисунки которых совпадают. У меня 12 карт, то есть 6 пар рисунков. За один раз я могу выбрать и открыть две карты, и если их рисунки совпадают, то я выиграл и карты удаляются из игры. Если карты не совпали, то карты обратно переворачиваются “рубашкой” вверх и я могу снова выбрать другие две карты. Эта игра называется “Concentration”, потому что я должен сконцентрироваться и запомнить те карты, которые не совпали, чтобы позже, когда я вернусь в игру, я смог бы использовать эту информацию для выбора совпадающих карт.
Давайте попробуем поиграть и перевернем несколько карт.
Я начинаю с одной карты. В действительности я не знаю, какие рисунки на этих картах, но давайте посмотрим:

На этой карте пара фиолетовых летучих мышей.
Далее я попытаюсь найти другую пару фиолетовых летучих мышей, давайте попробуем:

Я нашел их практически сразу. Эти две карты совпадают, и я получаю некоторое количество очков, но они  уходят из игры:

И теперь я могу снова приступить к поиску совпадающих карт.
Давайте попробуем эту карту:

Это привидение. Давайте попробуем найти подходящую ему карту:

Нет совпадения. Карта похожа на Роршаха, но это ведьма, которая летит на помеле, если приглядеться внимательнее.
Совпадения нет, я не получаю никаких очков, и переворачиваю их обратно “рубашкой” вверх:

И мы опять приступаем к поиску других двух совпадающих карт. Надеюсь, вы сконцентрированы и помните, какие уже переворачиваемые карты где находятся.
Я переверну эту карту:

Это симпатичная кошка. Давайте попробуем найти ей пару и выберем эту карту:
——- 10 -ая минута лекции ———

Это тыква! На самом деле это плохо, потому что мы получили еще одно несовпадение, но в некотором смысле это и хорошо, потому что мы получили дополнительную информацию о тех картах, на которых мы должны сконцентрироваться, теперь их уже 4.
Не совпавшие карты переворачиваются обратно “рубашкой” вверх:

Я выберу новые карты, и я собираюсь выбрать карты, которые я до сих пор не видел, потому что я знаю теперь, где они находятся.
Я выберу эту карту:

Это ведьма!
Теперь я должен сконцентрироваться и вспомнить, а где же находится ведьма?  Я думаю, что здесь:

ДА! Это ведьма! У нас совпадение, и эти карты покидают игру.

Игра продолжается.
Очевидно, что чем меньше карт вы выбираете меньшее число раз, тем больше будет ваш выигрыш.
Например, мы опять выбираем кошку. Где у нас соответствующая ей другая кошка?
Я думаю здесь, внизу:

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

Возвращаемся к Xcode. Перед вами экран заставки Xcode.

Справа в серой области будут аккумулироваться ваши проекты, над которыми вы будете работать на протяжении этого семестра. В данный момент у нас нет этого списка, потому что мы только что начали семестр. Но каждую неделю там будет появляться все больше и больше проектов.
Мы выберем создание нового проекта для нашего приложения и и кликаем на средней второй кнопке с заголовком  “Create a new Xcode project”.
Когда вы создаете новый проект, то вас спрашивают, а какого типа проект вы хотите создать?

Я хочу создать iOS приложение. Убедитесь, что вы кликнули в верхней части этого окна iOS. Не watchOS, не tvOS и не macOS приложение. Нам не нужно ни одно из вышеупомянутых приложений. Нам нужно iOS приложение.
Далее нас спрашиваю, а какого типа iOS приложение вы хотите создать?
Вам предлагаю различные шаблоны iOS приложений: Game для игр, Augmented Reality app для виртуальной реальности и т.д.
Мы всегда будем выбирать шаблон Single View Application, расположенный в левом верхнем углу, потому что это наиболее простой стартовый шаблон с наименьшим количеством кода при старте,  другие шаблоны имеют значительно больше готового кода.
Но я хочу научить вас самостоятельно писать код, а не смотреть, как это делают другие. Я не хочу, чтобы вы кликали на шаблоне, который дает вам всю инфраструктуру для игры или чего-то другого. Я хочу показать вам, как это делается с нуля. Поэтому мы всегда будем выбирать шаблон Single View Application и кликаем “Next” кнопку.
После того, как мы выберем нужный нам шаблон, нам задают ряд вопросов типа, а какое имя у вашего приложения?

Прекрасно, наша игра называется “Concentration”, поэтому приложение я назову Concentration. Строкой ниже нужно заполнить поле Team — это команда разработчиков, работающих над этим проектом. Команда может состоять из одного человека, которым являетесь вы. Вполне возможно, что при запуске Xcode не будет выпадающего списка в строке Team, а будет кнопка с заголовком “Add Account” или что-то типа “Add Team”. Вы кликаете на ней и все, что вам нужно сделать, это указать любой Apple ID, который можно получить совершенно бесплатно. Вам придется пройти через диалог, и вы добавите себя в качестве Team.

Есть еще имя организации  (Organization Name), которое может быть любым.
Имя организации появляется только как copyright символ (права авторства) в верхней части ваших Swift файлов и все.

Но следующая четвертая строка имеет поле Organization Identifier, которое супер важно и представляет собой ВАШ уникальный идентификатор как разработчика.

Я настоятельно рекомендую вам, как студенту Стэнфорда, заменить lecture в этом поле на ваш SUNet ID. В результате получите идентификатор, равный edu.stanford.cs193p + ваш SUNet ID. Это почти наверняка гарантирует уникальность, если вы — студент Стэнфорда. Если вы не являетесь студентом Стэнфорда, то можете выбрать что-то уникально идентифицирующее вас. Хорошим стилем является использование здесь обратной DNS нотации, которая, надеюсь, также будет хорошо работать в ваших обстоятельствах.
Путем комбинации уникального идентификатора разработчика и имени приложения  создается уникальный идентификатор для вашего приложения, который автоматически размещается в поле Bundle identifier.

Затем вы должны выбрать язык, на котором будете программировать. Я говорил вам, что таких языков два, но мы будем проводить всю разработку на языке Swift.

Вы можете комбинировать Swift и Objective-C даже в одном и том же приложении. Они прекрасно совмещаются. Потому что Swift конструировался полностью с учетом Objective-C, так что проблемы в совместном их использовании нет. На нашем курсе мы всегда будем выбирать Swift.
В первые две недели мы не будем ничего использовать из того, что расположено в нижней части этой формы, но в дальнейшем нам понадобится объектно-ориентированная база данных и тестирование:

Теперь я кликаю Next, и меня спрашивают, где я хочу разместить свой проект?
Я настоятельно рекомендую размещать его в вашей Home директории, в папке с именем Developer, потому что Home /Developer является каноническим местом для размещения ваших проектов.

Все ваши проекты будут собираться здесь, в том числе Concentration и другие, которые мы будем разрабатывать позже в этом семестре.
В нижней части можно указать вещи, связанные с управлением версиями исходного кода (Source Control), мы будем говорить об этом позже, но первые две недели мы не будем этого делать, так что Source Control оставляем не помеченным.
Нажимаем Create (Создать) и получаем наше первое iOS приложение.

Кто из вас уже знаком с Xcode? Около половины. Что ж так обычно и бывает.
Для тех, кто еще не видел Xcode я дам небольшие пояснения относительно пользовательского интерфейса Xcode. Весь экран в Xcode разделен на 3 основные секции:
СРЕДНЯЯ СЕКЦИЯ — главная, именно в ней мы будем редактировать исходный код и делать всю основную работу, в данный момент в ней показаны установки (Settings) проекта,
СЕКЦИЯ СЛЕВА серого цвета называется “Навигатор” (Navigator); она предназначена для навигации по вашему проекту. Вы можете работать с  “Навигатором” в разных режимах, выбирая соответствующие закладки вверху, но основной режим “Навигатора” (Navigator) — это показ файлов проекта.
СЕКЦИЯ СПРАВА серого цвета — это Область Утилит (Utilities Area).
То, что показывается в СРЕДНЕЙ СЕКЦИИ  зависит от того, что выбрано в  “Навигатор” (Navigator) слева. У нас показаны установки (Settings) проекта в главной средней секции потому, что в соответствующей закладке “Навигатора” (Navigator) выбран файл самого проекта Concentration, который отмечен темно синим цветом в самом верху:

На этой закладке в “Навигатора” (Navigator) показываются все файлы моего проекта.
Их шесть, они даются вам выбранным шаблоном, в частности, мы выбрали шаблон Single View Application.
Но я могу осуществлять навигацию по проекту также путем поиска (searching) определенного текста в вашем приложении:

Если я нахожусь в режиме отладки, то я могу осуществлять навигацию по моим точкам прерывания:

И так далее; вам определенно нужно познакомиться с областью  “Навигатора” (Navigator). Кроме того, вы можете регулировать размер пространства, необходимый вам для навигации.
——- 15 -ая минута лекции ———
Справа в Xcode находится Область Утилит (Utilities Area). У этой области есть верхняя и нижняя части, размер которых регулируется:

Мы будем подробно говорить об этой области через 5 минут, и вы узнаете все ее детали.
Сейчас я хочу показать, как вы можете управлять пространством, занимаемым каждой секцией.
Если вы посмотрите на верхний правый угол, то увидите там эти кнопки, с помощью которых можно показывать и скрывать правую и левую сторону пользовательского интерфейса Xcode.

Самая правая кнопка управляет появлением и исчезновением Области Утилит (Utilities Area).

Самая левая кнопка точно также управляет появлением и исчезновением “Навигатора”:

Таким образом, если вам нужно дополнительное пространство в главном окне, то вы всегда его сможете получить.
Есть еще одна кнопка — в середине. Видите ее? Она отвечает за появление и исчезновение “окна отладчика и консоли”. Отладчик расположен слева, а консоль — справа. Консоль — это место, куда выводятся данные печати в Swift с помощью функции print. Это очень полезный способ “легкой” отладки — просто распечатывать что-то по ходу выполнения приложения. И именно такой “легкий” способ отладки я буду использовать сегодня, не подключая возможности реального отладчика, о котором я будем говорить в Пятницу.

Средняя кнопка управляет появлением и исчезновением Области отладчика и консоли.

Для просмотра результатов отладки на консоли вы можете при желании двигать верхнюю границу “окна отладчика и консоли” вверх и вниз:

Таким образом, вы можете организовать в Xcode свое рабочее пространство наилучшим образом. У меня экран с довольно низким разрешением, поэтому я буду пытаться скрывать некоторые элементы интерфейса Xcode с тем, чтобы сделать текст кода демонстрационного примера максимально большим. Тогда вы будете отчетливо видеть, что я делаю.
Еще одна последняя вещь, которую я хочу показать вам прежде, чем погрузиться в демонстрационный пример, это панель запуска приложения, расположенная в верхнем левом углу.
При запуске приложения вы должны решить, где будете запускать его:

И перед нами появляются всевозможные опции запуска приложения:

Вы можете запускать приложение на реальном iOS устройстве, предварительно подключив его к вашему Mac либо беспроводным образом, либо с помощью USB кабеля или еще как-то. Я не подсоединил к своему Mac никакое iOS устройство, следовательно, у меня такой возможности нет. Но я могу запустить мое приложение на любом из множества симуляторов. Выше вы видите список симуляторов, которые симулируют различные iOS устройства типа iPad или iPhone 8+ или что-то еще. И вы можете запустить свое приложение на любом из этих симуляторов или на нескольких, если хотите. Я собираюсь работать с самым последним и с самым крутым iPhone X:

Давайте запустим наше приложение на iPhone X.
Мы пока ничего не создали, так что это будет пустое приложение; мы запустим это приложение просто для удовольствия.
Вы видите эту кнопку для запуска приложения?

С помощью этой кнопки мы запускаем приложение, просто кликнув на ней.
Теперь наше приложение компилируется, идет преобразование в бинарную форму, оно загружается на устройство, а в нашем случае на симулятор, и, наконец запускается. И все эти стадии преобразования мы видим в верхней части Xcode:

И вот оно уже здесь, на симуляторе iPhone X. Приложение абсолютно пустое, потому что я ничего не сделал в этом приложении, не создал никакого UI:

Но если я нажму кнопку Home на iPhone X, все знают, как она работает? Вы делаете жест скольжения снизу вверх, это является аналогом кнопки Home на iPhone X, ведь физически кнопки Home нет на iPhone X.

Но если нажму кнопку Home на iPhone X, то наше приложение уйдет в фоновый режим:

Вы видите, что помимо нашего приложения Concentration, здесь также есть и другие приложения. Например, на экране справа есть приложение Settings (Установки). И если вы хотите регулировать размер текста на вашем симуляторе, то вы можете это сделать точно также как на реальном iOS устройстве, запустив приложение Settings и выбрав опцию General:

Таким образом, понятно, что это реальный симулятор iOS устройства, а не просто “болванка” для запуска вашего приложения. Это, конечно, круто. И мы всегда на симуляторе можем вернуться обратно к нашему приложению.
Делаете жест скольжения снизу вверх и кликаем на Concentration.

Итак, мы познакомились с вами с основными частями Xcode.
Теперь давайте взглянем на те файлы, которые он предоставил в наше распоряжение.

У нас 6 файлов, но реально мы собираемся работать только с  двумя из них.
Например, папка Assets.xcassets. Он включает все media содержимое приложения. Все видео, изображения, звуки, иконки и подобные этому вещи, которые могут быть вставлены в ваше приложение. Вот как выглядят иконки приложения AppIcon, которые я не установил и все эти «кармашки» пустые:

Мы не будем работать с этим файлом.
Кроме того, мне не понадобятся файлы LaunchScreen.storyboard и AppDelegate.swift. Я даже не коснусь их в процессе разработки нашего приложения Concentration. Поэтому я кликаю правую клавишу мыши (CTRL-клик) и выбираю во всплывающем меню New Group From Selection для размещения выделенных файлов в отдельной папке:

Я назову эту новую группу файлов Supporting Files, потому что это вспомогательные файлы. Между прочим, я не поместил  файл Info.plist в папку Supporting Files:

Вы видите, что все они скрылись в этой папке, теперь мы не будем их видеть. Мы сфокусируемся на двух файлах, которые являются наиболее важными для сегодняшнего демонстрационного примера. По-моему выглядит лучше.
У нас остались другие файлы: ViewController.swift — это просто Swift код, который мы начнем писать через секунду:

И файл Main.storyboard, который является пользовательским интерфейсом (UI) для вашего приложения:

Вы будете создавать UI в Xcode графически, а не писать для этого код. Способ, каким вы будете это делать, заключается в том, что вы перетаскиваете с помощью “мышки” различные объекты UI типа кнопок Button, меток Label, ползунков Slider или текстовых полей Text Field туда, куда мы хотим. И они превратятся в настоящие кнопки, метки, ползунки или текстовые поля на экране UI. И вы будем инспектировать эти объекты и устанавливать их свойства.

Затем, когда вы запускаете приложение, то к этому “засушенному” и “замороженному” UI, который вы видите на storyboard, добавляется “вода” и он “оживает” на экране для взаимодействия с пользователем. Когда вы запускаете приложение, это не значит, что ваши кнопки и ползунки, расположенные на storyboard, генерируют огромное количество кода. Реально “оживают” кнопки и ползунки, которые мы редактируем на storyboard практически “в живую”.
Заметьте, что наш UI имеет прямоугольную iPhone форму. Именно в этом iPhone прямоугольнике мы редактируем наш UI. Точнее, этот iPhone прямоугольник имеет размеры iPhone 8.

Посмотрите на нижнюю часть экрана, если я кликну на ней, то увижу другие iOS устройства:

С помощью этого набора устройств я могу посмотреть, как выглядит мой UI, например, на iPad.  iPad огромен, так что мне придется немного уменьшить масштаб, чтобы лучше разглядеть его:

——- 20 -ая минута лекции ———
Я также могу посмотреть на свой UI в ландшафтном режиме:

Здесь производится переключение между портретным и ландшафтном режимами. Я могу выбрать другой тип iPhone, например, iPhone X:

Я могу выбрать любое возможное iOS устройство, и посмотреть, как выглядит мой UI. Наша цель, по большому счету, как только мы узнаем достаточно об iOS, создать такие UIs, которые хорошо смотрятся в ландшафтном или портретном режимах, на iPad, iPhone 8iPhone 8+, который больше iPhone X, но это не имеет значения. Это наша цель.
Но на первой неделе я не могу вас этому учить, для нас достаточно будет того, что UI будет выглядеть хорошо на iPhone X. Но на следующей неделе мы сделаем так, чтобы ваш UI выглядит хорошо также и на других iPhones. И в вашем домашнем Задании 2 вас попросят создать приложение, которое хорошо выглядит на всех возможных iOS устройствах.
Между прочим, перед вами находится целая система построения UI, которая называется Interface Builder. Это часть Xcode, называемая Interface Builder, с широкими функциональными возможностями ориентирована на построение UI, который будет прекрасно работать на всех устройствах.

Слева от UI вы видите небольшую область, называемую Схема UI (Document outline). В схеме UI (Document outline) представлены все элементы пользовательского интерфейса, но в текстовой форме, и это часто оказывается очень полезным для разработчика.
Внизу находится маленькая кнопочка, которая показывает и скрывает Схему UI (Document outline).

Я также могу скрыть панель для выбора iOS устройства, просто кликнув на ней:

Мы будем работать со схемой UI (Document outline) позже в этом семестре.
Я хочу построить UI для моей игры Concentration. Для этого мне нужны карты, и я собираюсь использовать кнопки UIButton для представления карт, что очень здорово, потому что когда кликаешь на кнопке, то она всегда что-то выполняет. Я собираюсь заставить мои карты переворачиваться. Это первое, что я собираюсь сделать.
Давайте создадим одну карту. Которая будет переворачиваться, когда мы на ней кликнем.
Кстати, если вы удерживаете клавишу Alt (option), то прокручивая “колесико” “мышки”, вы увеличиваете или уменьшаете масштаб вашего UI :

Здорово! Если не удерживать клавишу Alt (option), то прокручивая “колесико” “мышки”, вы перемещаете UI вверх и вниз:

Итак, у нас есть UI. Как мы будем размещать на этом UI кнопки?
Как и было обещано, мы идем в Область Утилит, и в ее нижней части выбираем закладку с Библиотекой Объектов (Object Library):

Мы видим в этой библиотеке целую кучу объектов. Объектов в смысле терминологии объектно-ориентированного программирования. Все это объекты типа меток Labels, кнопок Buttons, текстовых полей Text Fields, переключателей Switches и даже целые Safari WebKit Views, таблицы Table Views, текстовые изображения Text Views и даже виртуальную реальность ARKit и жесты можно перетянуть на ваш пользовательский интерфейс :

Я буду рассказывать о большой части этого огромного списка.
Но начнем мы с самого простого объекта, который расположен в верхней части списка — с кнопки Button.
Я просто выбираю ее “мышкой” и перетягиваю на мой UI в нужное место, а потом “бросаю” на мой UI :

В процессе перемещения кнопки по экрану появляются пунктирные голубые линии, которые помогают мне найти правильное место размещения : точно в середине экрана, или точно у левого края, или точно в середине и у нижнего края, или точно в левом верхнем углу:

Как только вы начнете думать о создании UI, работающем при повороте из портретного режима в ландшафтный и на всех iOS устройствах, голубые направляющие голубые линии начнут играть для нас решающую роль. Но в данный момент мы будем игнорировать голубые линии, потому что я собираюсь учить вас этой теме на следующей неделе.
Итак, у меня есть кнопка, но она очень-очень маленькая.
Я хочу сделать ее побольше. Для этого я могу потянуть за “ручки”, расположенные по краям и изменить размер моей кнопки до любого нужного мне размера.
Давайте сделаем кнопку более похожей на карту:

Мы также можем отредактировать текст на кнопке, если дважды кликнем на заголовке. Нам не нужен заголовок “Button”. Мы хотим сделать обратную сторону карты — “рубашку”, поэтому мы вообще удалим текст и получим кнопку без текстового заголовка :

Как насчет того, чтобы сделать обратную сторону карты оранжевой, поддерживая нашу тему Хэллоуина? Давайте установим цвет фона карты (background color) в оранжевый.
Как мы будем это делать?
С помощью верхней части Области Утилит. Я могу вообще избавиться от нижней половины Области Утилит, задвинув ее в самый низ.
Заметьте, как только я выберу кнопку, в верхней части Области Утилит появляется UI для определения специальных атрибутов моей кнопки (Button).

Но это не все. Инспектор атрибутов имеет объектно-ориентированную природу:

Здесь я могу устанавливать атрибуты того, что выбрано, то есть кнопки Button, но Button — это обычный объектно-ориентированный объект, который наследует от объекта Control, и мы можем видеть атрибуты объекта Control. В свою очередь объект Control, наследует от объекта View. И мы можем видеть атрибуты объекта View, потому что Button — это, в конечном счете, View.

Таким образом, благодаря объектно-ориентированной природе Инспектора Атрибутов мы можем инспектировать атрибуты не только самого объекта, но и целой иерархии его наследования.
Фон (Background) для объекта View устанавливается на UI, соответствующем объекту View:

Сейчас атрибут Background установлен в Clear, о чем говорит маленькая пересекающая красная линия. Это означает Clear, то есть Background не установлен, и сквозь него виден белый фон того, что находится позади кнопки. Но я очень легко могу поменять его на оранжевый, если кликну справа и вызову меню, в котором появляется окно, в котором представлено множество заранее установленных цвета и кнопка “Other”:
——- 25 -ая минута лекции ———

Я могу кликнуть на “Other” и выбрать оранжевый цвет по имени Orange:

Я могу переключиться на Crayon (фломастеры) и выбрать там цвет, близкий к оранжевому. Или на цветовое “колесо”:

Но я уже установил фон (атрибут Background) для моей карты в оранжевый. Это похоже на те карты, которые я демонстрировал, и я вполне доволен.
Следуя нашей теме Хэллоуина, мы должны сделать что-то страшное, давайте сделаем общий фон нашего UI черным.
Для этого я просто кликну в любом свободном месте на моем UI, и справа в Области Утилит нам покажут атрибуты НЕ кнопки Button, а атрибуты нашего общего большого View:

У этого View также есть цвет фона (атрибут Background), он — белый, именно он просвечивал сквозь цвет фона Clear нашей карты. Я изменю его тем же способом, что и менял цвет фона для карты, но выберу черный Black цвет из заранее определенного списка :

Теперь у меня прекрасная оранжевая карта на черном UI. Выглядит очень круто.

А как насчет лицевой стороны карты?

Цвет фона лицевой стороны карты — белый, и на ней находится изображение, которое может быть кошкой или пауком с паутиной или чем-то еще, возможно, JPEG изображением или изображением другого формата.
Но у меня есть действительно замечательная  идея, которую очень легко реализовать. Давайте использовать эмоджи (emoji), потому что, если мы поместим эмоджи (emoji) на лицевую сторону карты, то у нас появится множество возможностей для выбора. И это очень легко, нам не придется где-то искать изображения (images) или делать что-то подобное.
Мы так и поступим.
Я сделаю сейчас лицевую сторону карты.
Для начала я заменю оранжевый цвет фона на белый:

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

Большинство Mac приложений в меню Edit, в самом низу, содержат раздел Emoji & Symbols. Я не знаю, многие ли из вас знают об этом:

Если я пойду в меню Edit ->   Emoji & Symbols, то получу окно с множеством эмоджи:

из которых я могу выбрать подходящее.
Например, для нашей темы Хэллоуин, я выбираю “привидение” (ghost):

Это такое забавное “привидение”, мы дважды кликаем на нем, и оно попадает на нашу карту.
Но оно такое крошечное по сравнению с размерами iPhone X, что выглядит просто как маленькое грязное пятнышко:

Я хочу сделать его значительно больше. Я иду в Область Утилит, в его верхнюю часть и ищу шрифт для моей кнопки. Здесь установлен System шрифт 15 point:

Я установлю размер шрифта равным 50 point:

Вот теперь у нас прекрасное “привидение”.
Здорово. Мы получили все, что нам необходимо для конструирования нашего UI.
Запускаем приложение, и смотрим, что произойдет. Посмотрим, увидим ли мы черный фон и это “привидение” на нашем  iPhone X?

Конечно, все на месте.
Когда я кликаю на карте, она немного “мигает”  и, по-видимому, работает, но, конечно, ничего не делает.  Это сообщает мне о некоторой реакции карты на то, что я кликаю на ней, но она ничего не делает. Однако, мы хотим, чтобы при нажатии на карту что-то происходило. В основном, мы хотим, чтобы карта переворачивалась.
Как мы можем заставить что-то делать элементы UI?
Мы “подцепим” их к некоторому Swift коду. В нашем случае мы хотим “подцепить” нашу кнопку к коду ViewController, который нам достался от шаблона Single View App:

Этот класс ViewController получил от шаблона код для очень важных методов, но они мне не нужен в ближайшее время, и я удалю их:

Это ваш первый взгляд на Swift код. Давайте быстро пройдемся по нему.

import — это как include. Он предоставляет в наше распоряжение UIKit. UIKit — это iOS фреймворк, у которого есть все эти кнопки Button,  бегунки Slider и прочие UI элементы. Он представляет самый верхний Cocoa Touch слой, о котором мы говорили в начале Лекции.
Далее следует декларация класса в объектно-ориентированном смысле с помощью ключевого слова class.
Затем имя класса — ViewController. Надо сказать, что это не очень хорошее имя для класса, оно слишком общее (generic) и не отражает специфики данного класса. Возможно, класс следовало бы назвать ConcentrationViewController или что-то подобное этому. Но пока не меняйте имя класса в своем домашнем Задании. Дело в том, что имя класса также задействовано в нашем UI и предполагает изменение имени класса в двух местах: в коде, в файле ViewController.swift, и в нашем UI, файле Main.storyboard. Позже я покажу вам, как это сделать корректно.

Затем следует двоеточие : и UIViewController.  UIViewController — это имя superclass:

Это Объектно-Ориентированное Программирование (ООП). И у нас имеет место наследование (inheritance). Наш класс ViewController наследует от класса UIViewController, который находится в UIKit. Об этом говорят начальные буквы UI в имени superclass. Класс UIViewController знает все о том, как управлять элементами пользовательского интерфейса UI. Когда наш класс ViewController наследует от класса UIViewController, то это означает, что он наследует всю функциональность класса UIViewController, то есть способность управлять UI. Все, что нам остается сделать, — это разместить код, связанный с нашей игрой Concentration, и это здорово.
Внутри фигурных скобок мы разместим все наши методы (methods) и переменные экземпляра класса (instance variables).
Кто не знает, что означают слова “метод” (method) и «переменная экземпляра класса» (instance variable)?
Хорошо, все знают.
Конечно, вы должны это знать, потому что это фундаментальные основы Объектно- Ориентированного Программирования (ООП).
Мы разместим все наши  переменные экземпляра класса и методы внутри фигурных скобок.

Вот как декларируется класс в Swift.
Как мы заставим нашу кнопку что-нибудь сделать?
Мы создадим для этого метод внутри фигурных скобок. И при нажатии на кнопку, этот метод, естественно,  должен вызываться.

Как нам этого добиться?

——- 30 -ая минута лекции ———
Хотите — верьте, хотите — нет, но мы должны разместить на экране одновременно наш UI и наш код, класс ViewController.
И сделаем это мы с помощью маленькой кнопки Ассистента Редактора (Assistant Editor) в правом верхнем углу экрана с двумя кружочками:

Когда я кликаю на ней, то и UI, и мой код одновременно выходят на экран. Я могу отрегулировать необходимое пространство для UI и моего кода, возможно, избавившись от Навигатора и Области Утилит:

Почему мне нужно, чтобы UI и мой код одновременно были на экране во время того, когда мы “подцепляем” кнопку к коду? Потому что способ, каким мы будем это делать, несколько замысловатый. Я буду удерживать нажатой клавишу CTRL и буду тянуть “мышкой» линию от моей кнопки на UI в код:

Вы видите на экране фиксируется, что нажата клавиша CTRL. И, когда я отпускаю клавишу CTRL, у вас появляется возможность осуществить взаимосвязь между вашим UI и кодом:

Нас спрашивают: “Какого типа взаимосвязь (Connection) вы хотите установить?
Мы можем выбрать Action, который является методом, или два других — Outlet и Outlet Collection,  о которых я расскажу позже на этой Лекции.

Давайте начнем с Action. Action означает, что при нажатии кнопки вызывается этот метод Action. И мы должны дать имя Name этому методу. Я назову его touchCard, потому что именно это и происходит, когда кто-то касается нашей карты:

Метод, который будет для меня создан, может иметь аргументы (Arguments), а может не иметь никаких аргументов:

Или может иметь один аргумент, которым является Sender, то есть другими словами, кнопка, которая посылает мне этот метод:

Мне действительно необходим этот аргумент, потому что когда мне посылается метод touchCard, мне нужно перевернуть карту. Следовательно, я должен “разговаривать” с моей кнопкой и мне необходим этот аргумент Sender:

И что очень ВАЖНО, обратите внимание на тип аргумента — поле Type.  Нам говорят, что кнопка имеет тип Any? Но мы хотим, чтобы этот тип Type соответствовал кнопке, то есть UIButton, так как именно кнопка посылает нам этот метод. Я не знаю, почему здесь по умолчанию не выставляется Type равный UIButton. Я вижу это несоответствие уже в течение нескольких лет и, видимо, это будет продолжаться. Но этого быть не должно.

И если вы не поменяете поле Type с Any на UIButton, то остальной код не будет работать.
Даже если вы ничего не запомнили из того, что я только что сказал, вам определенно нужно запомнить, что вы не должны оставлять в этом поле Any. Потому что мы точно знаем тип объекта, посылающего нам это сообщение. Это UIButton, так что вам нужно заменить Any на UIButton.
Здесь есть и другие поля помимо тех, о которых я только что рассказал.
Это поле Object,  в котором указан View Controller. Очевидно, что мы посылаем этот метод View Controller. Есть поле Event, в котором указано Touch Up Inside, что просто означает, что этот метод посылается, когда вы касаетесь кнопки внутри границ.
Кликаем на Connect.
Это дает мне метод, и это наш первый Swift метод:

Давайте посмотрим на его отдельные части. Интересно, что выражение @IBAction в действительности не является частью Swift метода. Это просто специальная директива, которую Xcode размещает здесь что-то для себя. Это заставляет Xcode поместить слева от метода touchCard маленький кружок вместо номера строки. Вы видите, как номер строки 13 замещен таким кружком. Если вы наведете на него “мышку”, не кликая, то смотрите, что происходит. Вам покажут, какая кнопка посылает вам сообщение, то есть к чему на UI «подцеплен» ваш метод:

Всякий раз, когда размещается директива @IBAction, она вызывает появление кружочка слева от метода.
Оставшаяся часть — это Swift синтаксис метода, давайте рассмотрим его внимательно.
Ключевое слово func говорит о том, что функция:

Метод — это просто функция в классе class. Совершенно законно иметь функции за пределами классов. В этом случае они являются глобальными функциями. Мы почти никогда не будем создавать глобальные функции, потому что мы будем ориентироваться на объекты, но в принципе мы можем это делать.
Вслед за ключевым словом func идет имя метода — touchCard. Я выбрал это имя при заполнении всплывающей формы:

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

У нашего метода один аргумент. Тип аргумента указывается в конце вместе с двоеточием : :

В нашем случае это, очевидно, :UIButton. При заполнении всплывающей формы мы указали, что у нас один аргумент sender, тип которого UIButton, вот и все.
Это имена параметров:

Именно “имена” в множественном числе.
Есть две вещи в Swift, которые существенно отличаются от того, что используется в других языках.
ПЕРВАЯ. Каждый аргумент имеет имя, которое вы должны включить в вызов метода. Например, мы имеем в Java : touchCard (6, @Hello@, 5). Вы НИКОГДА не будете так делать в Swift. Каждый параметр в Swift должен иметь имя перед своим значением.  В этом случае при вызове метода или при чтении кода вам нет необходимости помнить, что собой представляет первый параметр, а что — второй. Потому что все параметры именованы.
ВТОРАЯ вещь заключается в том, что аргумент имеет два имени. Этими двумя именами являются ВНЕШНЕЕ (external) имя, которое используется при вызове, и ВНУТРЕННЕЕ ( internal) имя, которое используется внутри при реализации метода. Через секунду я напишу свой собственный метод, и мы поговорим об этом подробнее.
Между прочим, если ваша функция что-то возвращает, то это оформляется в виде “стрелочки” ->:

Этот метод возвращает целое число Int. Очень простой синтаксис для этого. Но наш метод ничего не возвращает, поэтому мы возвращаем предыдущий синтаксис:

——- 35 -ая минута лекции ———
Теперь давайте убедимся, что это работает. Для этого я использую функцию print (), которая является глобальной. Она берет строку и печатает ее на консоли:

Мы будем печатать текст “agh! a ghost!”.
Запускаем приложение и посмотрим, будет ли это работать, если мы нажмем на кнопку с “привидением”.
Между прочим, если мы что-то печатаем на консоли, то, возможно, мы захотим показать нашу консоль с помощью кнопки в правом верхнем углу, регулирующей появление консоли и отладчика:

Мы можем сделать Область Отладчика немного поменьше в пользу консоли.
Это наша консоль.
Но вы можете сделать одну замечательную вещь в Xcode, и я покажу вам ее.
Вы идете в меню Xcode ->  Behaviors -> Edit Behaviors :

и получаете форму, описывающую “поведения” Xcode, то есть когда он какие окна открывает и т.д.. Например, если вы запускаете приложение (Running) и генерируете некоторые данные на консоли (Generates output), вы можете заставить Xcode показывать отладчик (Show debugger):

И при запуске приложения Область Отладчика будет появляться снизу, если ее еще там нет. Это такая маленькая приятная возможность.
Давайте запустим приложение.
Другие советы и рекомендации по использованию Xcode  мы разберем в Пятницу. Поэтому хороший повод прийти  в Пятницу на секцию.
Вопросы?
ВОПРОС: Покажите, пожалуйста, еще раз, как подсоединить кнопку к коду ViewController?
ОТВЕТ: Я покажу вам через секунду?
Давайте убедимся, что все это работает, а потом я покажу вам, как подсоединить кнопку.

Итак, у нас есть эта кнопка с “привидением”, кликаем на ней, и видим, что на консоль выводится текст “agh! it’s a ghost”. Так что все работает.
Теперь вернемся к вопросу “Как подсоединить кнопку к коду ViewController?”
Вы удерживаете клавишу CTRL и тянете мышку от кнопки в код:

Когда вы отпускаете клавишу CTRL, всплывает форма, на которой вам задают вопросы относительно того, как вы хотите назвать метод и т.д.
Итак, мы “подцепили” нашу кнопку к коду. Теперь нам нужно сделать так, чтобы вместо печати карта переворачивалась, когда мы кликаем на ней.
Убираем печать, и я собираюсь добавить мою собственную функцию, которая будет переворачивать карту.
Давайте создадим свою собственную Swift функцию с именем flipCard:

У функции flipCard два аргумента: один — это эмоджи, который я хочу разместить на карте, например, “привидение” или что-то еще, а другой — кнопка, на которой я хочу установить этот эмоджи.
Я назову эти два параметра именами, которые могут показаться вам странными.
Первый параметр имеет имя withEmoji emoji, а затем следует тип : String, который является строкой. Таким образом у первого параметра есть ВНЕШНЕЕ имя withEmoji и ВНУТРЕННЕЕ имя emoji.
А как насчет второго параметра, кнопки UIButton>?
Второй параметр имеет имя on button, а затем следует тип :UIButton, который является кнопкой.
Возможно, вам действительно покажутся странными имена параметров, как внутренние, так и, внешние. В вашем Задании на чтение на последней странице дана ссылка на документ Swift API Guidelines, который вы обязательно должны прочесть и в котором подробно объясняется, как выбирать хорошие имена для параметров. Там очень хорошо подобранный перечень правил для выбора хороших имен параметров.
Примечание переводчика. У нас есть перевод на русский язык этого документа Руководство по проектированию Swift API (Swift API design guidelines) .

ПРАВИЛО номер 1 для выбора хороших имен параметров заключается в следующем. Когда кто-то вызывает функцию, то вызов ее должен звучать как правильная фраза на английском языке.
Давайте вызовем нашу новую функцию flipCard в методе touchCard, потому что я хочу вызвать функцию flipCard с эмоджи “привидение” ? :

Заметьте, как только я начинаю набирать имя функции, Xcode пытается мне помочь. Xcode настолько сообразительный, что знает, что у меня есть метод flipCard. Мне достаточно нажать клавишу Tab и он покажет мне весь метод целиком со всеми параметрами:

Теперь мне остается только их заполнить.
Вместо String подставляем эмоджи  «привидение» ?, которое скопируем непосредственно с нашего  
UI:

Что мы подставляем вместо UIButton? Конечно, sender.

Теперь прочтите вызов метода flipCard как целую фразу на английском языке: “Flip the card with the emoji ghost on the sender button”. Это ПРАВИЛО номер 1, которое мы пытаемся выполнить.
Но внутри нашего метода flipCard мы не хотели бы иметь имя для эмоджи типа withEmoji или посылать сообщение кнопке on. Это было бы странно и не имело бы никакого смысла, вот почему у нас различные имена для внешнего и внутреннего использования.
Вполне допустимо иметь одно имя для параметра, например, типа emoji:

В этом случае и ВНЕШНЕЕ,  и ВНУТРЕННЕЕ  имя будут одинаковыми — emoji.
Символ подчеркивания “_”:

который присутствует в методе touchCard. Он означает, что внешнее имя аргумента отсутствует, другими словами, мы получаем ситуацию как в Java или некоторых других языках.
Мы почти никогда не будем так делать, в документации сказано, когда вы можете это делать. В методе touchCard присутствует символ подчеркивания “_”,  который связан с тем, что сообщение touchCard возвращается в мир Objective-C, который не имеет внутренних и внешних имен параметров. Именно поэтому здесь и присутствует символ подчеркивания “_”,  но мы не будем его использовать почти никогда.
Как мы реализуем метод flipCard?
Метод flipCard, по существу, работает как переключатель, в нем я должен взглянуть на кнопку button, и, если на ней уже есть эмоджи  «?», то я должен перевернуть карту на обратную сторону, “рубашку”, с оранжевым фоном и отсутствием текста. Если — нет, то я должен разместить там “привидение”  «?» на белом фоне. То есть поступить в точности так, как мы играли с картами раньше.Таким образом, нам нужно проверить, является ли текущий заголовок кнопки “приведением”  «?».

——- 40 -ая минута лекции ———
Я прямо сразу начну писать код:

Xcode мне подсказывает, какие объекты button у меня есть.
Мне нужно послать сообщение кнопке button и спросить ее о текущем заголовке (current title). Конечно, можно посмотреть документацию на предмет того, что может делать кнопка. Но есть более крутой способ — вы можете нажать клавишу “точка” “.”, в Swift, это также как и в Java, означает посылку сообщения:

Как только вы сделаете это, Xcode покажет вам все методы и переменные, которые кнопка button понимает. Надо сказать их достаточно много, я пролистал много страниц, но мы только добрались до буквы C:

В списке порядка двух сотен элементов. Как это может мне помочь?
Замечательно то, что есть некоторая хитрость, которую нам предлагает Xcode. Я просто печатаю наименование того, что мне нужно, и смотрите, что будет происходить, если я просто напечатаю слово “title”, которое, я думаю, может входить в имя метода или переменной, потому что я хочу получить текущий заголовок кнопки:

Вы видите, что Xcode показал мне все методы и свойства, начинающиеся со слова “title” ИЛИ имеющие в имени слово “title” :

ИЛИ даже то, что имеет в имени T-I-T-L-E, что, по существу, бесполезно, именно поэтому это находится в конце списка:

Xcode делает все возможное, чтобы показать вам максимально подходящее тому, что вы напечатали.
Давайте посмотрим в начало списка, может быть мы найдем то, что нам надо.

Какой метод даст нам заголовок кнопки?
Как насчет titleColor (for: UIControlState)? Это определенно не то, что я хочу.
Может быть, сurrentTitle, который возвращает текущий заголовок кнопки, который в данный момент показан на экране:

Ура, я нашел в точности то, что мне нужно! Победа!
Когда я ищу нужный мне метод, нужно смотреть на строку в самом низу этого окна с описанием метода или переменной.
В любом случае пробуем метод сurrentTitle, для этого дважды кликнем на нем и сравним с эмоджи emoji:

Метод сurrentTitle разместился в коде, и теперь я могу проверить заголовок нашей кнопки на равенство emoji с тем, чтобы “перевернуть” соответствующую ей карту. Заметьте, что я использую ВНУТРЕННИЕ имена emoji и button в этом коде. Я НЕ использую ВНЕШНИЕ имена withEmoji для эмоджи или on для кнопки. ВНЕШНИЕ имена используются только при вызове.
Если я обнаружил, что  на карте уже есть “привидение” ?, то я хочу установить у карты оранжевый фон и пустой заголовок. Мне необходимо установить заголовок кнопки и я видел перед этим метод setTitle:

Действительно, метод setTitle используется для установки специального заголовка. Но у этого метода есть дополнительный параметр for: UIControlState. Видите? Что за ерунда такая?
Я не знаю ничего относительно кнопок, поэтому я не уверен, что мне нужен этот метод, кроме того, здесь есть и другие методы setTitle…, но я думаю мне стоит начать с первого метода. Я дважды кликаю на нем, и получаю его в коде:

Заголовок, который я хочу установить, конечно, представляет собой пустую строку, так как я пытаюсь создать обратную сторону карты, “рубашку”:

Но я затрудняюсь заполнить второй параметр, потому что я не знаю, что означает UIControlState.
И здесь я покажу вам еще одну крутую вещь, которую вы можете делать.
Вы удерживаете клавишу option и наводите “мышку” на что-то в коде, это подсвечивается и появляется маленький знак вопроса прямо над этой вещью :

Я могу кликнуть на ней, и вы увидите документацию для этой вещи.

Я навожу “мышку” на метод setTitle, и появляется описание этого метода:

Я читаю документацию и в 3-ем параграфе раздела Description говорится, что следует как минимум установить значение для  нормального normal состояния. Звучит обнадеживающе. Теперь я хотел бы понять, как я могу получить это normal состояния, поэтому я кликаю на ссылке UIControlState?

И ссылка выводит меня на документацию по UIControlState.

Прокручиваем немного вниз, и видим normal, самая первая константа, которая называется normal.

Мы будем это изучать позже, но normal — это static var. Это свойство Типа UIControlState, и мы должны записать его следующим образом: UIControlState.normal. Это здорово, мы нашли то, что искали, но пока я нахожусь в документации, позвольте мне кратко показать вам, как работает документация.

Следуя иерархии, которая представлена в самом верху, я просматриваю документацию в разделе UIKit, в подразделе Views and Сontrols для класса UIControl, от которого наследует кнопка UIButton. И мы изучаем UIControlState.
Но я могу кликнуть где угодно, например, на Views and Сontrols и мы можем там увидеть UIButton :

Мы можем навести “мышку” на UIButton и кликнуть на ней, если мы хотим взглянуть на документацию UIButton:

Я настоятельно рекомендую прочесть все обзорные (overview) секции, которые есть в каждом классе. Это займет у вас не более 5 минут, но реально позволит понять, что происходит в том или ином классе. Я настоятельно рекомендую вам делать это для тех общераспространенных классов, которые вы используете. В данный момент это UIButton, позже будут Array и Dictionary. Обязательно читайте и вы будете понимать эти классы.
Вы можете использовать поисковую строку в верхней части экрана, и, конечно, вы можете выбрать любой метод в этом обзоре, например, уже знакомый нам метод setTitle:

Вы можете кликнуть на методе setTitle:

Мы вернулись к этому методу и видим, что здесь представлено тоже самое, что и в маленьком справочном окошке.
Теперь мы знаем, что представляет собой UIControlState, и можем вернуться к коду, установив UIControlState.normal:

Мы также хотим установить цвет фон, и я опять напечатаю точку “.”, и просто буду искать текст  “backgroundcolor”:

——- 45 -ая минута лекции ———
Посмотрите, мы нашли то, что называется точно так, как нам надо backgroundColor, который позволит нам установить цвет UIColor. Дважды кликаем на нем:

И я собираюсь установить его равным…. Хотите — верьте, хотите -нет, но я размещу здесь буквально сам цвет. Для этого вы должны начать печатать слово “color”, и выбрать первую строку в предлагаемом списке Color Literal:

Если вы дважды кликните на нем, то в коде разместится маленький квадратик и если вы кликните на нем, то появится окно, в котором вы сможете выбрать нужный вам цвет:

Давайте выберем наш прекрасный оранжевый цвет для обратной стороны карты:

Это очень здорово, когда вы можете увидеть цвет непосредственно в коде.
В противном случае, если у нас нет на карте “привидения” ?, то я хочу разместить его там. В этом случае мы будем использовать тот же самый код, но в качестве заголовка установим эмоджи emoji.
И я дважды кликаю на оранжевом квадрате, чтобы изменить цвет на белый (white) для лицевой стороны карты:

Мы его получили в коде:

Давайте запустим приложение, и посмотрим, сможет ли наша карта переворачиваться? Скрестите пальцы:

Кликаем, и карта переворачивается, опять кликаем — она возвращается в прежнее состояние. Прекрасно. Мы “на коне”!
Давайте добавим еще одну карту.  Хотите — верьте, хотите -нет, но в Interface Builder вы можете выполнять копирование (Copy)  и вставку (Paste) обычными клавишами ⌘C (Copy) и ⌘V (Paste):

Теперь у меня две карты, и вторая карта, копия, имеет точно такую же форму, размер шрифта заголовка и все остальные атрибуты.
Конечно, рекомендуется копировать и вставлять карты, а не вытягивать новую карту из Палитры Объектов и устанавливать заново все атрибуты.
Просто копирование ⌘C (Copy) и вставка ⌘V (Paste).
Но мы хотим, чтобы на новой карте был другой эмоджи, давайте разместим, например, “тыкву” (pumpkin) ?. Идем в меню Edit -> Emoji & Symbols:

И выбираем “тыкву”:

Теперь у нас две карты : карта с “тыквой” ? и карта с “привидением” ?.
Карта с “тыквой” ? также нуждается в методе для переворачивания карт.
Мы опять выполняем CTRL— перетягивание от новой кнопки в код для создания нового метода:

Если вы что-то пропустили в первый раз, то можете сейчас увидеть, как это делается.
Это Action, и я назову его touchSecondCard. Конечно, нам нужен Type, и это, конечно, же UIButton, поле ArgumentsSender:

Кликаем на кнопке “Connect”, и получаем метод touchSecondCard:

Я размещу в методе touchSecondCard точно такой же код, как и в методе touchCard, но вместо “привидения” ?, я размещу “тыкву” ?.
Код настолько простой, что все должно работать.
Давайте запустим приложение, и попробуем.

“Привидение” ? работает прекрасно, карта переворачивается и возвращается обратно, а “тыква” ? НЕ работает — карта не переворачивается …
Что же не так с “тыквой” ?? Как вообще возможно, что она не работает?
Мы могли бы подключить отладчик и установить точку прерывания, тем более, что это очень просто: достаточно кликнуть на номере строки, и вы получите точку прерывания в этом месте:

Но мы сделаем более легкую отладку, мы просто вставим печать в самое начало метода flipCard. “Тыква” ? должна вызывать этот метод, потому что она подсоединена к этому методу.
Я не буду применять отладчик, но вставлю печать с использование метода print, в котором хочу распечатать эмоджи emoji. Обычно другие языки программирования использовали бы %s или что-то подобное:

Мы не будем иметь дело с %s в Swift, у нас есть что-то получше, которым является текстовое представление объекта \( ).
Итак, \( ) означает, что если мы размещаем “что-то” внутри круглых скобок, то это “что-то” будет интерпретироваться как строка String и может быть вставлено в любую строку. Это то, что нам нужно:

Это действительно крутая вещь, в нашем случае это легко воспринимается, потому что мы вставляем строку emoji, но точно также вы можете в Swift преобразовать в строку более сложные объекты: массив Array, словарь Dictionary, при условии что они содержат элементы, которые можно преобразовать в строку String. В этом случае легко преобразуется и весь массив.
Повторю, \( ) — действительно крутая фишка.
Давайте запустим наше приложение и проверим, вызывает ли “тыква”  ? метод flipCard?

Кликаем на карте с “привидением” ?, карта переворачивается, и мы получаем сообщение на консоли о том, что сработал метод flipCard для “приведения” ?.
Теперь кликаем на “тыкве” ?:

Карта с “тыквой” ? не переворачивается и метод flipCard, похоже, вызывается дважды: сначала для “привидения” ?, а потом для “тыквы” ?. Но я не кликал дважды на карте с “тыквой” ?.
Что происходит? Очень странно.
Давайте попробуем еще раз кликнуть на “тыкве” ?:

Та же самая картина — метод flipCard для “тыквы” ? вызывается дважды.
Почему это происходит дважды?
Давайте посмотрим на метод touchSecondCard, предназначенный для “тыквы” ?:

Мы знаем, что метод touchSecondCard вызывается только “тыквой” ?.
——- 50 -ая минута лекции ———
Но метод touchCard вызывается ОБЕИМИ картами:

И в этом проблема.
Почему так произошло? Это произошло из-за того, что я копировал (⌘C Copy) и вставлял (⌘V Paste) карту с “привидением” ? для создания второй карты.  При проведении операции копирования и вставки происходит копирование всех методов. Это очень распространенная ошибка, которую очень легко сделать.
Конечно, я сделал ее намеренно, чтобы показать вам, как избавиться от нее.
Продолжение  находится здесь

Лекция 1 CS193P Fall 2017 — Введение в iOS 11, Xcode 9 и Swift 4. Часть 1.: 17 комментариев

  1. Спасибо Вам огромное за курсы! Подскажите как часто будет выходить перевод новых лекций? Думал перейти на эти или продолжить изучение прошлых.

    • Продолжайте изучение прошлых. Перевод и оформление новых Лекций — не быстрый процесс.Тем более, что прошлый курс легче и в отношении демонстрационных примеров и домашних Заданий.

  2. Спасибо большое! Очень доходчиво и понятно! Жду вторую часть.

  3. Есть ли для этого курса pdf версии лекций, как и в предыдущем курсе (iOS10)?

  4. Большое спасибо ещё раз Вам за вашу работу. Я имею доступ к первой части лекций. Разобрал 2. В начале 3 лекции он говорит:
    «Надеюсь, вы сделали ваше домашнее Задание на чтение, так что некоторая часть того, о чем я буду рассказывать, будет своего рода обзором, но другой части материалов о Swift действительно не было в вашем домашнем Задании на чтение.»
    В первой лекции есть ссылка на учебник — ОК. Но в заданиях я не могу найти заданий «на чтение». Их нет или я просто не могу тих найти?

  5. Добрый день. В начале 3 лекции профессор говорит:
    «Надеюсь, вы сделали ваше домашнее Задание на чтение, так что некоторая часть того, о чем я буду рассказывать, будет своего рода обзором, но другой части материалов о Swift действительно не было в вашем домашнем Задании на чтение.» Но в доступном задании я не могу найти «заданий на чтение». Их нет, или я просто не могу их найти?

  6. cs 108 или подобные курсы можно найти на этом сайте в переводе?

Обсуждение закрыто.