Xamarin книги на русском - IT Новости
Microclimate.su

IT Новости
134 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Xamarin книги на русском

Полное руководство для Xamarin разработчика: iOS и Android!

The Complete Xamarin Developer Course: iOS And Android!

Делайте кроссплатформенные Android и iOS-приложения с Xamarin Forms, Xamarin Classic, Azure Mobile App Services, Rest и многое другое. Xamarin — это принадлежащая Microsoft компания, которая позволяет разработчикам с использованием C# писать собственные приложения для Android, iOS (и даже Windows и MacOS) с собственными пользовательскими интерфейсами и общим кодом. Это означает, что вы можете создать приложение один раз и развернуть его как на Android, так и на iOS, которые запускаются изначально на платформе. Одна кодовая база, две платформы.

Вы можете создавать собственные приложения для Android и iOS, которые используют до 100% кода! Больше не нужно писать отдельные версии приложений для обеих платформ.

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

Текущие затраты на обслуживание сокращаются, потому что у вас есть одна база кода! Это также означает, что, изучая один язык (C #), вы можете теперь писать приложения для обеих платформ.

Программный пакет Microsoft Visual Studio доступен в Windows и Mac, и оба они отображаются в курсе. Вы можете использовать и развертывать Xamarin, есть ли у вас компьютер Windows или Mac.

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

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

Некоторые из ключевых вещей Xamarin, которые вы узнаете и сможете использовать в своих приложениях после прохождения этого курса, включают в себя Xamarin Forms, Xamarin Classic, использование Azure Mobile App Services, использование сервисов REST, внедрение баз данных SQLite и использование шаблона MVVM (очень важно учиться и понимать).

Большинство других курсов Xamarin сосредоточены только на Xamarin.Forms или Xamarin classic. В этом курсе рассматриваются ОБА. Также этот курс учит вас всем сервисам Azure Mobile App (интеграция с облачной базой данных), чему не учит ни один другой курс.

Ваш инструктор, Эдуардо Росас, является сертифицированным разработчиком Xamarin Mobile с 3-летним опытом работы на платформе и 5-летним опытом использования C #. Он начал разрабатывать приложения для Windows Phone 7 еще в 2012 году, которые, как и Windows 8 и Windows 10, используют C # и XAML и используют эти два языка для создания приложений Xamarin.Forms.

Это означает, что вы учитесь у кого-то, у кого есть вся профессиональная подготовка, навыки и опыт, которые вам нужно, и освоить Xamarin, как можно быстрее.

Если вы готовы получить первую оплаченную работу по программированию или перейти на более старшую позицию программирования, то этот курс для вас!

Полное руководство для Xamarin разработчика: iOS и Android!

The Complete Xamarin Developer Course: iOS And Android!

Делайте кроссплатформенные Android и iOS-приложения с Xamarin Forms, Xamarin Classic, Azure Mobile App Services, Rest и многое другое. Xamarin — это принадлежащая Microsoft компания, которая позволяет разработчикам с использованием C# писать собственные приложения для Android, iOS (и даже Windows и MacOS) с собственными пользовательскими интерфейсами и общим кодом. Это означает, что вы можете создать приложение один раз и развернуть его как на Android, так и на iOS, которые запускаются изначально на платформе. Одна кодовая база, две платформы.

Вы можете создавать собственные приложения для Android и iOS, которые используют до 100% кода! Больше не нужно писать отдельные версии приложений для обеих платформ.

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

Текущие затраты на обслуживание сокращаются, потому что у вас есть одна база кода! Это также означает, что, изучая один язык (C #), вы можете теперь писать приложения для обеих платформ.

Программный пакет Microsoft Visual Studio доступен в Windows и Mac, и оба они отображаются в курсе. Вы можете использовать и развертывать Xamarin, есть ли у вас компьютер Windows или Mac.

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

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

Некоторые из ключевых вещей Xamarin, которые вы узнаете и сможете использовать в своих приложениях после прохождения этого курса, включают в себя Xamarin Forms, Xamarin Classic, использование Azure Mobile App Services, использование сервисов REST, внедрение баз данных SQLite и использование шаблона MVVM (очень важно учиться и понимать).

Большинство других курсов Xamarin сосредоточены только на Xamarin.Forms или Xamarin classic. В этом курсе рассматриваются ОБА. Также этот курс учит вас всем сервисам Azure Mobile App (интеграция с облачной базой данных), чему не учит ни один другой курс.

Ваш инструктор, Эдуардо Росас, является сертифицированным разработчиком Xamarin Mobile с 3-летним опытом работы на платформе и 5-летним опытом использования C #. Он начал разрабатывать приложения для Windows Phone 7 еще в 2012 году, которые, как и Windows 8 и Windows 10, используют C # и XAML и используют эти два языка для создания приложений Xamarin.Forms.

Читать еще:  Книга максима левина как стать хакером

Это означает, что вы учитесь у кого-то, у кого есть вся профессиональная подготовка, навыки и опыт, которые вам нужно, и освоить Xamarin, как можно быстрее.

Если вы готовы получить первую оплаченную работу по программированию или перейти на более старшую позицию программирования, то этот курс для вас!

Xamarin: что это такое, кому стоит использовать и ответы на другие важные вопросы о фреймворке

Xamarin: что это такое, кому стоит использовать и ответы на другие важные вопросы о фреймворке

  • Статьи , 2 октября 2016 в 20:54
  • Антон Машков

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

Кто выигрывает с Xamarin?

Бизнес-логика приложения редко меняется при смене платформы. Ваш любимый интернет-банкинг проводит платежи и сообщает баланс вне зависимости от того, работаете вы на смартфоне или ноутбуке. Подобные приложения со сложной бизнес-логикой и стандартным интерфейсом — прерогатива Xamarin.

Алгоритмы, разработанные на C# для одной платформы, программисты используют и для всех остальных платформ. Например, при работе на Xamarin.Android и Xamarin.iOS, до 75% кода можно переиспользовать: приложение работает одинаково и на iPhone, и на Android-смартфоне.

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

Какие плюсы?

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

Ваша команда подходит?

Для программистов, уже работающих с несколькими платформами отдельно, переход на кроссплатформенные решения покажется рутиной. Разобраться в Xamarin легко, а вот изучить документацию, гайдлайны, SDK и API каждой платформы с нуля — гораздо сложнее.

Для тех же Xamarin.Android и Xamarin.iOS требуется знание iOS Storyboards и синтаксис Android XML. Конечно, обучать сотрудников всегда полезно, но готовы ли вы делать эти вложения прямо сейчас? В любом случае, лучше иметь на проекте пару iOS-Android разработчиков, которые ускорят процесс обучения коллег. В команде одни десктоп-специалисты, а приложение должно работать и на смартфонах? Без дополнительной помощи мобильных разработчиков вы вряд ли почувствуете экономию от Xamarin.

Сколько это стоит?

Ещё в начале 2016 года разработчики тратили на лицензию Xamarin до $999 в год. Но после поглощения компанией Microsoft большая часть продуктов Xamarin стала доступна по лицензии Visual Studio 2013 или Visual Studio 2015. Скачивайте всё необходимое с официального сайта Xamarin или прямо в Visual Studio 2015 (Update 2) и начинайте работу.

Доплачивать надо, например, за Xamarin Test Cloud. Но будем честны: без этого сервиса может обойтись подавляющее большинство проектов.

Стоит учитывать стоимость оборудования. Вам понадобятся устройства с macOS для разработки на iOS SDK и Windows для Windows Phone SDK, а Android SDK работает и там, и там.

О чем стоит беспокоиться?

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

Раздел для разработчиков на сайте Xamarin содержит детальную документацию, API и примеры всех методов и процедур — этого достаточно, чтобы начать разработку. Для всего остального есть Stackoverflow с ответами на любые вопросы по Xamarin, iOS, Android.

Первые Xamarin-специалисты жаловались на проблемы при работе со сторонними библиотеками. Сегодня SQLite.NET, loC фреймворки Autofac, MVVC фреймворки и другие популярные библиотеки поддерживают кроссплатформенную разработку. Если вы не собираетесь использовать на проекте исключительно редкие инструменты, то волноваться не о чем.

Xamarin.Forms или Xamarin.IOS + Xamarin.Android?

Зависит от возможностей и желаний. Xamarin.Forms — это инструмент для разработки единого интерфейса для всех платформ. Дизайн описывается в XML-файле, используя синтаксис XAML. Это оценят .NET-разработчики, которые обычно уверенно работают с XAML.

Проблема в том, что программисту будет доступен всего лишь небольшой набор стандартных элементов управления, внешняя оболочка, связанная с нативными кнопками, чекбоксами и прочим. Теоритически, в Xamarin.Forms используется до 100% общего кода, но только для приложений с совсем уж простым интерфейсом, вроде «Hello world». Если вам захочется что-то, чего нет в наборе, то придётся перерабатывать и сами элементы на каждой платформе по-отдельности. Выбирайте Xamarin.Forms для проектов, где вы готовы сэкономить на гибкости настройки интерфейса.

Чаще «схалявить» не получается и нужно использовать Xamarin.iOS и Xamarin.Android. Так у вас будет прямой доступ к API платформ и полный набор элементов управления, а каждая платформа будет представлена отдельным решением.

Так подойдет мне Xamarin или нет?

Ответьте на три вопроса и станет ясно, подходит ли вам Xamarin:

  • Интерфейс приложения без сложной логики взаимодействия и нестандартных элементов управления?
  • У вас в команде есть мобильные разработчики?
  • Вы планируете другие кроссплатформенные проекты (пусть даже не на Xamarin) в ближайшее время?

Если вы ответили «да» на все вопросы, тогда Xamarin — хорошее вложение для вашей команды и проекта в долгосрочной перспективе.

Автор: Мария Куликовская, веб-разработчик, Itransition

Мария работает в Itransition более трех лет, отвечая за планирование проектов, выбор технологий под бизнес-требования заказчика, управление развертыванием и пост-проектной поддержкой и т.п. Участвовала в разработке самых разных систем, как мобильных, так и десктопных. Сфера особого интереса — базы данных.

Последние записи

В IT с непрофильным образованием? Легко!

Advanced debugging в Xcode: средства отладки, про которые часто забывают

Будни разработчика на Кипре

Свой среди своих: гуманитарии в IT

Собрались и погнали!

Наш первый опыт разработки на Xamarin

Полгода назад мы завершили разработку внутрикорпоративного мобильного приложения “Company Staff”. Company Staff (далее – CS) – это приложение для сотрудников нашей компании, помогающее нам искать коллег, получать информацию о них (дата рождения, вишлисты, достижения и т.д.), узнавать последние новости компании и многое другое.

Все началось с того, что у нашей .NET-команды между завершенным проектом и запланированным стартом нового выдалось свободное время, которое решили потратить на изучение новой для нас технологии – Xamarin. И чтобы не тратить время зря, мы хотели сразу опробовать эту технологию на приложении, которое было бы полезно Noveo. Долго думать не пришлось – мы вспомнили о Company Staff. Это приложение уже существовало в виде Web- и iOS-версий и, соответственно, готового Web API. Также существовало Android-приложение, которое просто импортировало контакты в телефон. Более того, наши дизайнеры уже потрудились и приготовили замечательный дизайн для нового Android-приложения, так что выбор был очевиден.

В данной статье мы расскажем о самом Xamarin (а точнее – о Xamarin Forms), о процессе разработки нашего приложения с помощью этой технологии, о трудностях, с которыми мы столкнулись, и об общем впечатлении о кроссплатформенной разработке на Xamarin. Начнем.

Xamarin

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

Xamarin – это фреймворк для кросс-платформенной разработки мобильных приложений, основанный на open-source реализации платформы .Net – Mono. С помощью Xamarin можно разрабатывать приложения для Apple-, Android- и Windows-девайсов, используя один язык – C#, и одно IDE – Visual Studio или Xamarin Studio. Также данная платформа предоставляет полный доступ к SDK, единую среду выполнения и даже родные механизмы создания UI. Приложения на Xamarin практически не уступают в производительности и внешнему виду нативным.

Многие до сих пор полагают, что кроссплатформенная разработка должна подчиняться фразе “write once, run everywhere”, что подразумевает, что один код должен работать на нескольких платформах без изменений. Однако такой подход обычно приводит к приложениям с ограниченной функциональностью (многие фичи, присущие той или иной платформе, недоступны) и универсальным UI, который не вписывается ни в одну из мобильных платформ.

Xamarin, в свою очередь, нельзя отнести к категории “write once, run everywhere”, хотя бы потому, что одна из его важнейших функций – возможность реализовать нативный UI для каждой платформы отдельно. При этом большая часть кода, которая включает в себя бизнес-логику, слой данных, доступ к ним и др., остаётся общей для всех платформ.

Как это работает?

Исходники на C# становятся нативными приложениями совершенно различными путями на каждой платформе. Главное различие заключается в предварительной компиляции:

  • Для iOS используется Ahead-of-Time (AOT) компиляция. Xamarin.iOS-приложение компилируется прямо в машинный код (ARM Assembly language). Поскольку Apple запрещает динамическую генерацию кода, накладывается ряд ограничений (см. Xamarin.iOS Limitations).
  • Для Android все немного сложнее. Для выполнения приложений в Android используется виртуальная Java-машина Dalvik. Нативные Java-приложения компилируются в промежуточный байт-код, который интерпретируется Dalvik’ом в команды процессора во время исполнения программы (Just-in-time (JIT) компиляция). Xamarin в свою очередь компилирует C#-код в промежуточный байт-код для виртуальной машины Mono, которая упаковывается в приложение. При запуске Xamarin-приложения две виртуальные машины Mono и Dalvik работают параллельно, обмениваясь данными через JNI.
  • Для Windows все как обычно. C# компилируется в IL и выполняется встроенной средой выполнения. Инструменты Xamarin’a не нужны. Также можно отметить, что для приложений Universal Windows Platform (UWP) остаётся функция .NET Native, которая ведет себя аналогично AOT-компиляции для iOS.

Результатом скомпилированного Xamarin-приложения являются .app-файл для iOS, .apk для Android и .appxbundle для UWP. Эти файлы неотличимы от пакетов приложений, созданных стандартными для платформ IDE, и развертываются точно таким же образом.

Xamarin.Forms

Первый же вопрос, который мы себе задали, – зачем для нашего приложения нужен Xamarin? Ведь по большому счету все, что должно уметь приложение, – это отобразить данные, которые приходят с сервера. По предварительным оценкам, только 25-30% приложения общие для всех платформ, а всё остальное – UI, который нужно реализовывать отдельно для каждой платформы.

Хотя целью Company Staff первоначально было обучение новой технологии, чтобы максимально проникнуться платформой и в дальнейшем заниматься серьёзными коммерческими проектами, мы решили отнестись к “тренингу” как к продукту. Тем более, что он действительно имел практическое применение в реалиях нашей компании. И поэтому нужно было сначала ответить на вопрос целесообразности применения Xamarin.

К счастью, разработчики Xamarin позаботились о нас и предоставили Xamarin Forms API.

Xamarin.Forms – это “надстройка” над Xamarin.iOS и Xamarin.Android, которая позволяет создавать кросс-платформенный пользовательский интерфейс. Такой интерфейс можно создать как с помощью XAML, так и кодом С#. Устроено это довольно просто: верстка реализуется с помощью Xamarin.Forms-компонентов, которые транслируются в нативные компоненты с помощью специальных классов-рендереров на каждой целевой платформе. Кроме того, важным достоинством является полноценная поддержка MVVM (Model-View-ViewModel) – наличие привязки данных (data binding) и управление ими. Таким образом, в идеальном случае разработка на Xamarin.Forms немногим отличается от разработки приложений UWP/WindowsPhone/WPF.

Первые шаги

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

Для Xamarin Forms есть 3 архитектурных подхода для общего кросс-платформенного кода:

  • Shared Asset Projects (SAP) – довольно простой подход. Такой проект не компилируется в отдельную сборку, а “встраивается” в проекты, в которых используется. Такой подход позволяет использовать платформо-зависимый код наряду с общим, используя директивы компилятора #if.
  • Portable Class Libraries (PCL) – кроссплатформенная библиотека. В настройках такой библиотеки необходимо указать целевые платформы, в которых она будет использоваться: В результате будут доступны только те функции, которые находятся в пересечении указанных платформ. PCL не позволит использовать какой-либо платформо-зависимый функционал, таким образом гарантируя, что PCL код запустится на всех указанных платформах.
  • .NET Standard Libraries – более новая технология, упрощенная версия PCL, но с более широким функционалом. На момент разработки нашего приложения .NETStandard еще не появился в общем доступе, и мы, естественно, не могли рассматривать его. Хотя стоит отметить, что сегодня мы бы выбрали именно этот подход, поскольку он более гибок и прогрессивен.

После краткого описания первых двух подходов очевидно, что у PCL намного больше преимуществ перед SAP. Конечно, могут возникнуть ситуации, когда какая-либо фича не может быть реализована общим кодом (например, работа с файлами), при условии, что стоит строгая задача локализовать бизнес-логику в отдельном проекте. В таком случае можно скомбинировать оба подхода. В нашей же ситуации мы решили не прибегать к SAP, а платформо-зависимый функционал реализовать в проектах под конкретную ОС.

Верхняя структура проекта проста, определилась сразу и почти не изменилась до релиза проекта:

— CompanyStaff – PCL библиотека Forms, которая содержит общие для всех платформ модели (Models), вью-модели (ViewModels), локализацию, общие настройки приложений, бизнес-логику и, собственно, сами Xamarin.Forms вью (Views);

— CompanyStaff.Droid, CompanyStaff.iOS, CompanyStaff.UWP – по большому счету это и есть нативный Xamarin. Здесь содержится реализация нативного функционала приложения, и именно эти проекты затем собираются в пакеты приложений под указанные платформы. Код данных проектов – это C#-обертки над нативными классами. В нашем случае классы этих проектов можно разделить на две категории:

1) Рендереры – классы, отвечающие за отображение визуальных компонент. Они содержат ссылки на PCL-объекты и выставляют свои свойства согласно этим объектам. В дальнейшем рендереры разворачиваются в нативные контролы.

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

Для начала нужно создать класс в PCL, унаследованный от Entry.

Затем просто добавляем новый контрол в код пользовательского интерфейса (в нашем случае интерфейс описан в XAML):

Это все, что нужно в PCL для нашего простого примера. Переходим к реализации рендереров. Для этого необходимо всего три вещи:

  • Создать унаследованный от EntryRenderer класс, который отвечает за отображение нативного элемента.
  • Переопределить метод OnElementChanged, в котором необходимо описать логику кастомизации контрола. Этот метод вызывается при создании соответствующего контрола Forms.
  • Добавить атрибут ExportRenderer на класс рендерера, чтобы “зарегистрировать” наш класс в Xamarin.Forms для рендеринга определенного контрола.

Вот так выглядит код рендереров для нашего поля ввода:

2) Реализация DependencyService’ов – реализация функционала, не связанного с UI, позволяющая работать с данным функционалом из PCL на уровне абстракций.

Одной из важных функций в CS является возможность добавления контактов сотрудника в телефонную книгу устройства. Поскольку реализация данного функционала сильно “платформо-зависима”, а доступ к нему нам необходим из PCL кода, то наиболее удобный способ – использование DependencyService’ов.

Для начала нужен интерфейс в PCL для операций добавления контактов. В нашем приложении он выглядит так:

Затем нужно реализовать данный интерфейс на каждой платформе. Общая схема одинакова (за исключением .NET Native компиляции UWP проектов). Пример для Android:

Далее из PCL кода достаточно вызвать фабричный метод Get () у статического класса DependencyService для выполнения описанных операций:

В CS с помощью DependencyService’ов реализована работа с контактами, ориентацией девайса, социальными сетями, локализацией, защищенным хранилищем данных и др.

CompanyStaff.Dependencies – сюда мы вынесли интерфейсы DependencyService’ов.

— CompanyStaff.ServicesContract и CompanyStaff.Services – интерфейсы и реализация работы с web-сервисом соответственно.

— Bootstrapper – регистрация сервисов в IoC контейнере для Dependency Injection.

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

  • базовые классы для работы с MVVM (ViewModelBase, Commands, Events);
  • Dependency Injection, в первую очередь для внедрения сервисов во вью-модели;
  • реализация межстраничной навигации.

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

Существует несколько наиболее популярных фреймворков для данных целей:

Каждый из этих фреймворков портирован для Xamarin.Forms. Со всеми, кроме последнего, мы имели опыт работы раньше на других платформах – UWP, WindowsPhone, WPF.

MVVMCross и Prism – большие и мощные фреймворки с большой поддержкой коммьюнити. Поскольку и Xamarin, и Xamarin.Forms быстро развиваются, количество форков и звездочек на github’e на данный момент и в дальнейшем стало определяющим фактором при выборе сторонних инструментов.

Мы решили одновременно попробовать оба фреймворка и выбрать более удобный. С MVVMCross сразу возникли проблемы c инициализацией на UWP. Prism, в свою очередь, завелся сразу и без каких-либо трудностей. Долго не разбираясь, оставили Prism. Тем более, что мы давно хотели его «пощупать».

В итоге – мы остались довольны выбором Prism, в первую очередь – благодаря удобной реализации навигации MVVM-путём, хоть и пришлось повозиться с навигацией на уровне Xamarin.Forms.

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

0 0 голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector