作者简介:gennyxu(徐冬成) 天天P图 iOS 工程师
iOS10新加入的基于iMessage的应用扩展,可以丰富发送消息的内容。(分享表情、图片、文字、视频、动态消息;一起完成任务或游戏。)
简单的将发送的数据内型分为三种:
两种显示模式:Compact和Expanded。
Compact模式不能访问键盘和相机,不能使用横向滑动,横向滑动操作会由系统捕获;但可以访问输入框。
Expanded模式不能访问用户输入框;但是可以访问键盘、相机,并且可以使用横向滑动操作。
后面一列的Extension是在已有的App中加入iMessage Extension功能,和众多其他的Extension类似,也基本遵循其他Extension的规范。
从开发角度主要分为两类:
1、Sticker Pack App/Extension;
2、iMessage App/Extension;
创建一个Sticker Pack App,实际上是创建了一个空App加上一个Sticker Pack Extension;创建一个iMessage App,和Sticker Pack App一样,一个空App加上Extension;除了创建时选择不一样:
Sticker Pack Extension可以不写代码,快速加入贴纸并显示;iMessage Extension更加自由一点,可以自己写UI控制贴纸布局,也可以用于发送文字、链接、音视频、交互消息。
优势在于无需代码,打开iMessage自动加载贴纸;非常适合一些第三方表情的开发。贴纸的图片格式支持PNG、APNG、GIF、JPEG。
Sticker显示布局目前只有三种:
Small:100 x 100 points @3x (300 x 300 pixels)
Medium:136 x 136 points @3x (408 x 408 pixels)
Large:206 x 206 points @3x (618 x 618 pixels)
XCode更改布局——无需代码:
建议:
1、必须提供@3x的贴纸图片;系统会在运行时,自动将表情按比例缩小到@2x或@1x来使用;
2、为了显示质量和显示效果,建议提供同时提供@1x和@2x的图片;
3、单个贴纸最大文件大小500KB,为了显示效果最好不小于100x100 points,不大于206x206points。(XCode保存PNG动画时使用24bit调色板可能会导致文件超过预期,请做好预防)
如果需要自定义页面以及Sticker布局,或者网络拉取贴纸、使用相机或IAP等功能,就需要使用iMessage Extension。
1、iMessage App/Extension LifeCycle:
1)、MSMessagesAppViewController:iMessage Extension的自定义的主类,可以通过其回话变量(指向MSConversation的实例)来发送贴纸、链接、图片、音视频,也可以用来发送交互式消息;
2)、MSStickerBrowserViewController:创建自定义的贴纸使用
MSStickerBrowserView 其每一个cell都是MSStickerView
MSStickerView 显示MSSticker贴纸数据,有属性指向MSSticker
MSSticker 贴纸数据,用于发送或者显示
3)、MSConversation:用于发送iMessage的消息;MSMessagesAppViewController有属性指向MSConversation。
4)、MSMessage自定义的消息体,通常用于interactive messages;
5)、MSSession用来描述消息如何发送;通常用于interactive messages。新建interactive message时,新建一个MSSession;当你回复interactive messages时,使用对应消息的MSSession。
6)、MSMessageLayout 描述消息的展示形式,显示样式及文案;是一个抽象类。目前只有MSMessageTemplateLayout这种格式。
上面是一些主要的类,可以通过下图得出主要的关系。
备注:和普通App一样,如果需要使用到相机、麦克风等能力,请一定记得在在Info.plist中加入对应能力所需的描述,否则Extension会Crash。
如图所示,当你创建一个iMessage Extension的工程时;系统会自动创建一个MSMessagesAppViewController。关于iMessage Extension LifeCycle的回调也全位于MSMessagesAppViewController中;所以对于开发者而言iMessage Extension LifeCycle可以看成是MSMessagesAppViewController的LifeCycle。
- (void)didBecomeActiveWithConversation:(MSConversation *)conversation;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)willResignActiveWithConversation:(MSConversation *)conversation;
启动Message Extension后,系统会立刻调用didBecomeActiveWithConversation:。被关闭或其它方式dismiss后,会很快执行willResignActiveWithConversation:,随后系统便可以终止Message Extension,通常会被系统立刻终止,随后回收资源。
2、Compact和Expanded切换过程:
通常可以由系统触发,也可以自己代码逻辑触发。
通过调用MSMessagesAppViewController的中的方法实现切换:
-(void)requestPresentationStyle:(MSMessagesAppPresentationStyle)presentationStyle;
当presentationStyle发生变化时,会调用MSMessagesAppViewController下面两个回调函数;可以在回调中修改UI或数据,不同状态显示不同的页面。
-(void)willTransitionToPresentationStyle:(MSMessagesAppPresentationStyle)presentationStyle;
-(void)didTransitionToPresentationStyle:(MSMessagesAppPresentationStyle)presentationStyle;
3、自定义贴纸数据或UI布局:
如果只需要自定义贴纸数据或UI布局,可以简单实现这个Extension。通常只需要用到下面几个类:MSStickerBrowserViewController、MSStickerBrowserView、MSStickerView 和 MSSticker。前三个类类似于UITableViewController、UITableView、UITableViewCell;MSSticker相当于一个控制贴纸显示的数据模型,支持使用网络地址实例化。
MSStickerBrowserViewController\MSStickerBrowserView通过实现其两个回调来实现贴纸显示。
@protocol MSStickerBrowserViewDataSource <NSObject>
- (NSInteger)numberOfStickersInStickerBrowserView:(MSStickerBrowserView *)stickerBrowserView;
- (MSSticker *)stickerBrowserView:(MSStickerBrowserView *)stickerBrowserView stickerAtIndex:(NSInteger)index;
@end
如果使用MSStickerBrowserViewController,通常将其作为MessagesViewController的childViewController;也可以被present出来显示。
备注:
1)、MSStickerBrowserViewController和MSStickerBrowserView同样只支持Small、Medium、Large三个布局;如不满足需求,只能使用自定义UI控件加上MSStickerView、MSSticker来实现。
2)、页面布局时需要考虑Compact或Expanded两种状态;建议在MessagesViewController中获取其topLayoutGuide和bottomLayoutGuide。
通过MessagesViewController present出来的页面可能会无法获取到正确的数据)
4、MSMessage和Interactive Messages
MSMessage是消息体,内部有MSSession和MSMessageLayout。MSSession用于控制交互消息;MSMessageLayout用于消息布局,即长什么样子。布局只支持MSMessageTemplateLayout这一种布局,如图片所见:
而MSMessage消息的发送都是通过当前回话窗口(MSConversation)完成。通过MessagesViewController的activeConversation属性获取当前会话。可以通过调用MSConversation四个方法发送不同类型消息:
- (void)insertMessage:(MSMessage*)message completionHandler:(void(^)(NSError *))result;
- (void)insertSticker:(MSSticker*)sticker completionHandler:(void(^)(NSError *))result;
- (void)insertText:(NSString *)text completionHandler:(void(^)(NSError*))result;
- (void)insertAttachment:(NSURL *)URL withAlternateFilename:(NSString *)filename completionHandler:(void(^)(NSError *))result;
四个接口分别用于发送交互式消息、Sticker、文本及音视频;简单使用如下:
MSMessage的URL属性通常用来描述消息内容。因为iMessage App只能在iOS系统运行;MacOS收到该消息之后,也不会解析消息内容。如果用户点击该消息并且URL是http类型的,会通过浏览器打开对应的网页。通过URL属性参数实现Interactive Messages数据传递。例如官方Demo通过此字段记录游戏额外数据;消息被点击进入Extension时,会解析该字段。
发送消息时,需要需要注意的是:
从输入框中点击发送消息会触发didStartSendingMessage;从输入框中删除或取消发送会触发didCancelSendingMessage;消息发送成功后,自己也会触发didReceiveMessage。
-(void)didStartSendingMessage:(MSMessage*)message conversation:(MSConversation*)conversation;
-(void)didCancelSendingMessage:(MSMessage*)message conversation:(MSConversation*)conversation;
-(void)didReceiveMessage:(MSMessage*)message conversation:(MSConversation*)conversation;
当前Extension处于Active状态时,选择某条消息会触发:
-(void)willSelectMessage:(MSMessage *)message conversation:(MSConversation *)conversation;
-(void)didSelectMessage:(MSMessage *)message conversation:(MSConversation *)conversation;
如果是通过点击MSMessage打开的Extension,可以通过MSConversation的selectedMessage属性获取当前选中的消息;通常情况需要根据当前选中的MSMessage来配置当前页面及参数。
1、目前iMessage Extension只有发送交互式消息才会提醒用户安装对应App,建议大家尽量发送交互式消息;
2、太局限,iMessage App只能在iOS系统运行,其他品台,如MacOS收到消息之后不会解析消息内容;
3、图标规范:4比3;图标背景简洁,中心容易聚焦;四个角平整,系统会自动给图标加上圆角的Mask;提供多种尺寸的图标;(尺寸参考如下)
此外上传时,需要上传两个图标:One for the App Store for iMessage, and One for the App Store for iPhone and iPad;尺寸分别是1024 x 768pixels 和1024px by 1024px。(这两个图标通常会被scale缩小显示,设计时需要确认缩小的图标也能效果比较好)
参考网址:
[0]https://developer.apple.com/app-store/imessage-app-submissions/
[1]https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/AppExtensionKeys.html
[2]https://developer.apple.com/library/content/samplecode/IceCreamBuilder/Introduction/Intro.html
[3]https://developer.apple.com/ios/human-interface-guidelines/extensions/messaging/
文章后记: 天天P图是由腾讯公司开发的业内领先的图像处理,相机美拍的APP。欢迎扫码或搜索关注我们的微信公众号:“天天P图攻城狮”,那上面将陆续公开分享我们的技术实践,期待一起交流学习! 加入我们: 天天P图技术团队长期招聘: (1) AND / iOS 开发工程师 (2) 图像处理算法工程师 期待对我们感兴趣或者有推荐的技术牛人加入我们(base 上海)!联系方式:ttpic_dev@qq.com