Основы расширения приложения сообщений в Xamarin.iOS
В этой статье показано, как включить расширение приложения сообщений в решение Xamarin.iOS, которое интегрируется с приложением "Сообщения" и представляет новые функциональные возможности для пользователя.
Новое в iOS 10 расширение приложения сообщений интегрируется с приложением "Сообщения" и представляет новые функциональные возможности для пользователя. Расширение может отправлять текст, наклейки, файлы мультимедиа и интерактивные сообщения.
Сведения о расширениях приложений сообщений
Как упоминалось выше, расширение приложения сообщений интегрируется с приложением "Сообщения" и предоставляет пользователю новые функциональные возможности. Расширение может отправлять текст, наклейки, файлы мультимедиа и интерактивные сообщения. Доступны два типа расширения приложения сообщений:
- Пакеты с наклейками — содержит коллекцию стикеров, которые пользователь может добавить в сообщение. Пакеты с наклейками можно создавать без написания кода.
- Приложение iMessage — может представлять пользовательский интерфейс в приложении "Сообщения" для выбора стикеров, ввода текста, включая файлы мультимедиа (с дополнительными преобразованиями типов) и создание, редактирование и отправка сообщений взаимодействия.
Расширения приложений сообщений предоставляют три основных типа контента:
- Интерактивные сообщения — это тип пользовательского содержимого сообщения, создаваемого приложением, когда пользователь нажимает на сообщение, приложение будет запущено на переднем плане.
- Наклейки — это изображения, созданные приложением, которое может быть включено в сообщения, отправляемые пользователями.
- Другое поддерживаемого содержимого . Приложение может предоставлять такие материалы, как фотографии, видео, текст или ссылки на любые другие типы контента, которые всегда поддерживаются приложением "Сообщения".
Новое приложение для iOS 10 теперь включает в себя собственный выделенный, встроенный в App Store. Все приложения, включающие расширения приложений сообщений, будут отображаться и продвигаться в этом магазине. В новом ящике приложений сообщений будут отображаться все приложения, скачанные из Магазина сообщений, чтобы обеспечить быстрый доступ к пользователям.
Кроме того, в iOS 10 компания Apple добавила inline App Attribution, что позволяет пользователю легко обнаруживать приложение. Например, если один пользователь отправляет содержимое другому из приложения, которое не установлен 2-й пользователь (например, наклейка), имя отправляющего приложения отображается под содержимым в журнале сообщений. Если пользователь нажимает имя приложения, откроется Магазин приложений сообщений и приложение, выбранное в магазине.
Расширения приложений сообщений похожи на существующие приложения iOS, знакомые разработчику с созданием, и у них будет доступ ко всем стандартным платформам и функциям стандартного приложения iOS. Например:
- У них есть доступ к покупке в приложении.
- У них есть доступ к Apple Pay.
- У них есть доступ к оборудованию устройства, например к Камера.
Расширения приложений сообщений поддерживаются только в iOS 10, однако содержимое, которое отправляет эти расширения, можно просматривать на устройствах watchOS и macOS. Новая страница "Последние", добавленная в watchOS 3, будет отображать последние наклейки, отправленные с телефона, в том числе из расширений приложений сообщений, и позволить пользователю отправлять эти наклейки из часов.
Сведения о платформе сообщений
Платформа "Сообщения" в iOS 10 предоставляет интерфейс между расширением "Приложения сообщений" и приложением "Сообщение" на устройстве iOS пользователя. Когда пользователь запускает приложение из приложения "Сообщения", эта платформа позволяет обнаружить приложение и предоставить данные и контекст, необходимые для размещения пользовательского интерфейса.
После запуска приложения пользователь взаимодействует с ним, чтобы создать новое содержимое для совместного использования с помощью сообщения. Затем приложение использует платформу "Сообщения" для передачи созданного содержимого в приложение "Сообщения" для обработки.
Платформа сообщений и расширения приложений сообщений основаны на существующих технологиях расширений приложений iOS. Дополнительные сведения о расширениях приложений см. в руководстве по программированию расширений приложений Apple.
В отличие от других точек расширения, предоставляемых Apple во всей системе, разработчику не нужно предоставлять хост-приложение для расширений приложений сообщений, так как само приложение сообщения выступает в качестве контейнера. Однако разработчик может включить расширение приложений сообщений внутри нового или существующего приложения iOS и доставки его вместе с пакетом.
Если расширения приложений сообщений включены в пакет приложения iOS, значок приложения будет отображаться как на начальном экране устройства, так и в ящике приложений сообщений из приложения "Сообщения". Если он не включен в пакет приложений, расширение "Приложения сообщений" будет отображаться только в ящике приложений сообщений.
Даже если расширения приложений сообщений не включены в пакет приложений узла, разработчику потребуется предоставить значок приложения в пакете расширения "Приложения сообщений", так как это значок, который будет отображаться в других частях системы, таких как ящик приложения сообщений или Параметры, для расширения.
О наклейках
Apple разработала наклейки как новый способ для пользователей iMessage для обмена данными, позволяя наклейкам отправляться встроенным образом, как любое другое содержимое сообщения или они могут быть присоединены к предыдущим пузырям сообщений внутри беседы.
Что такое наклейки?
- Они представляют собой изображения, которые предоставляет расширение приложений сообщений.
- Они могут быть анимированными или статическими изображениями.
- Они предоставляют новый способ предоставления общего доступа к содержимому изображения изнутри приложения.
Существует два способа создания стикеров:
- Расширения приложений для пакетов с наклейками можно создавать из Xcode без включения кода. Все, что необходимо, — это ресурсы для стикеров и значков приложения.
- Создав стандартное расширение приложений сообщений, которое предоставляет наклейки из кода через платформу сообщений.
Создание пакетов с наклейками
Пакеты с наклейками создаются из специального шаблона внутри Xcode и просто предоставляют статический набор ресурсов изображений, которые можно использовать в качестве наклейки. Как уже упоминалось выше, разработчик просто перетаскивает файлы изображений в папку "Пакет наклейки" в каталог активов стикеров.
Чтобы изображение было включено в пакет стикером, оно должно соответствовать следующим требованиям:
- Изображения должны находиться в формате PNG, APNG, GIF или JPEG. Apple предлагает использовать только форматы PNG и APNG при предоставлении ресурсов Стикера.
- Анимированные наклейки поддерживают только форматы APNG и GIF.
- Изображения с наклейками должны предоставлять прозрачный фон, так как они могут быть помещены над пузырьками сообщений в беседе пользователем.
- Отдельные файлы изображений должны быть меньше 500 КБ.
- Изображения не могут быть меньше 100x100 точек или больше 206 x 206 точек.
Внимание
Изображения с наклейками всегда должны быть предоставлены в разрешении в диапазоне @3x
пикселей 300 x 300 до 618 x 618 пикселей. Система автоматически создаст @2x
версии @1x
во время выполнения.
Apple предлагает протестировать ресурсы изображения наклейки на различных цветных фонах (таких как белый, черный, красный, желтый и многоцветный) и над фотографиями, чтобы убедиться, что они выглядят лучше во всех возможных ситуациях.
Пакеты с наклейками могут предоставлять наклейки в одном из трех доступных размеров:
- Небольшой - 100 x 100 точек.
- Средняя — 136 x 136 точек. Это размер по умолчанию.
- Большой - 206 x 206 очков.
Используйте инспектор атрибутов Xcode, чтобы задать размер всего пакета Стикера и предоставить только ресурсы изображений, соответствующие запрошенным размеру, для получения наилучших результатов в браузере стикером внутри приложения "Сообщения".
Дополнительные сведения см. в справочнике по сообщениям Apple.
Создание пользовательского интерфейса наклейки
Если приложению требуется больше контроля или гибкости, чем предоставляется пакетом стикера, он может включать расширение приложения сообщений и предоставлять наклейки через платформу "Сообщения" для пользовательского интерфейса наклейки.
Каковы преимущества создания пользовательского интерфейса наклейки?
- Позволяет приложению настраивать отображение стикеров пользователям приложения. Например, чтобы представить наклейки в формате, отличном от стандартного макета сетки или на другом цветном фоне.
- Позволяет стикеры динамически создаваться из кода, а не включаться в качестве статических ресурсов изображений.
- Позволяет динамически загружать ресурсы образов с веб-сервера разработчика без необходимости выпуска новой версии в App Store.
- Позволяет получить доступ к камере устройства, чтобы создать наклейки на лету.
- Разрешает покупки в приложении, чтобы пользователь смог приобрести дополнительные наклейки внутри приложения.
Чтобы создать пользовательский интерфейс наклейки, сделайте следующее:
По умолчанию MessagesViewController.cs
файл будет добавлен в решение. Это основная точка входа в расширение, и она наследуется от MSMessageAppViewController
класса.
Платформа "Сообщения" предоставляет классы для представления доступных стикеров пользователю:
MSStickerBrowserViewController
— управляет представлением, в которое будут представлены наклейки. Он также соответствуетIMSStickerBrowserViewDataSource
интерфейсу для возврата счетчика наклейки и наклейки для заданного индекса браузера.MSStickerBrowserView
— Это представление, в котором будут отображаться доступные наклейки.MSStickerSize
— Определяет отдельные размеры ячеек для сетки стикеров, представленных в представлении браузера.
Создание пользовательского браузера с наклейками
Разработчик может дополнительно настроить интерфейс наклейки для пользователя, предоставив пользовательский браузер с наклейками (MSMessageAppBrowserViewController
) в расширении приложения сообщений. Браузер пользовательской наклейки изменяет способ представления наклейки пользователю при выборе наклейки для включения в поток сообщений.
Выполните следующие действия.
Сделайте следующее StickerBrowserViewController.cs
:
using System;
using System.Collections.Generic;
using UIKit;
using Messages;
using Foundation;
namespace MonkeyStickers
{
public partial class StickerBrowserViewController : MSStickerBrowserViewController
{
#region Computed Properties
public List<MSSticker> Stickers { get; set; } = new List<MSSticker> ();
#endregion
#region Constructors
public StickerBrowserViewController (MSStickerSize stickerSize) : base (stickerSize)
{
}
#endregion
#region Private Methods
private void CreateSticker (string assetName, string localizedDescription)
{
// Get path to asset
var path = NSBundle.MainBundle.PathForResource (assetName, "png");
if (path == null) {
Console.WriteLine ("Couldn't create sticker {0}.", assetName);
return;
}
// Build new sticker
var stickerURL = new NSUrl (path);
NSError error = null;
var sticker = new MSSticker (stickerURL, localizedDescription, out error);
if (error == null) {
// Add to collection
Stickers.Add (sticker);
} else {
// Report error
Console.WriteLine ("Error, couldn't create sticker {0}: {1}", assetName, error);
}
}
private void LoadStickers ()
{
// Load sticker assets from disk
CreateSticker ("canada", "Canada Sticker");
CreateSticker ("clouds", "Clouds Sticker");
...
CreateSticker ("tree", "Tree Sticker");
}
#endregion
#region Public Methods
public void ChangeBackgroundColor (UIColor color)
{
StickerBrowserView.BackgroundColor = color;
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Initialize
LoadStickers ();
}
public override nint GetNumberOfStickers (MSStickerBrowserView stickerBrowserView)
{
return Stickers.Count;
}
public override MSSticker GetSticker (MSStickerBrowserView stickerBrowserView, nint index)
{
return Stickers[(int)index];
}
#endregion
}
}
Подробно рассмотрим приведенный выше код. Он создает хранилище для стикеров, которые предоставляет расширение:
public List<MSSticker> Stickers { get; set; } = new List<MSSticker> ();
И переопределяет два метода MSStickerBrowserViewController
класса для предоставления данных для браузера из этого хранилища данных:
public override nint GetNumberOfStickers (MSStickerBrowserView stickerBrowserView)
{
return Stickers.Count;
}
public override MSSticker GetSticker (MSStickerBrowserView stickerBrowserView, nint index)
{
return Stickers[(int)index];
}
Метод CreateSticker
получает путь к ресурсу изображения из пакета расширения и использует его для создания нового экземпляра MSSticker
из этого ресурса, который добавляется в коллекцию:
private void CreateSticker (string assetName, string localizedDescription)
{
// Get path to asset
var path = NSBundle.MainBundle.PathForResource (assetName, "png");
if (path == null) {
Console.WriteLine ("Couldn't create sticker {0}.", assetName);
return;
}
// Build new sticker
var stickerURL = new NSUrl (path);
NSError error = null;
var sticker = new MSSticker (stickerURL, localizedDescription, out error);
if (error == null) {
// Add to collection
Stickers.Add (sticker);
} else {
// Report error
Console.WriteLine ("Error, couldn't create sticker {0}: {1}", assetName, error);
}
}
Метод LoadSticker
вызывается для ViewDidLoad
создания наклейки из именованного ресурса изображения (включенного в пакет приложения) и добавления его в коллекцию стикеров.
Чтобы реализовать браузер пользовательской наклейки, измените MessagesViewController.cs
файл и сделайте его следующим образом:
using System;
using UIKit;
using Messages;
namespace MonkeyStickers
{
public partial class MessagesViewController : MSMessagesAppViewController
{
#region Computed Properties
public StickerBrowserViewController BrowserViewController { get; set;}
#endregion
#region Constructors
protected ViewController (IntPtr handle) : base (handle)
{
// Note: this .ctor should not contain any initialization logic.
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Create new browser and configure it
BrowserViewController = new StickerBrowserViewController (MSStickerSize.Regular);
BrowserViewController.View.Frame = View.Frame;
BrowserViewController.ChangeBackgroundColor (UIColor.Gray);
// Add to view
AddChildViewController (BrowserViewController);
BrowserViewController.DidMoveToParentViewController (this);
View.AddSubview (BrowserViewController.View);
}
#endregion
}
}
Подробно рассмотрим этот код, он создает хранилище для пользовательского браузера:
public StickerBrowserViewController BrowserViewController { get; set;}
И в методе ViewDidLoad
создается экземпляр и настраивается новый браузер:
// Create new browser and configure it
BrowserViewController = new StickerBrowserViewController (MSStickerSize.Regular);
BrowserViewController.View.Frame = View.Frame;
BrowserViewController.ChangeBackgroundColor (UIColor.Gray);
Затем он добавляет браузер в представление, чтобы отобразить его:
// Add to view
AddChildViewController (BrowserViewController);
BrowserViewController.DidMoveToParentViewController (this);
View.AddSubview (BrowserViewController.View);
Дальнейшая настройка наклейки
Дальнейшая настройка стикера возможна, включив только два класса в расширение приложения сообщений:
MSStickerView
MSSticker
Используя приведенные выше методы, расширение может поддерживать выбор стикера, который не зависит от стандартного метода Браузера Стикера. Кроме того, дисплей наклейки можно переключать между двумя разными режимами просмотра:
- Compact — это режим по умолчанию, в котором представление стикером занимает 25 % от представления сообщений.
- Развернутое -Представление наклейки заполняет все представление сообщений.
Это представление наклейки можно переключать между этими режимами программным способом или вручную пользователем.
Ознакомьтесь со следующим примером обработки переключения между двумя различными режимами представления. Для каждого состояния потребуется два разных контроллера представления. Обрабатывает StickerBrowserViewController
представление Compact и выглядит следующим образом:
using System;
using System.Collections.Generic;
using UIKit;
using Messages;
using Foundation;
namespace MessageExtension
{
public partial class StickerBrowserViewController : MSStickerBrowserViewController
{
#region Computed Properties
public MessagesViewController MessagesAppViewController { get; set; }
public List<MSSticker> Stickers { get; set; } = new List<MSSticker> ();
#endregion
#region Constructors
public StickerBrowserViewController (MessagesViewController messagesAppViewController, MSStickerSize stickerSize) : base (stickerSize)
{
// Initialize
this.MessagesAppViewController = messagesAppViewController;
}
#endregion
#region Private Methods
private void CreateSticker (string assetName, string localizedDescription)
{
// Get path to asset
var path = NSBundle.MainBundle.PathForResource (assetName, "png");
if (path == null) {
Console.WriteLine ("Couldn't create sticker {0}.", assetName);
return;
}
// Build new sticker
var stickerURL = new NSUrl (path);
NSError error = null;
var sticker = new MSSticker (stickerURL, localizedDescription, out error);
if (error == null) {
// Add to collection
Stickers.Add (sticker);
} else {
// Report error
Console.WriteLine ("Error, couldn't create sticker {0}: {1}", assetName, error);
}
}
private void LoadStickers ()
{
// Load sticker assets from disk
CreateSticker ("add", "Add New Sticker");
CreateSticker ("canada", "Canada Sticker");
CreateSticker ("clouds", "Clouds Sticker");
CreateSticker ("tree", "Tree Sticker");
}
#endregion
#region Public Methods
public void ChangeBackgroundColor (UIColor color)
{
StickerBrowserView.BackgroundColor = color;
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Initialize
LoadStickers ();
}
public override nint GetNumberOfStickers (MSStickerBrowserView stickerBrowserView)
{
return Stickers.Count;
}
public override MSSticker GetSticker (MSStickerBrowserView stickerBrowserView, nint index)
{
// Wanting to add a new sticker?
if (index == 0) {
// Yes, ask controller to present add sticker interface
MessagesAppViewController.AddNewSticker ();
return null;
} else {
// No, return existing sticker
return Stickers [(int)index];
}
}
#endregion
}
}
Будет AddStickerViewController
обрабатываться расширенное представление наклейки и выглядеть следующим образом:
using System;
using Foundation;
using UIKit;
using Messages;
namespace MessageExtension
{
public class AddStickerViewController : UIViewController
{
#region Computed Properties
public MessagesViewController MessagesAppViewController { get; set;}
public MSSticker NewSticker { get; set;}
#endregion
#region Constructors
public AddStickerViewController (MessagesViewController messagesAppViewController)
{
// Initialize
this.MessagesAppViewController = messagesAppViewController;
}
#endregion
#region Override Method
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Build interface to create new sticker
var cancelButton = new UIButton (UIButtonType.RoundedRect);
cancelButton.TouchDown += (sender, e) => {
// Cancel add new sticker
MessagesAppViewController.CancelAddNewSticker ();
};
View.AddSubview (cancelButton);
var doneButton = new UIButton (UIButtonType.RoundedRect);
doneButton.TouchDown += (sender, e) => {
// Add new sticker to collection
MessagesAppViewController.AddStickerToCollection (NewSticker);
};
View.AddSubview (doneButton);
...
}
#endregion
}
}
Эти MessageViewController
контроллеры представления реализуются для управления запрошенным состоянием:
using System;
using UIKit;
using Messages;
namespace MessageExtension
{
public partial class MessagesViewController : MSMessagesAppViewController
{
#region Computed Properties
public bool IsAddingSticker { get; set;}
public StickerBrowserViewController BrowserViewController { get; set; }
public AddStickerViewController AddStickerController { get; set;}
#endregion
#region Constructors
protected MessagesViewController (IntPtr handle) : base (handle)
{
// Note: this .ctor should not contain any initialization logic.
}
#endregion
#region Public Methods
public void PresentStickerBrowser ()
{
// Is the Add sticker view being displayed?
if (IsAddingSticker) {
// Yes, remove it from view
AddStickerController.RemoveFromParentViewController ();
AddStickerController.View.RemoveFromSuperview ();
}
// Add to view
AddChildViewController (BrowserViewController);
BrowserViewController.DidMoveToParentViewController (this);
View.AddSubview (BrowserViewController.View);
// Save mode
IsAddingSticker = false;
}
public void PresentAddSticker ()
{
// Is the sticker browser being displayed?
if (!IsAddingSticker) {
// Yes, remove it from view
BrowserViewController.RemoveFromParentViewController ();
BrowserViewController.View.RemoveFromSuperview ();
}
// Add to view
AddChildViewController (AddStickerController);
AddStickerController.DidMoveToParentViewController (this);
View.AddSubview (AddStickerController.View);
// Save mode
IsAddingSticker = true;
}
public void AddNewSticker ()
{
// Switch to expanded view mode
Request (MSMessagesAppPresentationStyle.Expanded);
}
public void CancelAddNewSticker ()
{
// Switch to compact view mode
Request (MSMessagesAppPresentationStyle.Compact);
}
public void AddStickerToCollection (MSSticker sticker)
{
// Add sticker to collection
BrowserViewController.Stickers.Add (sticker);
// Switch to compact view mode
Request (MSMessagesAppPresentationStyle.Compact);
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Create new browser and configure it
BrowserViewController = new StickerBrowserViewController (this, MSStickerSize.Regular);
BrowserViewController.View.Frame = View.Frame;
BrowserViewController.ChangeBackgroundColor (UIColor.Gray);
// Create new Add controller and configure it as well
AddStickerController = new AddStickerViewController (this);
AddStickerController.View.Frame = View.Frame;
// Initially present the sticker browser
PresentStickerBrowser ();
}
public override void DidTransition (MSMessagesAppPresentationStyle presentationStyle)
{
base.DidTransition (presentationStyle);
// Take action based on style
switch (presentationStyle) {
case MSMessagesAppPresentationStyle.Compact:
PresentStickerBrowser ();
break;
case MSMessagesAppPresentationStyle.Expanded:
PresentAddSticker ();
break;
}
}
#endregion
}
}
Когда пользователь запрашивает добавление новой наклейки в доступную коллекцию, создается AddStickerViewController
видимый контроллер, а представление "Наклейка" входит в расширенное представление:
// Switch to expanded view mode
Request (MSMessagesAppPresentationStyle.Expanded);
Когда пользователь выбирает наклейку для добавления, он добавляется в доступную коллекцию, а представление Compact запрашивается:
public void AddStickerToCollection (MSSticker sticker)
{
// Add sticker to collection
BrowserViewController.Stickers.Add (sticker);
// Switch to compact view mode
Request (MSMessagesAppPresentationStyle.Compact);
}
Метод DidTransition
переопределяется для обработки переключения между двумя режимами:
public override void DidTransition (MSMessagesAppPresentationStyle presentationStyle)
{
base.DidTransition (presentationStyle);
// Take action based on style
switch (presentationStyle) {
case MSMessagesAppPresentationStyle.Compact:
PresentStickerBrowser ();
break;
case MSMessagesAppPresentationStyle.Expanded:
PresentAddSticker ();
break;
}
}
Итоги
В этой статье описано, как расширение приложения сообщений в решении Xamarin.iOS, которое интегрируется с приложением "Сообщения" и предоставляет новые функциональные возможности пользователю. Он охватывал использование расширения для отправки текста, стикеров, файлов мультимедиа и интерактивных сообщений.