Почему git не открывает файлы на swift
Перейти к содержимому

Почему git не открывает файлы на swift

  • автор:

Не отображается файл сториборда после сброса версии остальных файлов в проекте XCode. SWIFT

Всем привет, я начинающий, не бросайте тапками пожалуйста. В общем у меня в проекте отлетел файл сториборд, случилось это после того как я наклацал чего то не того при попытке делегирования от одного контроллера к другому, посыпались ошибки которые я решить не смог, про гит хаб я до этого момента увы не слышал и мне не пришло ничего умнее, как откатить все файлы при помощи TextEdit до версии, когда все было ок, ошибки из кода пропали, но вместо сотриборда теперь просто пустой белый фон, при том, что сам файл отдельно от проекта открывается и содержит в себе все как и было, а внутри проекта- нет. Я подозреваю возможно его нужно как то заново законектить где то в системных файлах проекта но где бы это могло быть сам я не нашел, а как прикрутить сториборд обратно не нашел в гугле. Подскажите пожалуйста как прикрутить назад к проекту файл сториборда Вот так ведет себя файл вне проекта, введите сюда описание изображения А вот так отображается файл в проекте. А вот так он ведет себя в проекте К слову все файлы, которые находятся ниже меин сотриборда отображаются теперь точно так же- пустым фоном.

Отслеживать

задан 10 янв 2022 в 15:45

7 3 3 бронзовых знака

отдельно от проекта открывается и содержит в себе все как и было — открывается в текстовом редакторе в виде xml или в икскоде в виде макета?

10 янв 2022 в 16:02

Именно в икскоде и там все так как и было в самом проекте

10 янв 2022 в 16:33

Не совсем понятно как он у вас «отлетел», если он все же открывается вне проекта (и в проект я как понимаю тоже при этом добавлен?). Неплохо бы взглянуть на скриншот, как он сейчас отображается в проекте

10 янв 2022 в 18:35

Добавил скрины в сам вопрос. Заметил еще что не отображаются и все вкладки ниже файла сториборда

GitHub: открытие файлов из Pull Request’ов и веток

По горячим следам чекаута Pull Request’ов, теперь вы можете открывать файлы в GitHub for Mac и GitHub for Windows прямо из Pull Request’ов и веток!

Теперь в Pull Request’ах появилась кнопка «Открыть» («Open»):

pr-open-file

И в интерфейсе просмотра файлов из веток:

branch-open-file

:pencil:

Клик на по этой кнопке откроет GitHub for Mac или GitHub for Windows, склонирует репозиторий (если у вас его еще нет), автоматически переключится на ветку, которая содержит эти изменения и, наконец, откроет файл для редактирования в приложении, ассоциированном с этим типом файлов.
Мы надеемся, что теперь вам будет легче комментировать Pull Request’ы!

  • Веб-разработка
  • Программирование
  • Git

Инструкция: как скачать файл с GitHub

Закройте IDE. Забудьте про пуши. Отрекитесь от коммитов и репозиториев.

Кадр: сериал «Остановись и гори»

Максим Сафронов

Максим Сафронов

Автор, редактор, IT-журналист. Рассказывает о новых технологиях, цифровых профессиях и полезных инструментах для разработчиков. Любит играть на электрогитаре и программировать на Swift.

Если вы откроете файл в веб-версии GitHub, то заметите, что там нет отдельной кнопки «Скачать». Действительно, удобного способа загружать код напрямую с сайта разработчики не завезли, но есть альтернативные способы — в этой статье как раз о них поговорим. Заодно разберёмся, как скачивать файлы с GitHub на смартфон — пока только на Android-устройства, с айфонами всё сложно.

Способ первый

Скачать проект целиком

Все проекты на GitHub хранятся в репозиториях. Репозиторий — это место, где лежат файлы, библиотеки и фрагменты кода программы. Хорошая новость: если у вас есть доступ к проекту, его можно утащить себе на компьютер и разобрать на отдельные файлы. Вот как это сделать:

Шаг 1. Выберите проект, который хотите скачать. Ваши репозитории хранятся в разделе Your repositories, а проекты из свободного доступа можно найти с помощью окошка Search or jump to.

Шаг 2. Откройте выбранный проект. Мы, например, решили забрать себе классический «виндовый» калькулятор, с недавних пор выложенный в открытый доступ в аккаунте Microsoft.

Шаг 3. Нажмите кнопку Code в правом верхнем углу. Выпадет меню, в котором нужно выбрать Download ZIP.

Готово! Теперь у нас на компьютере есть собственная версия проекта. Можно запустить его в Visual Studio, а также в другом редакторе кода или IDE и допилить под свои нужды. Например, перекрасить кнопки в фиолетовый цвет — а почему бы и нет? ��

Способ второй

Скачать файл с GitHub через Raw

Единственный штатный способ скачать отдельный файл в GitHub — это кнопка Raw. Она превращает код файла в обычный текстовый документ без всякой разметки — в таком виде его можно легко загрузить на жёсткий диск. Не слишком удобный, но рабочий способ — давайте его тоже разберём.

Шаг 1. В репозитории проекта откройте файл, который хотите скачать.

Шаг 2. Когда файл откроется, нажмите кнопку Raw.

Шаг 3. Перед вами — исходный код файла, открытый в браузере. Чтобы его скачать, нажмите правой кнопкой мыши, а потом выберите «Сохранить как…».

Шаг 4. В открывшемся окне можно задать файлу имя и формат. Если планируете работать с кодом в текстовом редакторе, можно оставить .txt.

Способ третий

Использовать расширение

В интернет-магазинах браузеров полно расширений, которые облегчают загрузку с GitHub. Например, GitZip for GitHub помогает скачивать не только файлы, но и целые папки. Рассказываем, как им пользоваться:

Шаг 1. Скачайте и установите утилиту в магазине расширений вашего браузера — есть версии для Chrome, Microsoft Edge и Mozilla.

На заметку: если расширение доступно для Chrome, то запустить его можно в любом браузере, работающем на хромовском движке Blink, — например, в Opera, Vivaldi или «Яндекс.Браузере».

Шаг 2. В репозитории проекта напротив каждого файла появятся чекбоксы — отметьте галочками те, которые хотите скачать.

Шаг 3. Нажмите на кнопку загрузки в правом нижнем углу.

Готово! Можно наслаждаться новыми возможностями до боли знакомого сервиса.

Бонус: как скачивать файлы из GitHub на Android-устройствах

По умолчанию в мобильной версии GitHub нет функции скачивания файлов. Но её можно активировать, если открыть в мобильном браузере версию сайта для ПК. После этого можно будет скачать отдельный файл либо весь проект в виде ZIP-архива.

Если нужен проект целиком:

Шаг 1. Откройте веб-страницу нужного репозитория через Google Chrome.

Шаг 2. В контекстном меню браузера нажмите на кнопку «Версия для ПК».

Шаг 3. После этого страница перезагрузится и откроется обычная десктопная версия сайта. Нажмите зелёную кнопку Code, а потом — Download ZIP.

Если нужен отдельный файл:

Шаг 1. Откройте на GitHub страницу файла и активируйте версию для ПК.

Шаг 2. Когда откроется десктопная версия страницы, нажмите кнопку Raw в правом верхнем углу.

Шаг 3. Снова вызовите контекстное меню браузера и нажмите на значок загрузки в самом верху — после этого на смартфон скачается нужный файл в формате .txt.

К сожалению, на iOS десктопная версия GitHub не открывается ни в одном браузере, поэтому функции Raw и Download ZIP недоступны. Если у вас есть рабочий способ — напишите нам в редакцию, добавим его в статью.

Что дальше

В этой статье мы обсудили нюансы работы только с веб-версией GitHub. Если хотите полностью перенести проект на свой компьютер и работать с ним локально, почитайте нашу статью про GitHub Desktop. Вы узнаете, как создать репозиторий, синхронизировать его с ПК и обновлять файлы удалённо.

Ещё можно почитать материал про систему контроля версий Git. Объясняем на понятных схемах, как работает технология, которая лежит в основе GitHub и других похожих сервисов. Вы поймёте, как там всё устроено, и сможете блеснуть знаниями на собеседовании.

Больше интересного про код в нашем телеграм-канале. Подписывайтесь!

Saved searches

Use saved searches to filter your results more quickly

Cancel Create saved search

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Гайдлайн по разработке iOS-приложения на Swift

ILYA2606/SwiftGuideline

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Switch branches/tags
Branches Tags
Could not load branches
Nothing to show
Could not load tags
Nothing to show

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Cancel Create

  • Local
  • Codespaces

HTTPS GitHub CLI
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

Latest commit message
Commit time

README.md

Гайдлайн по разработке iOS-приложения на Swift

Русифицированный и немного измененный гайдлайн от raywenderlich.com

Оглавление

  • Начнем с перфекционизма
  • Ширина страницы
  • Именование
    • Методы
    • Булевы
    • Префиксы класса
    • Делегаты
    • Зависимый от типа контекст
    • Обобщения
    • Язык
    • Соответствие протокола
    • Неиспользованный код
    • Минимальный импорт
    • Использование self
    • Вычисляемые свойства
    • Использование final
    • Константы
    • Статические методы и свойства типа переменных
    • Необязательные значения
    • Ленивая инициализация
    • Вывод типа
    • Синтаксический сахар
    • Массивы и словари
    • Продление срока жизни объекта
    • Обработка guard

    Начнем с перфекционизма

    Как бы это ни звучало банально – всегда старайтесь компилировать свой код без предупреждений (warnings).

    Ширина страницы

    Установите ширину страницы в 120 символов (Xcode / Preferences / Text Editing / Page guide at column). Это значение рекомендуется включить в соответствующем правиле в SwiftLint. Таким образом, весь код будет умещаться в заданную ширину страницы и будет более читабельным.

    Именование

    Правильное именование упрощает чтение и понимание кода. Используйте соглашения именования в Swift, описанные в API Design Guidelines. Некоторые ключевые особенности включают:

    • Стремитесь к ясности при вызовах
    • Выбирайте приоритет ясности перед крайностью
    • Используйте camelCase, а не snake_case
    • Используйте верхний регистр для типов и протоколов, нижний регистр для всего остального
    • Включайте только необходимые слова, при этом избегая лишних
    • Используйте именование на основе роли, а не типа, но при этом по наименованию объекта должно быть понятен его тип (contactsView, nameLabel, descriptionViewHeightConstraint)
    • Иногда давайте расширенную информацию для типов со слабой ссылкой
    • Стремитесь к свободному использованию
    • Начинайте фабричные методы через “make” (Например, makeProduct )
    • Методы именования:
      • методы в форме глагола следуют правилу -ed, -ing для неизменяемого объекта (Например, sorted )
      • методы в форме глагола следуют правилу первой формы для изменяемого объекта (Например, sort )
      • булевы типы должны читаться, как утверждения (Например, isEnabled )
      • протоколы должны описывать существительные (Например, Sphere -> Spherable )
      • протоколы, описывающие возможность, должны заканчиваться в -able или -ible (Например, Fuckable )
      • Массивы с суффиксом множественного числа (Например, names , userIDs , mainIndexes )
      • Словари с суффиксом Map (Например, userRatingMap )
      • Множества с суффиксом Set (Например, imageSet )

      Методы

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

      Пишите имя метода без параметров (Например, addTarget ) Пишите имя метода с метками аргументов (Например, addTarget(:action:) ) Пишите полное имя метода с метками и типами аргументов (Например, addTarget(_: Any?, action: Selector?) ) В приведенном выше примере с использованием UIGestureRecognizer вариант 1 более однозначен и предпочтителен.

      Совет: Можно использовать панель перехода Xcode для поиска методов с метками аргументов.

      Methods in Xcode jump bar

      Булевы

      Для булевых переменных принято использовать вспомогательный глагол в начале.

      Рекомендуется:

      var isFavoriteCategoryFilled: Bool var hasRoaming: Bool var isBlocked: Bool

      Не рекомендуется:

      var favoriteCategoryFilled: Bool var roaming: Bool var blocked: Bool

      Префиксы класса

      Типы Swift автоматически называются модулем, в котором они содержатся, и вы не должны добавлять префикс класса, например DP. Если сталкиваются два имени из разных модулей, вы можете сделать различие, предварительно указав имя типа с именем модуля. Вводите имя модуля только в том случае, если существует вероятность путаницы, которая должна быть крайне редкой.

      import SomeModule let myClass = MyModule.UsefulClass()

      Делегаты

      При создании пользовательских методов делегата первый параметр должен быть параметром делегата (UIKit содержит многочисленные примеры подобного).

      Рекомендуется:

      func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String) func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool

      Не рекомендуется:

      func didSelectName(namePicker: NamePickerViewController, name: String) func namePickerShouldReload() -> Bool

      Зависимый от типа контекст

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

      Рекомендуется:

      let selector = #selector(viewDidLoad) view.backgroundColor = .red let toView = context.view(forKey: .to) let view = UIView(frame: .zero)

      Не рекомендуется:

      let selector = #selector(ViewController.viewDidLoad) view.backgroundColor = UIColor.red let toView = context.view(forKey: UITransitionContextViewKey.to) let view = UIView(frame: CGRect.zero)

      Обобщения

      Имена обобщений должны быть понятными и в формате UpperCamelCase. Если имя типа не имеет значимой роли, используйте традиционную одиночную прописную букву, такую как T , U или V .

      Рекомендуется:

      struct StackElement> < . > func writeTarget: OutputStream>(to target: inout Target) func swapT>(_ a: inout T, _ b: inout T)

      Не рекомендуется:

      struct StackT> < . > func writetarget: OutputStream>(to target: inout target) func swapThing>(_ a: inout Thing, _ b: inout Thing)

      Язык

      Возьмите за основу американско-английское правописание в соответствии с API Apple.

      Рекомендуется:

      let color = "red"

      Не рекомендуется:

      let colour = "red"

      Организация кода

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

      Лучше соблюдать следующую последовательность:

      // MARK: - Types // MARK: - Constants // MARK: - IBOutlets // MARK: - Public Properties // MARK: - Private Properties // MARK: - UIViewController(*) // MARK: - Public Methods // MARK: - IBActions // MARK: - Private Methods 

      (*)Вместо UIViewController вы должны написать другой суперкласс, от которого вы наследуетесь.

      Соответствие протокола

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

      Рекомендуется:

      class MyViewController: UIViewController < // код класса > // MARK: - UITableViewDataSource extension MyViewController: UITableViewDataSource < // методы датасорса > // MARK: - UIScrollViewDelegate extension MyViewController: UIScrollViewDelegate < // методы делегата >

      Не рекомендуется:

      class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate < // все методы >
      • Когда вам нужен метод переопределения, который реализован в другом расширении
      • Когда вы используете класс с обобщениями и Objective-C протоколами с дополнительными методами (@objc не поддерживается в расширениях Generic-классов или классов, которые наследуются от Generic-классов)

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

      Для наследников UIViewController можно рассмотреть разложение в отдельные расширения: жизненный цикл, пользовательские аксессоры и IBActions.

      Неиспользованный код

      Неиспользованный (мертвый) код, включая код шаблона Xcode и комментарии к заполнению, должен быть удален. За исключением того, что вы пишете учебник, где даете указание читателю использовать прокомментированный код.

      Методы, непосредственно не связанные с учебником, реализация которых просто вызывает суперкласс, также должны быть удалены. Сюда входят любые пустые/неиспользуемые методы UIApplicationDelegate.

      Рекомендуется:

      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int < return Database.contacts.count >

      Не рекомендуется:

      override func didReceiveMemoryWarning() < super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. > override func numberOfSections(in tableView: UITableView) -> Int < // #warning Incomplete implementation, return the number of sections return 1 > override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int < // #warning Incomplete implementation, return the number of rows return Database.contacts.count >

      Минимальный импорт

      Соблюдайте минимальное количество импортов. Например, опустите импорт Foundation , если импортируете UIKit .

      Отступы

      • Отступ использует 4 пробела, а не табуляцию, чтобы сохранить пространство и помочь предотвратить обертку строк. Для этого надо убедиться, что выбрана соответствующая опция в Xcode (Preferences / Text Editing / Indentation / Prefer Indent using: Spaces, и Tab width: 4)
      • Обычные и фигурные скобки (в if / else / switch / while и т.д.) всегда открываются в той же строки, что и оператор, но закрываются на новой строке
      • Совет: Можно автоматически применить корректный отступ, выделив нужный код, а затем нажав Control-I (или Editor/Structure/Re-Indent)

      Рекомендуется:

      if user.isHappy < // что-то сделаем > else < // сделаем что-то другое >

      Не рекомендуется:

      if user.isHappy < // что-то сделаем > else < // сделаем что-то другое >
      • Должна быть ровно одна пустая строка между методами, помогающими визуальной ясности и организации. Пропуски внутри методов должны разделять функциональность, но наличие слишком большого их количества в методе часто означает, что вы должны отрефакторить этот метод
      • Двоеточия всегда не имеют пробела слева, но имеют один справа. Исключением является тройной оператор ? : , пустой словарь [:] и синтаксис #selector для неназванных параметров (_:) .

      Рекомендуется:

      class TestDatabase: Database < var dataMap: [String: CGFloat] = ["A": 1.2, "B": 3.2] >

      Не рекомендуется:

      class TestDatabase : Database < var dataMap :[String:CGFloat] = ["A" : 1.2, "B":3.2] >
      • В идеале, длинные строки должны быть в пределах 70 символов. Тем не менее, жесткого ограничения нет
      • Пробелов на концах строк быть не должно
      • В конце каждого файла должна быть одна пустая строка

      Комментарии

      При необходимости, используйте комментарии, чтобы объяснить, почему какой-то фрагмент кода что-то делает. Комментарии должны быть обновлены до текущего состояния кода или удалены совсем.

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

      Классы и структуры

      Что использовать?

      Структуры имеют семантику значений. Используйте структуры для вещей, которые не имеют личности. Массив, содержащий [a, b, c], действительно тот же, что и другой массив, содержащий [a, b, c], и они полностью взаимозаменяемы. Неважно, используете ли вы первый массив или второй, потому что они представляют собой то же самое. Вот почему массивы – это структуры.

      Классы имеют ссылочную семантику. Используйте классы для вещей, которые имеют личность или определенный жизненный цикл. Можно моделировать человека как класс, потому что объекты двух людей – две разные вещи. Все потому, что если у двух людей одно и то же имя и дата рождения, то это не значит, что они одни и те же. Но дата рождения человека была бы структурой, потому что дата 3 марта 1950 года такая же, как и любой другой объект даты 3 марта 1950 года. Сама дата не имеет личности.

      Иногда вещи должны быть структурами, но при этом должны соответствовать AnyObject или исторически моделироваться уже как классы ( NSDate , NSSet ). Старайтесь как можно ближе следовать этим рекомендациям.

      Пример определения

      Вот пример хорошо продуманного определения класса:

      class Circle: Shape < var x: Int, y: Int var radius: Double var diameter: Double < get < return radius * 2 > set < radius = newValue / 2 > > init(x: Int, y: Int, radius: Double) < self.x = x self.y = y self.radius = radius > convenience init(x: Int, y: Int, diameter: Double) < self.init(x: x, y: y, radius: diameter / 2) > override func area() -> Double < return Double.pi * radius * radius > > extension Circle: CustomStringConvertible < var description: String < return "center = \(centerString) area = \(area())" > private var centerString: String < return "(\(x),\(y))" > >

      Пример выше демонстрирует следующие стили:

      • Указывайте типы для свойств, переменных, констант, объявлений аргументов и других операторов с пробелом после двоеточия, например. x: Int и Circle: Shape .
      • Определяйте несколько переменных и структур в одной строке, если они имеют общую цель/контекст
      • Определение геттера и сеттера, а также наблюдателя свойств
      • Не добавляйте модификаторы доступа, такие как internal , если они уже установлены по умолчанию. Аналогичным образом не следует повторять модификатор доступа при переопределении метода
      • Организовывайте дополнительную функциональность (например, печать) в расширениях
      • Скрывайте данные реализации, не связанные с общим доступом, такие как centerString внутри расширения с помощью частного контроля доступа

      Использование self

      Для краткости кода избегайте использования self , так как Swift не требует доступа к свойствам объекта или вызова его методов.

      Используйте self только тогда, когда это требуется компилятором (в сбегающих @escaping замыканиях или в инициализаторах для устранения неоднозначности свойств из аргументов). Другими словами, если код компилируется без self , опустите его.

      Вычисляемые свойства

      Если вычисляемое свойство доступно только для чтения, опустите get . Предложение get требуется только тогда, когда предоставляется предложение set .

      Рекомендуется:

      var diameter: Double < return radius * 2 >

      Не рекомендуется:

      var diameter: Double < get < return radius * 2 > >

      Всегда используйте вычисляемое свойство вместо метода без аргументов и побочных эффектов.

      Рекомендуется:

      var homeFolderPath: Path < //. return path >

      Не рекомендуется:

      func homeFolderPath() -> Path < //. return path >

      Использование Final

      Маркировка классов как final в примерах может отвлекать от основной темы и не всегда требуется. Тем не менее, использование final может иногда уточнять ваши намерения и стоит затрат. В приведенном ниже примере Box имеет особую цель, и расширение в виде производного класса не предназначено. Пометка final делает это более понятным.

      final class BoxT> < let value: T init(_ value: T) < self.value = value > >

      Также это улучшает чтение кода и ускоряет компиляцию.

      Объявление и вызов функций

      Сохраняйте короткие объявления функций или типов на одной строке, включая открывающую фигурную скобку:

      func method(parameter: [Double]) -> Bool < // . >

      Для функций надо добавить переносы строк для каждого аргумента, включая первый, если они превышают руководство по ширине страницы. Для того, чтобы аргументы визуально не сливались с телом метода (ведь они с одним отступом), переносите завершающую скобку также на новую строку:

      func method( parameter1: [Double], parameter2: Double, parameter3: Int ) -> Bool < // . >

      Это же правило применяется и для вызовов функций.

      let result = method( parameter1: parameter1, parameter2: parameter2, parameter3: parameter3 )

      Оставьте одну пустую строку между функциями и одну до и после MARK

      func colorView() < //. > func reticulate() < //. > // MARK: - Private Methods private func retry() < //. >

      Выражения замыканий

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

      Рекомендуется:

      UIView.animate(withDuration: 1.0) < // . > UIView.animate( withDuration: 1.0, animations: < // . >, completion: < finished in // . >)

      Не рекомендуется:

      UIView.animate(withDuration: 1.0, animations: < // . >) UIView.animate(withDuration: 1.0, animations: < // . >) < (f: Bool) in // . >

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

      participants.sort < a, b in a > b >

      Связанные методы с использованием закрывающих замыканий должны быть понятными и легко читаемыми. Примеры:

      let value = numbers .map < $0 * 2 > .filter < $0 > 50 > .map < $0 + 10 >

      Типы

      Всегда используйте родные типы Swift, когда они доступны. Swift предлагает ассоциацию к типам Objective-C, поэтому вы можете использовать полный набор методов по мере необходимости.

      Рекомендуется:

      let width: Double = 120 // Double let widthString = (width as NSNumber).stringValue // String

      Не рекомендуется:

      let width: NSNumber = 120.0 // NSNumber let widthString: NSString = width.stringValue // NSString

      В коде SpriteKit используйте CGFloat , т.к. он сделает код более кратким, избегая слишком большого количества преобразований.

      Константы

      Константы определяются с помощью ключевого слова let , а переменные – var . Всегда используйте let вместо var , если значение переменной не изменится.

      Совет: Есть неплохая техника, когда определяете объекты, используя let , и изменяете его на var , если компилятор начнет ругаться.

      Вы можете определить константы для типа, а не для экземпляра этого типа, используя свойства типа. Чтобы объявить свойство типа как константу, просто используйте static let . Свойства типа, объявленные таким образом, намного лучше, чем глобальные константами, потому что их легче отличить от свойств экземпляра. Пример:

      Рекомендуется:

      enum Math < static let e = 2.718281828459045235360287 static let root2 = 1.41421356237309504880168872 > let hypotenuse = side * Math.root2

      Не рекомендуется:

      let e = 2.718281828459045235360287 // портит глобальное пространство имен let root2 = 1.41421356237309504880168872 let hypotenuse = side * root2 // что за root2?

      Если уж приспичило использовать глобальное пространство имен, то советуем именовать в следующем формате:

      Рекомендуется:

      let TopMargin: CGFloat = 10

      Не рекомендуется:

      let kTopMargin: CGFloat = 10 let bottomMargin: CGFloat = 100 

      Статические методы и свойства типа переменных

      Статические методы и свойства типа работают аналогично глобальным функциям и глобальным переменным, также должны использоваться экономно. Они полезны, когда функциональность привязана к определенному типу или когда требуется совместимость с Objective-C.

      Необязательные значения

      Можно объявлять переменные и возвращаемые типы функций как необязательные ? , где допустимо значение nil .

      Используйте неявно развернутые типы, объявленные с помощью ! только тогда, когда заранее известно, что они будут инициализированы раньше, чем будут использованы. Например, subviews , которые будут установлены во viewDidLoad .

      При доступе к необязательному значению используйте необязательную цепочку:

      self.textContainer?.textLabel?.setNeedsDisplay()

      Используйте также дополнительную связку if let , когда удобнее разворачивать значение и выполнять несколько операций:

      if let textContainer = self.textContainer < // . >

      При наименовании необязательных переменных и свойств избегайте указывать их необязательность, например, optionalString или maybeView , поскольку их необязательность уже указана в объявлении типа.

      Для объектов развернутых типов не используй такие имена, как unwrappedView или actualLabel . Также лучше добавить новую строку после if, если в разделе разворачивания есть несколько переменных.

      Рекомендуется:

      var subview: UIView? var volume: Double? // позднее. if let subview = subview, let volume = volume < // что-то сделать с развернутыми subview и volume >

      Не рекомендуется:

      var optionalSubview: UIView? var volume: Double? if let unwrappedSubview = optionalSubview < if let realVolume = volume < // что-то сделать с развернутыми unwrappedSubview и realVolume > >

      Ленивая инициализация

      Рассмотрите возможность использования ленивой инициализации для более тонкого контроля за временем жизни объекта. Это особенно актуально для UIViewController , который лениво загружает вьюшки. Можно использовать замыкание, которое немедленно вызовится < >() или вызвать фабричный метод. Пример:

      lazy var locationManager: CLLocationManager = self.makeLocationManager() private func makeLocationManager() -> CLLocationManager < let manager = CLLocationManager() manager.desiredAccuracy = kCLLocationAccuracyBest manager.delegate = self manager.requestAlwaysAuthorization() return manager >

      Примечания:

      • [unowned self] здесь не требуется. Retain-цикл не создается
      • У менеджера местоположений есть побочный эффект для появления пользовательского интерфейса, чтобы спросить у пользователя разрешение, поэтому подобный тонкий контроль здесь имеет смысл

      Вывод типа

      Всегда предпочитайте компактный код и пусть компилятор сам выводит тип для констант или переменных отдельных экземпляров. Вывод типа также подходит для небольших массивов и словарей. При необходимости можно указать конкретный тип, например CGFloat и Int16 .

      Рекомендуется:

      let message = "Click the button" let currentBounds = computeViewBounds() var names = ["Mic", "Sam", "Christine"] let maximumWidth: CGFloat = 106.5

      Не рекомендуется:

      let message: String = "Click the button" let currentBounds: CGRect = computeViewBounds() let names = [String]()
      Тип аннотации для пустых массивов и словарей

      Для пустых массивов и словарей не надо использовать аннотацию типа.

      Рекомендуется:

      var names: [String] = [] var lookupMap: [String: Int] = [:]

      Не рекомендуется:

      var names = [String]() var lookupMap = [String: Int]()

      Синтаксический сахар

      Используйте краткие версии объявлений типа, используя синтаксис обобщений.

      Рекомендуется:

      var deviceModels: [String] var employeeMap: [Int: String] var faxNumber: Int?

      Не рекомендуется:

      var deviceModels: ArrayString> var employeeMap: DictionaryInt, String> var faxNumber: OptionalInt>

      Массивы и словари

      Используйте следующий перенос, когда массив или словарь не умещаются по ширине страницы:

      Рекомендуется:

      let deviceModelMap = ["BMW": 100, "Mercedes": 120] let wheels = [ "Continental", "Vitoria", . ]

      Не рекомендуется:

      let wheels = ["Continental", "Vitoria", // параметры, превышающие ширину страницы]

      Функции против методов

      Свободные функции, которые не привязаны к классу или типу, должны использоваться крайне осторожно. Когда это возможно, используйте метод вместо свободной функции. Это помогает в удобочитаемости и открытости.

      Свободные функции наиболее подходят, если они не связаны с каким-либо конкретным типом или экземпляром.

      Рекомендуется

      let sortedItems = items.mergeSorted() // легко найти rocket.launch() // воздействует только на модель

      Не рекомендуется

      let sortedItems = mergeSort(items) // сложно найти launch(&rocket)

      Исключения для свободных функций

      let tuples = zip(a, b) let value = max(x, y, z)

      Управление памятью

      Код не должен создавать retain-циклы. Нужно проанализировать график объектов (Xcode / Debug navigator / View Memory Graph Hierarchy) и предотвратить strong-циклы с помощью weak или unowned ссылками. Кроме того, можно использовать типы значений ( struct , enum ) для предотвращения циклов.

      Продление срока жизни объекта

      Продлите срок жизни объекта, используя [weak self] и guard let `self` = self else < return >(если это необходимо). Лучше использовать [weak self] , нежели [unowned self] , т.к. не всегда понятно, что self к этому моменту будет жить. Продление срока жизни объекта – это рекомендуемый вариант для необязательного разворачивания.

      Рекомендуется

      resource.request().onComplete < [weak self] response in guard let self = self else < return > let model = self.updateModel(response) self.updateUI(model) >

      Не рекомендуется

      // будет сбой, если self будет освобожден (выгружен из памяти) в момент выполнения замыкания resource.request().onComplete < [unowned self] response in let model = self.updateModel(response) self.updateUI(model) >

      Не рекомендуется

      // освобождение self может произойти между обновлением модели и обновлением пользовательского интерфейса, если обновление модели происходит не в главном потоке resource.request().onComplete < [weak self] response in let model = self?.updateModel(response) self?.updateUI(model) >

      Контроль доступа

      Аннотации полного контроля доступа в учебниках могут отвлекать от основной темы и в общем-то не требуются. Однако использование private и fileprivate , таким образом, добавляет ясности и способствует инкапсуляции. Лучше использовать private , нежели fileprivate , если это возможно. Использование расширений может потребовать использования fileprivate .

      Можно явно использовать open , public и internal , когда вам требуется полная спецификация контроля доступа.

      Используйте контроль доступа в качестве первичного спецификатора свойств. Исключения составляют лишь static или атрибуты, такие как @IBAction , @IBOutlet , @discardableResult и @IBInspectable .

      Рекомендуется:

      private let message = "Great Scott!" class TimeMachine < fileprivate dynamic lazy var fluxCapacitor = FluxCapacitor() >

      Не рекомендуется:

      fileprivate let message = "Great Scott!" class TimeMachine < lazy dynamic fileprivate var fluxCapacitor = FluxCapacitor() >

      Поток управления

      Лучше использовать стиль for-in для цикла for , нежели стиль while-condition-increment .

      Рекомендуется:

      for _ in 0 .. 3 < print("Hello three times") > for (index, person) in participants.enumerated() < print("\(person) is at position #\(index)") > for index in stride(from: 0, to: items.count, by: 2) < print(index) > for index in (0 . 3).reversed() < print(index) >

      Не рекомендуется:

      var i = 0 while i  3 < print("Hello three times") i += 1 > var i = 0 while i  participants.count < let person = participants[i] print("\(person) is at position #\(i)") i += 1 >

      Золотой путь

      При написании кода с условными обозначениями левый край кода должен быть, как говорят, «золотым». То есть, не надо добавлять лишние операторы if , заменив их на операторы множественного возврата. Для этого был создан оператор guard .

      Рекомендуется:

      func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies < guard let context = context else < throw FFTError.noContext > guard let inputData = inputData else < throw FFTError.noInputData > // используем context и inputData для подсчета frequencies return frequencies >

      Не рекомендуется:

      func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies < if let context = context < if let inputData = inputData < // используем context и inputData для подсчета frequencies return frequencies > else < throw FFTError.noInputData > > else < throw FFTError.noContext > >

      Использование guard

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

      Рекомендуется:

      if isTrue(), isFalse(), tax > MinTax < // . >

      Не рекомендуется:

      if a > b && b > c && tax > MinTax && currentValue > MaxValue < // . >

      Когда несколько опций раскрываются через guard или if let , то вложенность заметно сокращается. Пример:

      Рекомендуется:

      guard let number1 = number1, let number2 = number2, let number3 = number3 else < clean() fatalError("impossible") > // что-то делаем

      или можно использовать вариант else в одну строку, если внутри всего один оператор

      guard let number1 = number1, let number2 = number2 else < return > // что-то делаем

      или однострочный вариант, если условие всего одно

      or one-liner with one let operation

      guard let number1 = number1 else < return >

      Не рекомендуется:

      if let number1 = number1 < if let number2 = number2 < if let number3 = number3 < // что-то делаем > else < fatalError("impossible") > > else < fatalError("impossible") > > else < fatalError("impossible") >

      Обработка guard

      Операторы guard обязаны каким-то образом обозначить выход. Как правило, это должен быть простой однострочный оператор, такой как return , throw , break , continue , или fatalError() . Следует избегать больших блоков кода. Если для нескольких точек выхода требуется код очистки, стоит использовать defer , чтобы избежать дублирования кода очистки.

      Точки с запятой

      Swift не требует точки с запятой после каждого оператора в вашем коде. Они необходимы только в том случае, если вы хотите объединить несколько операторов в одной строке. Но это делать крайне нежелательно.

      Рекомендуется:

      let swift = "not a scripting language"

      Не рекомендуется:

      let swift = "not a scripting language";

      Примечание: Swift is very different from JavaScript, where omitting semicolons is считается опасным занятием

      Круглые скобки

      Скобки вокруг выражений не требуются и их следует опустить.

      Рекомендуется:

      if name == "Hello" < print("World") >

      Не рекомендуется:

      if (name == "Hello") < print("World") >

      В больших выражениях необязательные круглые скобки иногда могут сделать код более понятным.

      Рекомендуется:

      let isPlayerMarked = (player == current ? "X" : "O") && player.active

      Формат организации и Bundle Identifier

      В случае использования проекта Xcode организация должна быть настроена на вашу компанию/имя, также Bundle Identifier должен быть в формате domain.companyName.appName , где domain – доменная зона проекта, обычно соотствует доменной зоне сайта компании, например, com, companyname – наименование компании (обычно в нижнем регистре), appName – название вашего проекта (обычно в формате UpperCamelCase)

      Xcode Project settings

      Ссылки

      • The Swift API Design Guidelines
      • The Swift Programming Language
      • Using Swift with Cocoa and Objective-C
      • Swift Standard Library Reference

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *