Cocoa mac os это

Cocoa

Cocoa и Cocoa Touch framework-и это мощь Mac OS X и IOS тесно интегрированная в опыт разработки Xcode. На высоком уровне API, Cocoa делает возможным: легко добавлять анимацию, создавать сети и создавать родной внешний вид и поведение платформы для вашего приложения с помощью всего нескольких строк кода.

Cocoa Framework-и

Cocoa framework-и состоят из библиотек, API, и сред, которые формируют слой разработки для всех Mac OS X. Разрабатывая с Cocoa, вы будете создавать приложения так же, как была создана и сама Mac OS X. Ваше приложение будет автоматически наследовать большую часть поведения и проявления Mac OS X, с полным доступом ко всей мощи операционной системы UNIX. Использование Cocoa с Xcode IDE просто лучший способ для создания нативных приложений для Mac.

Сила Objective-C

Большая часть Cocoa реализована в Objective-C, объектно-ориентированном языке, который компилируется для запуска с невероятной скоростью, а использование действительно динамичного выполнения делает его уникально гибким. Поскольку Objective-C является подмножеством С, то легко смешивать C и даже C++ в приложениях Cocoa.

Как работает приложение, -среда выполнения Objective-C создает объекты, основанные на выполнении логики, а не только способами определенными во время компиляции. Например, работающее Objective-C, приложение может загрузить интерфейс (nib файл, созданный в Interface Builder), подключить Cocoa объекты в интерфейсе к коду приложения, а затем запустить правильный метод одим нажатием кнопки на экране. Нет необходимости повторной компиляции.

Objective-C динамически выполненяемый и похож на многие современные языки сценариев, что позволяет с легкостью расширять содержимое Cocoa на другие языкаи, использующие Cocoa Bridge. С Cocoa Bridge, разработчики могут создавать первоклассные Mac OS X приложения используя AppleScript, Ruby и Python.

Cocoa использует шаблон проектирования Модель-Вид-Контроллер

Cocoa использует Модель-Вид-Контроллер (Model-View-Controller (MVC)) в качестве шаблона проектирования во всем. Модели инкапсуляции данных приложений, Просмотр отображения и редактирования данных, а также Контроллеры посредники логики между ними. Разделяя обязанности таким образом, в итоге вы получите приложение, которое проще спроектировать, внедрить и поддерживать.

Шаблон MVC означает, что Interface Builder не требует никакого кода уже написанного или сгенерированного в то время как вы сосредоточены исключительно на виде вашего приложения. Cocoa bindings на Mac исключают большинство связующего кода, что достигается связыванием между контроллерами закодироваными в Xcode и представлением View спроектированным в Interface Builder простой графической «линией» между ними. Interface Builder работает с Cocoa, чтобы облегчить локализации приложения, так что вы можете быстро выйти на совершенно новые рынки.

Список характеристик: Framework-и по категориям

Cocoa содержит первичные framework-и, такие как AppKit и Core Foundation, которые обеспечивают общие строительные блоки для всех приложений Mac, а также специализированные framework-и для всего, от сетей и данных до графики и профессиональной обработки звука. Эти framework-и варьируются от высокого уровня, Objective-C API, которые могут создавать удивительные эффекты из нескольких строк кода, вплоть до низкоуровневых framework-ов для управления каждым аспектом ядра системы. Вот небольшая выборка доступных framework-ов, обеспечиваемая Cocoa:

Источник

The Cocoa Environment. Part 1

Многие об этом говорят, но какое на самом деле место занимает Cocoa environment в жизни IOS и MacOS, да и вообще что это за такая уличная магия?

Поприветствуйте Cocoa!

Cocoa — это основная среда приложений для Mac OS X (есть еще Carbon, но эта среда используется в основном только для поддержки кода написанного для Mac OS 9.) и единственная среда приложений для операционных систем IOS. Она состоит из набора объектно-ориентированных библиотек, исполняющей среды и среды разработки.
Большинство программ, которые используют пользователи Mac OS X (например, Mail или Safari), а тем более, пользователи IOS, это программы, написанные с помощью Cocoa.
Ну а для создания приложений под Cocoa используется знаменитый Xcode.

Как и с чем?

Как и во всех средах приложений, Cocoa имеет два мира: мир runtime’а и мир разработки. В мире runtime’а, Cocoa приложения представляют пользовательский интерфейс и тесную интеграцию с другими компонентами операционной системы в Mac OS X, например, Finder и Dock.
Но в мире разработки Cocoa – интегрированный набор объектно-ориентированных программных компонентов-классов, которые, собственно, позволяют творить ПО под Mac OS X и IOS. Они дают возможность делать тучу вещей, от user-interface’а до управления массивами данных.
При разработке Cocoa приложений, на самом деле, можно использовать несколько языков программирования, но родной язык — Objective-C, который является расширением ANSI C, с некоторыми синтаксическими и семантическими особенностями (на основе Smalltalk) для поддержки ООП. Кроме того, ваш код может вызывать функции определенные в non-Cocoa интерфейсе, такие как библиотеки BSD в /usr/include. Вы даже можете смешивать C++ код с Cocoa кодом и ссылаться на этот скомпилированное чудо в вашем исполняемом файле.
Наиболее важные библиотеки Cocoa упакованы в два основных framework’a для каждой платформы: AppKit для Mac OS X и UIKit для IOS. Как и все framework’и, они содержат не только динамически доступные библиотеки (а иногда и несколько версий библиотек, необходимые для обеспечения обратной совместимости), но и файлы заголовков, API документацию, и связанных с ними ресурсы. Framework — это очень важная составляющая для любого проекта под Mac или IOS.
Мас OS X поддерживает ко всему прочему еще много полезных библиотек, таких как: WebKit и Address Book frameworks, но об этом позже.

Читайте также:  Нхл для windows 10

И как же Cocoa дружит с Mac OS X?

Архитектурно, Mac OS X является серией программных слоев (рис 1).


Рис 1. Вот так дружит с Mac OS X

Например, системный компонент, который в значительной степени ответственный за работу интерфейса Aqua – Quartz (реализован в Core Graphics framework), является частью слоя Application Services. Но в основании всего этого лежит Darwin (набор основных компонентов, используемых в Mac OS X и iOS). все в Mac OS X, в том числе Cocoa, в конечном счете зависит от этого слоя.
В Mac OS X, Cocoa состоит из двух основных framework’ов, которые необходимы для разработки приложений для Mac OS X:

  • AppKit. AppKit, один из компонент application framework’а, предоставляет отображение приложения на экрне и определяет структуру поведения приложений, включая обработку событий.
  • Foundation — компонент в слое Core Services, определяет основные поведения объектов, устанавливает механизмы их управления, и предоставляет возможность использовать примитивных типов данных, коллекций и сервисов операционной системы.

AppKit зависит от Foundation, который функционально находится в слое Core Services. Если посмотреть поближе на классы AppKit, можно увидеть, где Cocoa зависит от других частей Mac OS X, например, Carbon Core, Core Graphics (Quartz), и Launch Services.

  • Core Foundation. Многие классы Foundation framework основаны на эквивалентных непрозрачных классах Core Foundation. Эта тесная связь делает преобразования между совместимыми типами Core Foundation и Foundation «бесплатными». В свою очередь, классы Core Foundation используют BSD слой Darwin’а.
  • Carbon Core. AppKit и Foundation используют Carbon Core framework для получения доступа к некоторым системным службам. Например, Carbon предоставляет Core File Manager, который используется Cocoa для работы с различными файловыми системами.
  • Core Graphics. Cocoa использует Core Graphics для большинства задач связанных с отображением графики.
  • Launch Services. Класс NSWorkspace предоставляет основные возможности Launch Services. Cocoa также использует возможности Launch Services для ассоциации иконок с приложениями и документами.

Apple тщательно разработал Cocoa так, чтобы некоторые из ее программных интерфейсов давали доступ к базовым функциям, которые обычно необходимы приложениям. Но если требуются некоторые возможности, которые не
доступны через интерфейсы Cocoa, или если нужен более тонкий контроль над тем, что происходит в приложении, вы можете непосредственно использовать основные framework’и (ярким примером является Core Graphics, путем вызова функций которой можно получить более мощные средства управления графикой).

И как же Cocoa дружит с iOS?

Слой выполнения приложений в IOS называется Cocoa Touch. Хотя IOS инфраструктура, в которой работает Cocoa Touch похож на ту, в которой работает Cocoa в Mac OS X, есть некоторые существенные различия (Рис 2).


Рис 2. Вот так дружит с iOS

Как правило, системные библиотеки и framework’и IOS, которые использует UIKit являются подмножеством библиотек и framework’ов Mac OS X. Однако, из-за характера устройств, поддерживаемых ОС IOS,
есть некоторые framework’и, которые являются специфическими для IOS.
Ниже приводится краткое изложение некоторых из framework’ов каждого слоя:

  • Core OS. Этот уровень содержит ядро, файловую систему, сетеву инфраструктуру, безопасность, управления питанием, а также ряд драйверов устройств. В нем, ко всему прочему, содержится библиотека libSystem, которая поддерживает POSIX / BSD 4.4/C99 API спецификации и включает в себя системы на уровне API для многих сервисов.
  • Core Services. Предоставляет основные сервисы, такие как манипуляции со строками, управление коллекциями и сетевым взаимодействием, управление контактами, настройками. Они также дают возможность пользоваться аппаратными особенностями устройства (GPS, компас, акселерометр и гироскоп).
  • Примеры framework’а этого слоя — Core Location, Core Motion, и System Configuration.
  • Этот слой включает в себя как Foundation так и Core Foundation, которые предоставляют некоторые типы данных, такие как строки и коллекции.
  • Media. Обеспечивает слою Cocoa Touch доступ к мультимедийным возможностям. Включает в себя Core Graphics, Core Text, OpenGLES,
  • Core Animation, AVFoundation, Core Audio, и сервисы воспроизведения видео.
  • Cocoa Touch. Занимается непосредственной поддержкой приложений. Содержит такие компоненты как Game Kit, Map Kit и iAd.

Cocoa в IOS, как и Cocoa в Mac OS X, дает приложениям доступ к возможностям базовых функциям. И если вам требуется нечто большее, чем предоставляет Cocoa API, вы так же можете непосредственно использовать методы более низкого уровня.

Источник

Интеграция приложений Qt в среду Mac OS X (с использованием Cocoa и Objective-C++)

Доброго всем дня!

Недавно я писал о кастомизации заголовка окна в Mac OS X и получил реквесты написать поподробнее о взаимодействии Qt и Cocoa. Думаю, тему можно немного развернуть и написать об интеграции приложений, написанных с помощью Qt, в среду Mac OS X. Оговорюсь, что используется в данном случае Qt for Cocoa, если возьмёте Qt for Carbon, то и работать придётся только с карбоном. Но он морально устарел, и использовать его стоит только в крайних случаях.

Обычная Qt-программа имеет ряд несостыковок с Apple HIG. Точнее, может иметь, так как не всем программам нужен дополнительный функционал. Например, не любой программе надо иметь бэдж поверх значка в доке, расширять меню дока или выносить/дублировать некоторые функции в маковское меню.

Но что делать, если такой функционал нужен? Если нужно отображать в доке количество уведомлений (а-ля скайп), обрабатывать клик по иконке в доке, добавлять свои пункты меню в док, да ещё и иметь нормальное меню, в общем, сделать так, чтобы программа смотрелась как родная в Mac OS? Что-то из этого можно сделать с помощью штатных или полудокументированных функций Qt, а что-то — только с использованием Cocoa и, соответственно, Objective-C… Что же делать?

Читайте также:  Windows bitmap to jpeg

Нам поможет Objective-C++!

Что это за зверь и с чем его едят? По сути, это возможность комбинировать Objective-C и C++ классы в одном файле исходников. Причём, расширение заголовочников остаётся стандартным (.h), а вот для исходников нужно указывать расширение .mm, чтобы компилятор его съел и не поперхнулся.

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

Понятно, что для начала надо подстроить интерфейс программы под Apple HIG, без этого никуда, но это останется за рамками данной статьи, упомяну лишь полезные дефайны Q_WS_*, которые позволяют компилить разный код для разных ОСей. Мы же будем говорить о том, какими средствами можно подстроить своё приложение под новое окружение (или же как создать Mac-приложение на Qt с нуля — это зависит от поставленных целей).

Итак, пойдём по порядку.

Общая интеграция

Для начала дадим имя и значок программе. Нет, не то имя, которое имеет бандл, а имя, которое будет отображаться в Application Menu. Для этого нам потребуется свой файл Info.plist, а не тот, что генерирует qmake. Это делается одной строчкой в .pro:

В наш .plist пишем что-то такое:

Разумеется, вместо «MyAppName» и «com.mycompany.myapp» пишем английское название программы и свой идентификатор бандла. Почему английское? Да потому что локализуем мы его в другом файле. На это указывает самый первый параметр в плисте: LSHasLocalizedDisplayName. Создаём директорию «ru.lproj», а в ней файл InfoPlist.strings. В этот файл пишем что-то такое:

Здесь уже нужно указывать локализованное название бандла и имя, отображаемое в Application Menu. Чтобы это заработало, нужно при установке программы скопировать эту дерикторию в AppName.app/Contents/Resources, делать это лучше через указание INSTALLS в .pro файле, за подробностями прошу обращаться к документации к qmake. На скриншоте видно, что Application Menu имеет русское название, несмотря на то, что сам бандл имеет название на латинице.


Чтобы задать иконку программы (см. myicon.icns в файле MyInfo.plist), нам нужен файл .icns, который можно создать самому в графическом редакторе, либо сконвертировать из .ico или кучки .png с помощью программ или онлайн сервисов. Чтобы смотрелась иконка хорошо, лучше сделать в ней несколько размеров: 512×512, 256×256, 128×128, 64×64, 48×48, 32×32, 16×16. Система сама выберет какой размер в какой ситуации отображать. Файл с иконкой надо так же устанавливать в Resources. Самый простой способ заставить его устанавливаться — это прописать следующее в .pro файле:

Разделение кода

У Objective-C++ есть множество ограничений. Нельзя, к примеру, включать хедер с объявлением интерфейса Objective-C класса в файл исходников .cpp, ибо компилятор подавится. Для новых проектов, расчитанных только на Mac OS X, это не будет ограничением, ибо можно весь C++ код держать в .mm файлах и радоваться жизни. Но смысл Qt в кроссплатформенности, так что будем считать, что наши исходники всё-таки в .cpp файлах.

Выход тут прост. Надо создать «обёртку» для Objective-C вызовов и классов на C++. Я выбрал такую структуру: есть Qt/C++ класс, который обеспечивает интеграцию с Mac OS X. Какую-то работу он выполняет сам, а какую-то перепоручает «делегату», приватному классу, активно использующему Cocoa/Objective-C. При этом, получаем следующие файлы:

* myclass.h — заголовок основного класса
* myclass.cpp — реализация
* myclass_p.h — заголовок приватного класса (без Objective-C-интерфейсов)
* myclass_p.mm — исходники приватного класса, могут включать в себя интерфейсы и имплементацию классов Objective-C, включать любые хедеры и т.п.

Таким образом, мы чётко разграничиваем C++ и Objective-C++.

Кстати, чтобы Objective-C++ заработал, в .pro файле надо все хедеры/исходники, использующие его, помещать в секции OBJECTIVE_HEADERS и OBJECTIVE_SORCES. И, разумеется, делать это внутри блока macx: <>. А ещё, если мы хотим использовать Cocoa, то надо добавить этот фреймворк к проекту. Пишем в .pro:

А теперь пойдёт интересное.

Работа с Dock

Рассмотрим пять основных функций работы с доком: добавление бэджа, добавление оверлея, обработка клика на иконке в доке, «подбрасывание» иконки программы в доке и добавление своего меню. Средствами Qt решить можно только последнюю проблему, да и то слабо документированной функцией qt_mac_set_dock_menu(QMenu*). Причём объявить её надо самим, как внешнюю:

На меню, исходя из личного опыта, накладываются некоторые ограничения в сравнении с «родным» маковским меню:

* неактивные (disabled) пункты меню становятся зачем-то активными
* QMenu не эмиттит сигналы aboutToHide и aboutToShow
* нельзя сделать отступ каких-либо элементов
* если первый QAction в меню — разделитель, то он будет виден (в отличие от всех остальных проявлений QMenu)

Так что под это придётся подстраиваться. Можно, конечно, сделать всё на Objective-C/Cocoa, но тогда придётся делать свой механизм маппинга QAction’ов и родных пунктов меню. Но это имеет смысл делать только при действительно большой необходимости в устранении указанных ограничений.


Рассмотрим теперь клик на доке. Если бы мы писали на Cocoa, то проблем бы не было, достаточно было бы в AppDelegate реализовать метод applicationShouldHandleReopen:hasVisibleWindows:. Но мы не имеем прямого доступа к делегату программы, созданному в недрах Qt. Поэтому воспользуемся магией рантайма для добавления реализации этого метода. Для начала объявим функцию, которая будет реализовывать то, что нам нужно. Для этого превратим наш приватный класс в синглтон (всё равно нам не нужно более одного объекта этого класса) и напишем такую функцию:

Читайте также:  Не удалось настроить обновления windows как это отменить

Функция мертва без внедрения её в делегата. Не будем же с этим медлить!

Здесь мы берём класс делегата нашего приложения и добавляем в него метод на лету. И заодно реализуем метод emitClick(), эмиттящий Qt-сигнал о клике. Собственно, вот и всё, теперь по клику в доке мы можем показывать, к примеру, главное окно программы.

Далее можно попробовать подбросить иконку программы в доке. Первая же мысль: «так это же умеет делать QApplication::alert(QWidget*)!» Мысль верная, но преждевременно оптимистичная. Всё дело в том, что в Mac OS X 10.6.* эта функция работает как надо, а вот в 10.7.* почему-то не хочет (может быть, это связано с тем, что Qt 4.7.x официально не поддерживает Lion, а в 4.8 это пофиксят). Я не стал разбираться почему так происходит, и просто написал подбрасывание на Cocoa, благо это делается одной строкой:

И пусть этот кусок кода дублирует Qt-шный alert(), зато работать будет во всех версиях Mac OS X. А для других систем можно по-прежнему использовать alert().

Теперь разберёмся с бэджем. Если кто не в курсе, то это крсный кружок с текстом, отображаемый поверх значка программы в доке. Например, он используется для отображения числа непрочитанных писем в Mail.app. Документация от Apple говорит, что делать это надо так:

Здесь badgeString имеет тип NSString*. Ага, вот и первое неудобство! В Qt обычно идёт манипулирование QString, а значит, надо написать некий «конвертер» строк:

Как видно из кода (и из комментария к нему), возвращаемая строка не релизится, так что придётся делать это в вызывающем коде (Qt не использует ARC, так что за памятью следить будем сами).

Теперь можем написать функцию нашего приватного класса, которая будет выводить нужную нам строку в бэдже дока:


Теперь последний аспект работы с доком — добавить произвольный оверлей в док. Это делается с помощью следующего кода:

Здесь view это NSView*. Но мы-то работаем с Qt! А значит, нам надо в оверлей поместить QWidget*. Как же получить из QWidget’а его NSView? Пишем простую функцию:

Всё просто, создатели Qt сделали почти всю работу за нас.

Но, увы, ждёт нас облом: NSView, полученный из QWidget’а непригоден для установки в док. То есть, он ставится, NSDockTile его съедает, но вместо содержимого виджета в доке образуется пустое место. Не знаю уж, почему. Но даже в Qt Creator’е прогресс-бар в док вешается именно через свой чистый NSView, созданный специально для этого. Так что, если нужен свой оверлей, то милости просим написать свой View на Cocoa. Увы.

Работа с меню

Перейдём к маковскому меню (тому, что на верхней панели). По умолчанию, Qt-программа его не создаёт (ну, если не считать стандартного Application Menu с системными функциями). Первое, что приходит на ум Qt-разработчику, это QMenuBar. И действительно, в документации к нему написано, что он может выполнять функции маковского меню. Но тут два варианта: либо сделать отдельный QMenuBar для каждого окна программы, либо сделать один глобальный. Выберем второй вариант в силу его неоспоримых преимуществ.

Опять же, исходя из документации, нам нужно создать QMenuBar с нулевым родителем, т.е., QMenuBar * macMenuBar = new QMenuBar(NULL), тогда он будет глобальным. Точнее, первый, из соданных таким образом менюбаров, станет глобальным.

А теперь — куча монотонной работы руками. Создаём сами меню «Правка», «Файл», «Справка» и так далее. Это достаточно нудная работа, но без неё программа хорошо выглядеть не будет. Кроме того, стандартные сочетания клавиш ⌘W и ⌘M не будут соответственно закрывать и сворачивать окна. Их придётся так же делать самостоятельно (хорошо хоть ⌘Q работает сразу).

Отмечу некоторые особенности QAction’ов в Mac OS X. Если им задавать шорткаты, то в конструктор QKeySequence надо передавать «Ctrl+M» для создания шортката «⌘M». И вообще, клавиша «⌘» в Qt под мак везде проходит как Ctrl, а клавиша «Ctrl» — как Meta. Для более лёгкой портируемости программ, надо полагать.

Ну и об ограничениях данного подхода к созданию меню.

* нельзя сделать отступ пунктов меню
* QMenu не эмиттит сигнал aboutToHide (только aboutToShow)
* имеет место следующий баг: если меню «Справка» называется «Help», то в нём будет автоматически создан системный блок поиска по пунктам меню, но если он будет назван по-русски, этого не произойдёт, даже если в системе текущая локаль — русская. Как избавиться от этого глюка, я пока не нашёл.

Почти финал — кастомный заголовок окна в Qt

Чтобы применить всё, написанное мной в прошлой статье, к Qt-программе, нужно сделать следующее. Во-первых, ставим где надо retain/release, т.к. не включен ARC. Во-вторых, в Objective-C++ разрешено то, что не удалось сделать в чистом Objective-C: взятие класса, если он объявлен только форвардом:

Это избавляет нас от необходимости иметь хотя бы одно окно в программе перед вызовом данной функции. В остальном всё то же самое, так что копипастить код сюда не буду. Посмотреть это можно в примере (ссылка ниже).

Заключение

Итак, мы рассмотрели Objective-C++ в применении к связке Qt+Cocoa для интеграции программы, написанной на Qt, в среду Mac OS X. По большому счёту, ничего сложного в этом нет, если имеются базовые знания Objective-C и Cocoa. Надо только знать некоторые особенности, на которых я постарался заострить внимание в данной статье.

Если кого интересуют полные исходники тестового проекта, то добро пожаловать на GitHub!

PS: ещё можно было бы рассмотреть встраивание в программу уведомлений через Growl, но это читатель может сделать и сам, если он усвоил материал.

Источник

Оцените статью