Разработка приложений для macOS: полное руководство по Xcode

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • начинающие разработчики, желающие освоить создание приложений для macOS
  • опытные программисты, стремящиеся повысить свои навыки в использовании Xcode и фреймворков Apple
  • студенты и специалисты, интересующиеся профессией разработчика ПО для платформы Apple

    Вхождение в мир разработки приложений для macOS — это как получение ключей от элитного клуба с особыми правилами, инструментами и возможностями. Xcode — это не просто IDE, это билет в экосистему Apple, где создание программного обеспечения превращается в строго регламентированный, но при этом удивительно мощный процесс. Если вы хотите выйти за рамки обычного программирования и создавать приложения, которые органично вписываются в философию Apple, вам необходимо освоить этот инструмент. В этом руководстве я проведу вас через все ключевые этапы разработки для macOS — от установки среды до публикации готового приложения в Mac App Store. 🚀

Хотите расширить свои навыки разработки за пределы macOS? Курс Обучение веб-разработке от Skypro даст вам фундаментальные знания, которые отлично дополнят ваши навыки в Xcode. Веб-технологии часто интегрируются с нативными приложениями, создавая гибридные решения. Освоив обе стороны разработки, вы станете более универсальным и ценным специалистом, способным создавать комплексные продукты для любых платформ.

Настройка Xcode для разработки macOS-приложений

Прежде чем погрузиться в мир разработки приложений для macOS, необходимо правильно настроить рабочую среду. Xcode — это не просто редактор кода, а комплексная среда разработки, которая требует определенной конфигурации для эффективной работы с проектами macOS. 💻

Начнем с базовых шагов установки:

  1. Установка Xcode — загрузите последнюю версию из Mac App Store или с портала разработчиков Apple Developer. Текущая стабильная версия — Xcode 15.
  2. Регистрация Apple ID — для полноценной разработки вам понадобится аккаунт в программе Apple Developer. Базовый аккаунт бесплатный, но для публикации приложений потребуется платная подписка ($99/год).
  3. Установка дополнительных компонентов — после первого запуска Xcode предложит загрузить необходимые компоненты, включая симуляторы и инструменты командной строки.
  4. Настройка подписи кода (Code Signing) — создайте или импортируйте сертификаты разработчика в Keychain Access.

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

Настройка Рекомендуемое значение Причина
Тема интерфейса Темная Снижает нагрузку на глаза при длительной работе
Font Size 13-14pt Оптимальный баланс между читабельностью и экономией пространства
Tab width 4 пробела Стандарт для Swift кода
Code folding Включено Помогает управлять видимостью больших блоков кода
Behaviors Настроить действия при ошибках компиляции Автоматически показывает релевантные панели при определённых событиях

Важным аспектом является настройка системы контроля версий. Xcode имеет встроенную поддержку Git, которую стоит активировать в настройках. Для этого:

  1. Откройте Preferences (⌘+,)
  2. Перейдите в раздел Source Control
  3. Активируйте опцию "Enable Source Control"
  4. Настройте интеграцию с GitHub, GitLab или Bitbucket

Для эффективной разработки macOS-приложений рекомендую также установить несколько полезных плагинов и инструментов:

  • Alcatraz — менеджер пакетов для Xcode (для версий до Xcode 8)
  • CocoaPods или Swift Package Manager — для управления зависимостями
  • Realm Studio — для работы с базами данных Realm
  • Charles или Proxyman — для отладки сетевых запросов
  • Fastlane — для автоматизации процессов сборки и деплоя

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

Александр Петров, Senior macOS Developer

Помню свой первый опыт настройки Xcode для серьезного проекта — это было настоящим испытанием. Работая над приложением для обработки медицинских данных, я столкнулся с проблемой: проект компилировался на моей машине, но коллеги получали странные ошибки. Оказалось, что причина была в разных настройках Code Signing и использовании разных версий библиотек.

После этого случая я разработал для команды стандарт настройки среды: специальный скрипт, который устанавливал все необходимые зависимости через Homebrew, правильно конфигурировал CocoaPods и даже настраивал Git Hooks для автоматической проверки стиля кода. Когда новый разработчик присоединялся к команде, он запускал этот скрипт и получал полностью готовую среду разработки за 15 минут вместо нескольких часов ручной настройки.

Этот опыт научил меня, что правильная настройка Xcode — это не просто предпочтения разработчика, а критически важный шаг для успешной командной работы над macOS-приложениями.

Пошаговый план для смены профессии

Создание первого проекта в Xcode: интерфейс и структура

После настройки среды разработки пришло время создать первый проект. Xcode предоставляет несколько шаблонов для различных типов macOS-приложений. Для нашего пошагового руководства мы создадим стандартное приложение с графическим интерфейсом. 🖥️

Чтобы создать новый проект:

  1. Запустите Xcode и выберите "Create a new Xcode project" на начальном экране или через меню File > New > Project
  2. В разделе macOS выберите "App" (или "Cocoa App" в более старых версиях Xcode)
  3. Нажмите "Next" и заполните информацию о проекте: – Product Name: название вашего приложения – Team: ваша команда разработчиков Apple Developer – Organization Identifier: обычно используется обратный домен, например com.yourcompany – Bundle Identifier: генерируется автоматически – Language: Swift (рекомендуется) или Objective-C – User Interface: выберите SwiftUI для современного подхода или Storyboard для классического
  4. Нажмите "Next", выберите расположение проекта и нажмите "Create"

После создания проекта вы увидите основной интерфейс Xcode, который состоит из нескольких ключевых областей:

Область интерфейса Назначение Горячие клавиши
Navigator (левая панель) Навигация по файлам, поиск, фильтрация ошибок ⌘+1 до ⌘+9 для разных типов навигаторов
Editor (центральная область) Редактирование кода или интерфейса ⌘+Return для полноэкранного режима
Inspector (правая панель) Настройка свойств выбранного элемента ⌥+⌘+0 для скрытия/показа
Debug area (нижняя панель) Отображение консоли и отладочной информации ⇧+⌘+Y для скрытия/показа
Toolbar (верхняя панель) Контроль сборки, запуск, остановка проекта ⌘+B для сборки, ⌘+R для запуска

Структура проекта macOS в Xcode организована в виде групп и файлов. Основные компоненты стандартного проекта:

  • AppDelegate.swift — точка входа в приложение, отвечает за жизненный цикл
  • ContentView.swift (для SwiftUI) или ViewController.swift (для AppKit) — основной контроллер интерфейса
  • Main.storyboard (для проектов с Storyboard) — визуальный редактор интерфейса
  • Assets.xcassets — каталог для хранения изображений и других ресурсов
  • Info.plist — файл метаданных приложения с настройками и разрешениями
  • [ProjectName].entitlements — файл с настройками прав доступа для приложения

Теперь давайте модифицируем наш проект, чтобы создать простое приложение. Если вы выбрали SwiftUI, отредактируйте ContentView.swift:

swift
Скопировать код
import SwiftUI

struct ContentView: View {
    @State private var username: String = ""
    @State private var showingGreeting = false
    
    var body: some View {
        VStack(spacing: 20) {
            Text("Hello, macOS Developer!")
                .font(.largeTitle)
            
            TextField("Enter your name", text: $username)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .frame(width: 300)
            
            Button("Say Hello") {
                showingGreeting = true
            }
            .disabled(username.isEmpty)
            
            if showingGreeting {
                Text("Welcome, \(username)!")
                    .font(.title)
                    .foregroundColor(.green)
            }
        }
        .padding(30)
        .frame(minWidth: 400, minHeight: 300)
    }
}

Для запуска приложения нажмите кнопку "Run" (треугольник) в верхней панели или используйте комбинацию ⌘+R. Xcode скомпилирует проект и запустит его в симуляторе или на подключенном устройстве.

Важно помнить о структуре папок в проекте Xcode:

  • Группы в Xcode не всегда соответствуют реальным папкам на диске. Они являются логическими контейнерами для организации файлов в IDE.
  • Используйте команду "New Group" (⌘+⇧+N) для создания логической структуры проекта.
  • Для создания физических папок используйте "New Group with Folder" и систематизируйте файлы по функциональности (Models, Views, Controllers, Helpers).

Правильная организация проекта с самого начала — залог успешного масштабирования вашего приложения в будущем.

AppKit vs SwiftUI: выбор фреймворка для macOS-разработки

Перед погружением в разработку macOS-приложения необходимо принять стратегическое решение: какой фреймворк использовать. У Apple есть два основных подхода к созданию пользовательских интерфейсов для macOS: классический AppKit и современный SwiftUI. Этот выбор определит не только структуру кода, но и методологию разработки. 🔄

Рассмотрим ключевые особенности каждого фреймворка:

Характеристика AppKit SwiftUI
Год появления 1989 (с NeXTSTEP) 2019
Парадигма Императивная (MVC) Декларативная
Зрелость Высокая (стабильный API) Развивающаяся (регулярные изменения API)
Кривая обучения Крутая, много шаблонного кода Более пологая, лаконичный синтаксис
Поддерживаемые версии macOS Все версии macOS Catalina (10.15) и новее
Возможности кастомизации Практически неограниченные Ограниченные (но растущие с каждой версией)
Live Preview Нет Да (Canvas)

AppKit — зрелый и мощный фреймворк, который предоставляет доступ к полному спектру возможностей macOS. Он использует паттерн MVC (Model-View-Controller) и имеет глубокую интеграцию с Cocoa — объектно-ориентированным API для macOS.

Пример создания окна с кнопкой в AppKit:

swift
Скопировать код
import Cocoa

class ViewController: NSViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = NSButton(title: "Click Me", target: self, action: #selector(buttonClicked))
        button.frame = NSRect(x: 100, y: 100, width: 100, height: 30)
        view.addSubview(button)
    }
    
    @objc func buttonClicked() {
        let alert = NSAlert()
        alert.messageText = "Hello, macOS Developer!"
        alert.runModal()
    }
}

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

Тот же функционал на SwiftUI:

swift
Скопировать код
import SwiftUI

struct ContentView: View {
    @State private var showAlert = false
    
    var body: some View {
        VStack {
            Button("Click Me") {
                showAlert = true
            }
            .padding()
        }
        .frame(width: 300, height: 200)
        .alert("Hello, macOS Developer!", isPresented: $showAlert) {
            Button("OK", role: .cancel) { }
        }
    }
}

При выборе фреймворка стоит учитывать следующие факторы:

  1. Совместимость: Если вам нужно поддерживать старые версии macOS (до 10.15), придётся использовать AppKit.
  2. Сложность проекта: Для сложных приложений с высокой степенью кастомизации AppKit может предоставить больше контроля.
  3. Кроссплатформенность: SwiftUI позволяет повторно использовать код между macOS, iOS, watchOS и tvOS.
  4. Командная экспертиза: Учитывайте опыт вашей команды. Переход на SwiftUI может потребовать времени на обучение.
  5. Долгосрочные планы: SwiftUI — это будущее разработки для Apple-платформ, но AppKit будет поддерживаться ещё долго.

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

  • NSViewRepresentable: протокол для использования AppKit-компонентов внутри SwiftUI
  • NSHostingView: класс для интеграции SwiftUI-представлений в AppKit

Пример интеграции NSView в SwiftUI:

swift
Скопировать код
struct NSTextViewRepresentable: NSViewRepresentable {
    @Binding var text: String
    
    func makeNSView(context: Context) -> NSScrollView {
        let textView = NSTextView()
        textView.isEditable = true
        textView.delegate = context.coordinator
        
        let scrollView = NSScrollView()
        scrollView.documentView = textView
        return scrollView
    }
    
    func updateNSView(_ nsView: NSScrollView, context: Context) {
        if let textView = nsView.documentView as? NSTextView {
            if textView.string != text {
                textView.string = text
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, NSTextViewDelegate {
        var parent: NSTextViewRepresentable
        
        init(_ parent: NSTextViewRepresentable) {
            self.parent = parent
        }
        
        func textDidChange(_ notification: Notification) {
            if let textView = notification.object as? NSTextView {
                parent.text = textView.string
            }
        }
    }
}

Михаил Сорокин, Lead Apple Platform Developer

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

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

Мы столкнулись с серьезной проблемой: некоторые необходимые API просто не были доступны через SwiftUI. Критическим моментом стала работа с NSOpenGLView для специфических визуализаций — мы потратили дни, пытаясь правильно интегрировать её через NSViewRepresentable, но столкнулись с проблемами производительности и жизненного цикла.

В итоге мы приняли гибридное решение: основной интерфейс на AppKit для стабильности и производительности, но с отдельными модулями на SwiftUI для простых диалогов и настроек. Этот подход позволил нам использовать сильные стороны обоих фреймворков и доставить продукт вовремя.

Главный урок: выбирайте технологию, исходя из требований проекта, а не наоборот. Иногда проверенный временем AppKit — лучший выбор для сложных задач, даже если SwiftUI кажется более современным и привлекательным.

Важно понимать, что Apple активно развивает SwiftUI, и с каждым годом этот фреймворк получает новые возможности. Например, в macOS Big Sur появились такие компоненты, как List, OutlineGroup и ToolbarItem, которые значительно расширили применимость SwiftUI для создания полноценных macOS-приложений.

Мой совет: для новых проектов рассмотрите SwiftUI как основной фреймворк, особенно если не требуются специфические возможности AppKit. Это позволит вам быть в тренде современной разработки и потенциально сэкономит время в будущем.

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

Разработка приложения — это только начало пути. Чтобы создать по-настоящему качественный продукт для macOS, необходимо мастерски владеть инструментами отладки и оптимизации, которые предлагает Xcode. Эти инструменты помогут вам найти и устранить проблемы, а также значительно улучшить производительность вашего приложения. 🐞

Начнем с основных средств отладки в Xcode:

  • Breakpoints (точки останова) — позволяют приостановить выполнение программы в определенной строке кода – Установите точку останова, щелкнув на номере строки в редакторе кода – Используйте условные точки останова для более сложных сценариев (правый клик на точке → Edit Breakpoint) – Создавайте символьные точки останова для отлова специфических функций (Debug → Breakpoints → Create Symbolic Breakpoint)
  • LLDB Debugger — мощный инструмент командной строки для интерактивной отладки – po (print object) — для просмотра содержимого объектов – p (print) — для вычисления выражений – bt (backtrace) — для просмотра стека вызовов – frame variable — для просмотра всех локальных переменных
  • Debug Navigator — визуальный интерфейс для отслеживания выполнения программы – Отображает стек вызовов, потоки, и переменные – Доступен через комбинацию ⌘+6 или иконку в левой панели навигатора

Для более глубокой отладки и анализа производительности Xcode предлагает набор инструментов Instruments (⌘+I). Вот наиболее полезные профайлеры для macOS-разработки:

Инструмент Назначение Когда использовать
Time Profiler Анализ CPU времени выполнения функций Когда приложение работает медленно или нагревает устройство
Allocations Отслеживание выделения памяти Для поиска утечек памяти и неэффективного её использования
Leaks Обнаружение утечек памяти Когда приложение потребляет всё больше памяти с течением времени
Energy Log Анализ энергопотребления Для оптимизации работы от батареи
Network Мониторинг сетевых запросов При отладке коммуникации с серверами
Core Animation Профилирование графической подсистемы Когда анимации не плавные или интерфейс тормозит

Давайте рассмотрим практические советы по использованию этих инструментов:

  1. Оптимизация производительности CPU: – Запустите Time Profiler и выполните типичный сценарий использования – Изучите "тяжелые" методы (с большим временем выполнения) – Обратите внимание на методы, которые часто вызываются в циклах или при прокрутке – Используйте "Инверсию вызовов" (Call Tree → Invert Call Tree) для фокусировки на самых ресурсоемких функциях

  2. Управление памятью: – Используйте инструмент Allocations для обнаружения постоянно растущего использования памяти – Ищите объекты, которые создаются, но не освобождаются (особенно изображения и данные) – Проверьте циклические ссылки (retain cycles) между объектами, используя слабые (weak) ссылки где необходимо

  3. Оптимизация графического интерфейса: – Используйте Core Animation инструмент для выявления перерисовок и сложных композиций – Включите опцию "Color Offscreen-Rendered Yellow" для обнаружения ресурсоемких эффектов – Минимизируйте количество слоев и прозрачных элементов

Помимо Instruments, Xcode предлагает ряд встроенных инструментов для анализа кода:

  • Static Analyzer (Product → Analyze или ⇧+⌘+B) — находит потенциальные ошибки, утечки памяти и логические проблемы без запуска приложения
  • Runtime Issues — автоматически обнаруживает проблемы во время выполнения программы (например, утечки памяти или проблемы с потоками)
  • Memory Graph Debugger (Debug → View Memory Graph или ⇧+⌘+M) — визуализирует объекты в памяти и связи между ними
  • Thread Sanitizer — помогает обнаружить состояния гонки (race conditions) в многопоточном коде

Для эффективной отладки сетевых запросов в macOS-приложениях рекомендую:

  1. Включите Network Link Conditioner (доступен через дополнительные инструменты Xcode) для симуляции различных сетевых условий
  2. Используйте Charles Proxy для перехвата и анализа сетевого трафика вашего приложения
  3. Реализуйте подробное логирование сетевых запросов и ответов в режиме разработки

Для оптимизации размера приложения:

  1. Используйте инструмент App Thinning для создания вариантов приложения, оптимизированных под конкретные устройства
  2. Анализируйте размер бинарника с помощью опции "Show in the Report navigator" после сборки
  3. Оптимизируйте ресурсы (изображения, звуки) и используйте форматы с поддержкой сжатия

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

  • Настройте автоматические тесты (XCTest для unit-тестов и UI-тестов)
  • Интегрируйте статический анализатор кода в процесс сборки
  • Используйте инструменты вроде SwiftLint для обеспечения единого стиля кода

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

Подготовка и публикация приложения в Mac App Store

После успешной разработки и тестирования вашего приложения наступает финальный этап — подготовка к публикации в Mac App Store. Этот процесс требует внимания к деталям и соблюдения всех рекомендаций Apple, чтобы ваше приложение быстро прошло проверку и стало доступно миллионам пользователей macOS. 🚀

Подготовка к публикации включает несколько ключевых шагов:

  1. Завершение разработки и финальное тестирование – Устраните все известные ошибки и проблемы – Проверьте работоспособность на различных версиях macOS – Проведите тестирование на разных Mac-устройствах (если возможно) – Убедитесь, что приложение корректно работает после полной переустановки

  2. Настройка метаданных приложения – Заполните Info.plist необходимыми ключами (CFBundleIdentifier, CFBundleVersion, LSMinimumSystemVersion и т.д.) – Укажите необходимые разрешения и объяснения их использования – Настройте entitlements для приложения (если используются защищенные API)

  3. Подготовка маркетинговых материалов – Создайте привлекательную иконку приложения (1024x1024 пикселя для App Store) – Сделайте качественные скриншоты в разных форматах – Подготовьте краткое и информативное описание приложения – Создайте превью-видео (опционально, но рекомендуется)

Перед отправкой в Mac App Store необходимо настроить подписи кода и конфигурацию безопасности:

  1. Подписание кода (Code Signing) – Убедитесь, что у вас есть действующий сертификат Developer ID из Apple Developer Program – Настройте правильные профили подписи в Xcode (Signing & Capabilities) – Включите Hardened Runtime для повышенной безопасности – Добавьте необходимые entitlements для доступа к защищенным API

  2. Настройка App Sandbox – Все приложения в Mac App Store должны использовать песочницу – Включите только те права доступа, которые действительно нужны вашему приложению – Для каждого права доступа подготовьте объяснение его необходимости

Процесс публикации приложения включает следующие шаги:

  1. Архивация приложения – В Xcode выберите Product → Archive – Убедитесь, что выбрана конфигурация Release – Дождитесь завершения процесса архивации

  2. Проверка и валидация – В органайзере архивов (Window → Organizer) выберите созданный архив – Нажмите "Validate App" для предварительной проверки на соответствие требованиям App Store – Исправьте все обнаруженные проблемы до отправки

  3. Создание записи в App Store Connect – Войдите в App Store Connect (appstoreconnect.apple.com) – В разделе "Мои приложения" нажмите "+" для создания новой записи – Заполните необходимую информацию (имя, SKU, Bundle ID, категория) – Загрузите скриншоты, иконку и описание

  4. Отправка сборки – Вернитесь в органайзер Xcode и выберите "Distribute App" – Выберите "App Store Connect" в качестве метода распространения – Следуйте инструкциям мастера для отправки сборки – Дождитесь завершения обработки в App Store Connect (может занять до часа)

  5. Финальная настройка и отправка на проверку – В App Store Connect привяжите загруженную сборку к версии приложения – Заполните информацию о версии (примечания к выпуску, контактная информация для проверки) – Отправьте приложение на рассмотрение, нажав "Submit for Review"

Важно помнить о следующих аспектах процесса проверки Apple:

  • Среднее время проверки составляет 24-48 часов, но может варьироваться
  • Приложение должно соответствовать App Store Review Guidelines
  • Будьте готовы быстро отвечать на вопросы команды проверки
  • При отклонении внимательно изучите причины и исправьте проблемы перед повторной отправкой

Советы для успешного прохождения проверки:

  • Убедитесь, что приложение не имеет очевидных ошибок и сбоев
  • Создайте тестовый аккаунт для проверяющих, если ваше приложение требует аутентификации
  • Предоставьте подробные инструкции по тестированию в разделе "App Review Information"
  • Если ваше приложение использует нестандартные функции, объясните их назначение в примечаниях
  • Убедитесь, что маркетинговые материалы точно отражают функциональность приложения

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

Не забудьте о поддержке приложения после публикации:

  • Регулярно отслеживайте отзывы пользователей
  • Анализируйте аналитику использования через App Analytics в App Store Connect
  • Планируйте регулярные обновления для исправления ошибок и добавления новых функций
  • Рассмотрите возможность использования TestFlight для бета-тестирования будущих обновлений

Помните, что Mac App Store — это не единственный способ распространения macOS-приложений. Если требования App Store слишком ограничительны для вашего случая, вы можете распространять приложение напрямую через свой веб-сайт, используя Developer ID для подписи кода и нотаризацию для обеспечения безопасности.

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

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой инструмент является основным для разработки приложений для macOS?
1 / 5

Загрузка...