iMessage app 开发

来源:互联网 发布:python兼职讲师 编辑:程序博客网 时间:2024/05/21 10:14

说在前面:

iMessage app 是iOS10中嵌入到Message内容的iMessage apps,包含简单的表情包以及自定义的复杂界面。

iMessage App类别:

* Sticker pack app :单独的表情包应用,不需要编写任何代码,只需拖动图片即可,包括静态和动态表情。

* iMessage app :单独的iMessage应用,要编写代码,可以发送表情包、文字、视频、音频。

上面两个也可以以一个app的扩展嵌入到iMessage应用中。


一、创建独立的表情包应用(Sticker pack app ):无需代码

表情包限制:

* Small :100 x 100   @3x scale (300 x 300 pixel image)

* Medium : 136 x 136  @3x scale (378 x 378 pixel image)

* Large : 206 x 206  @3x scale (618 x 618 pixel image)

其他限制(表情包大小):

* 文件中的 images 不可以大于500kb

* image 不可以小于100 x 100 pt (300 x 300 pixels)

* image 不可以大于206 x 206 pt (618 x 618 pixels)

image 格式必须是PNG、APNG、JPEG、GIF



1、添加静态表情包 

< 1 > 创建Sticker Pack 工程

create a new Xcode project > iOS > Sticker Pack Application > Next 



< 2 > 拖入图片

选中Stickers.xcsstickers > 选中右边的Sticker Pack文件夹 > 选中素材中的所有图片 > 拖入Sticker Pack中


< 2 > 运行效果


这样就完成了Sticker pack静态表情包

2、添加动态表情包

< 1 >  选中Sticker Pack文件夹 > 点击下方➕号 > 选择New Sticker Sequence添加动态表情


< 2 > 拖入该动态图片的各个帧图片即可(拖入Frame1位置)。




< 3 > 可设置动态表情包的时间

选中Sticker Sequence > 点击右面板中的属性检查器 > 设置Sticker Sequence分类下的Frame Per Second


< 4 >运行效果





这样就已经完成了Sticker pack app

二、创建 iMessage 应用(iMessage app ):

个人理解有三种实现方式:

* 直接在MessagesAppViewController 类中添加View。简单,复杂的View不好管理。

* 创建MSStickerBrowserViewController ,作为子类添加到 MessagesAppViewController 中,只需要实现贴纸界面可以选择这种方式比较简单。

* 自定义一个ViewController,作为子类添加到 MessagesAppViewController 中,添加过后和扑通的App开发基本没区别,但是要注意View高度的变化,自动布局。


Message框架的几个基础类介绍:

MessagesAppViewController :iMessage App 程序的入口,工程默认创建其子类MessagesAppViewController 。

MSSticker : 表情。是 NSObject 的子类 。

MSStickerBrowserView : 表情View 。

MSStickerBrowViewController : 表情ViewController 。

MSStickerBrowViewDataSource :表情数据来源代理 。 

其实,上面四个类就类似于 UITableViewCell 、 UITableViewController 、 UITableViewDataSource 的关系。


1、自定义贴纸布局

< 1 > Create a new Xcode project > IOS > iMessage Application > Next

生成的目录结构,主要是针对 MessageExtension 文件夹开发。


< 2 > 将图片资源添加到工程中 。

< 3 > 在 MessagesAppViewController 中加载表情包数据,创建MSStickerBrowserViewController 实现MSStickerBrowserViewDataSource 代理数据 。

[objc] view plain copy
  1. #import "MessagesViewController.h"  
  2.   
  3. @interface MessagesViewController ()<MSStickerBrowserViewDataSource>  
  4. //创建数据原数组来存储我们的表情包  
  5. @property (nonatomic,strongNSMutableArray *stickersArray;  
  6.   
  7. @end  
  8.   
  9. @implementation MessagesViewController  
  10.   
  11. - (void)viewDidLoad {  
  12.       
  13.     [super viewDidLoad];  
  14.     // 初始化本地表情包  
  15.     [self loadStickers];  
  16.     // 创建本地表情包控制器  
  17.     [self createStickerBrowserViewController];  
  18.       
  19. }  
  20.   
  21. //加载表情包,上面设置了数据源,所以我们要加载图片(数据)  
  22. - (void)loadStickers{  
  23.     NSMutableArray *mArray = [NSMutableArray array];  
  24.       
  25.     for (int i = 1; i < 11; i++) {  
[objc] view plain copy
  1. <span style="white-space:pre">    </span>//传入对应的url  
  2.         NSURL *url = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"scoops%02d_sticker", i] withExtension:@"png"];  
  3.         MSSticker *sticker = [[MSSticker alloc]initWithContentsOfFileURL:url localizedDescription:@"" error:nil];  
  4.         [mArray addObject:sticker];  
  5.     }  
  6.     self.stickersArray = mArray;  
  7.       
  8. }  
  9.   
  10. // 要想显示图片表情,必须要初始化一个MSStickerBrowserViewController作为根视图  
  11. - (void)createStickerBrowserViewController{  
  12.     MSStickerBrowserViewController *browserVc = [[MSStickerBrowserViewController alloc]initWithStickerSize:MSStickerSizeSmall];  
  13.     [self addChildViewController:browserVc];  
  14.     [self.view addSubview:browserVc.view];  
  15.     browserVc.stickerBrowserView.backgroundColor = [UIColor cyanColor];  
  16.     //设置数据源  
  17.     browserVc.stickerBrowserView.dataSource = self;  
  18.     browserVc.view.translatesAutoresizingMaskIntoConstraints = NO;  
  19.       
  20.     //自动布局  
  21.     [self.view.topAnchor constraintEqualToAnchor:browserVc.view.topAnchor].active = YES;  
  22.     [self.view.bottomAnchor constraintEqualToAnchor:browserVc.view.bottomAnchor].active = YES;  
  23.     [self.view.leftAnchor constraintEqualToAnchor:browserVc.view.leftAnchor].active = YES;  
  24.     [self.view.rightAnchor constraintEqualToAnchor:browserVc.view.rightAnchor].active = YES;  
  25.       
  26.       
  27. }  
  28.   
  29. #pragma mark - MSStickerBrowserViewDataSource 数据源代理方法(必须实现)  
  30. // 一共有多少个  
  31. -(NSInteger)numberOfStickersInStickerBrowserView:(MSStickerBrowserView *)stickerBrowserView{  
  32.       
  33.     return self.stickersArray.count;  
  34. }  
  35.   
  36. // 每一个要显示什么  
  37. - (MSSticker *)stickerBrowserView:(MSStickerBrowserView *)stickerBrowserView stickerAtIndex:(NSInteger)index{  
  38.       
  39.     return self.stickersArray[index];  
  40. }  
  41.   
  42.   
  43.   
  44. @end  

这样就实现了在代码中添加贴图 。


2、自定义ViewController可发送图片、音频、视频文件

创建方式:

* 可以像上面一样添加一个 iMessage 应用

* 可以再一个普通的APP中加入iMessage扩展(APP)。


接下来我们主要讲一讲如何在已有的项目中添加 iMessage APP 扩展。

< 1 > 首先创建一个普通的工程,点击➕号添加 iMessage 扩展




点击Finish,弹框选Yes ,完成添加扩展生成的目录和创建的 iMessage App 在 MyMessage2Extension 目录下是一样的 。


完整代码:

[objc] view plain copy
  1. #import "MessagesViewController.h"  
  2.   
  3. @implementation MessagesViewController  
  4.   
  5. - (void)viewDidLoad {  
  6.     [super viewDidLoad];  
  7.     [self setupButton];  
  8. }  
  9.   
  10. // 创建按钮 (懒加载的方法)  
  11. -(UIButton *)createButtonWithTitle:(NSString *)title action:(SEL)action{  
  12.     UIButton *button = [[UIButton alloc] init];  
  13.     [button setBackgroundColor:[self randomColor]];  
  14.     button.translatesAutoresizingMaskIntoConstraints = NO;  
  15.     [button setTitle:title forState:UIControlStateNormal];  
  16.     [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];  
  17.     [self.view addSubview:button];  
  18.     return button;  
  19. }  
  20.   
  21. //button的背景颜色设置(随机颜色)  
  22. -(UIColor *)randomColor{  
  23.     CGFloat red = (CGFloat)random() / (CGFloat)RAND_MAX;  
  24.     CGFloat green = (CGFloat)random() / (CGFloat)RAND_MAX;  
  25.     CGFloat blue = (CGFloat)random() / (CGFloat)RAND_MAX;  
  26.     return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];  
  27. }  
  28.   
  29. //设置按钮  
  30. - (void)setupButton {  
  31.     UIButton *photoButton = [self createButtonWithTitle:@"图片" action:@selector(sendPhoto)];  
  32.     UIButton *musicButton = [self createButtonWithTitle:@"音乐" action:@selector(sendMusic)];  
  33.     UIButton *videoButton = [self createButtonWithTitle:@"视频" action:@selector(sendVideo)];  
  34.     UIButton *stickerButton = [self createButtonWithTitle:@"贴纸" action:@selector(sendStick)];  
  35.     UIButton *alterButton = [self createButtonWithTitle:@"自定义" action:@selector(sendAlter)];  
  36.   
  37.     [photoButton.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;  
  38.     [photoButton.rightAnchor constraintEqualToAnchor:musicButton.leftAnchor].active = YES;  
  39.     [photoButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;  
  40.     [photoButton.heightAnchor constraintEqualToConstant:50].active = YES;  
  41.       
  42.     [musicButton.rightAnchor constraintEqualToAnchor:videoButton.leftAnchor].active = YES;  
  43.     [musicButton.widthAnchor constraintEqualToAnchor:photoButton.widthAnchor].active = YES;  
  44.     [musicButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;  
  45.     [musicButton.heightAnchor constraintEqualToConstant:50].active = YES;  
  46.       
  47.     [videoButton.rightAnchor constraintEqualToAnchor:stickerButton.leftAnchor].active = YES;  
  48.     [videoButton.widthAnchor constraintEqualToAnchor:photoButton.widthAnchor].active = YES;  
  49.     [videoButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;  
  50.     [videoButton.heightAnchor constraintEqualToConstant:50].active = YES;  
  51.       
  52.     [stickerButton.rightAnchor constraintEqualToAnchor:alterButton.leftAnchor].active = YES;  
  53.     [stickerButton.widthAnchor constraintEqualToAnchor:photoButton.widthAnchor].active = YES;  
  54.     [stickerButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;  
  55.     [stickerButton.heightAnchor constraintEqualToConstant:50].active = YES;  
  56.       
  57.     [alterButton.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;  
  58.     [alterButton.widthAnchor constraintEqualToAnchor:photoButton.widthAnchor].active = YES;  
  59.     [alterButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;  
  60.     [alterButton.heightAnchor constraintEqualToConstant:50].active = YES;  
  61. }  
  62.   
  63. //发送图片  
  64. -(void)sendPhoto{  
  65.     NSURL *url = [[NSBundle mainBundle] URLForResource:@"image" withExtension:@"png"];  
  66.     [self sendMessageWithURL:url];  
  67. }  
  68. //发送音乐  
  69. -(void)sendMusic{  
  70.     NSURL *url = [[NSBundle mainBundle] URLForResource:@"blank" withExtension:@"mp3"];  
  71.     [self sendMessageWithURL:url];  
  72. }  
  73. //发送视频  
  74. -(void)sendVideo{  
  75.     NSURL *url = [[NSBundle mainBundle] URLForResource:@"moments" withExtension:@"mp4"];  
  76.     [self sendMessageWithURL:url];  
  77. }  
  78. //发送贴纸  
  79. -(void)sendStick{  
  80.     [self requestPresentationStyle:MSMessagesAppPresentationStyleCompact];  
  81.     NSURL *url = [[NSBundle mainBundle] URLForResource:@"sticker" withExtension:@"png"];  
  82.   
  83.     MSSticker *sticker = [[MSSticker alloc] initWithContentsOfFileURL:url localizedDescription:@"localizedDescription" error:nil];  
  84.       
  85.     [self.activeConversation insertSticker:sticker completionHandler:^(NSError * _Nullable error) {  
  86.         if (error) {  
  87.             NSLog(@"%@",error);  
  88.         }  
  89.     }];  
  90. }  
  91. //发送自定义消息  
  92. -(void)sendAlter{  
  93.     [self requestPresentationStyle:MSMessagesAppPresentationStyleCompact];  
  94.     MSMessageTemplateLayout *layout = [[MSMessageTemplateLayout alloc] init];  
  95.     layout.image = [UIImage imageNamed:@"image"];  
  96.     layout.imageTitle = @"老虎";  
  97.     MSMessage *message = [[MSMessage alloc] init];  
  98.     message.layout =layout;  
  99.     [self.activeConversation insertMessage:message completionHandler:^(NSError * _Nullable error) {  
  100.         if (error) {  
  101.             NSLog(@"%@",error);  
  102.         }  
  103.     }];  
  104. }  
  105.   
  106. // 通过 URL 发送消息  
  107. -(void)sendMessageWithURL:(NSURL *)url{  
  108.     [self requestPresentationStyle:MSMessagesAppPresentationStyleCompact];  
  109.     [self.activeConversation insertAttachment:url withAlternateFilename:nil completionHandler:^(NSError * _Nullable error) {  
  110.         if (error) {  
  111.             NSLog(@"%@",error);  
  112.         }  
  113.     }];  
  114. }  
  115.   
  116.   
  117. @end  


代码分析:

发送图片、音视频文件

activeConversation 是 MSMessagesAppViewController 里面的一个属性,发送音视频文件,都是通过这个方法。

[objc] view plain copy
  1. [self.activeConversation insertAttachment:url withAlternateFilename:nil completionHandler:^(NSError * _Nullable error) {  
  2.     if (error) {  
  3.         NSLog(@"%@",error);  
  4.     }  
  5. }];  

传入对应文件的URL即可。

[objc] view plain copy
  1. NSURL *url = [[NSBundle mainBundle] URLForResource:@"image" withExtension:@"png"];  

有时候可能找不到对应的URL, 可以再这里查看是否有加入的文件,如果没有加入,店家➕号加入该文件即可。




发送贴纸

发送贴纸通过这个方法,同理传入对应的URL 即可,注意贴纸的尺寸问题 。

[objc] view plain copy
  1. MSSticker *sticker = [[MSSticker alloc] initWithContentsOfFileURL:url localizedDescription:@"localizedDescription" error:nil];  
  2.   
  3. [self.activeConversation insertSticker:sticker completionHandler:^(NSError * _Nullable error) {  
  4.     if (error) {  
  5.         NSLog(@"%@",error);  
  6.     }  
  7. }];  


发送自定义消息
发送自定义消息主要是自定义 message 的 layout 属性以及其他的相关属性。

[objc] view plain copy
  1. MSMessageTemplateLayout *layout = [[MSMessageTemplateLayout alloc] init];  
  2. layout.image = [UIImage imageNamed:@"image"];  
  3. layout.imageTitle = @"老虎";  
  4. MSMessage *message = [[MSMessage alloc] init];  
  5. message.layout =layout;  
  6. [self.activeConversation insertMessage:message completionHandler:^(NSError * _Nullable error) {  
  7.     if (error) {  
  8.         NSLog(@"%@",error);  
  9.     }  
  10. }]; 
0 0
原创粉丝点击