微信分享实践-2019
方案选择
- 方案1:采用第三方的二次开发包,比如友盟。友盟社会化分享开发文档
这个方案的好处是经过了友盟的二次开发,将微信分心,QQ分享,新浪分享等各种各样的分享综合在一起考虑,经过包装,提供了相对统一的接口。另外,友盟统计,友盟崩溃收集等一般都要用的,统一一套,相对比较省心。
- 方案2:抛弃“友盟之类的中间商”,直接集成微信的
API
。微信分享开发手册
这个方案的好处是链路短了,复杂度降低了。另外,微信提供的接口也挺简单好用的,并没有比友盟提供的接口复杂。
选择: 经过评估,本次项目组决定采用方案2,直接集成微信API
。根据网上的说明文档,用起来很方便。这里根据实际情况,选择了一种相对比较简单的方法。
接入方式
-
使用
CocoaPods
的方式,比较省心。只要在工程的Podfile
里面添加pod 'WechatOpenSDK'
就可以了。在使用的地方,只要#import <WXApi.h>
就可以了 -
是否需要添加
URL scheme
? ===》 因为这里的需求是只要分享出去就可以,不需要额外的交互,所以就没有必要添加了。这里添加的URL scheme
作用,是让微信反过来调用我们的APP
。 -
是否需要“重写
AppDelegate
的handleOpenURL
和openURL
方法”?
===》 大多数情况下没有必要。这里的作用是微信拉起我们的APP
,向我们传递的数据可以在这两个方法里面拿到。
我们当前的需求只是分享出去,并不要求微信回传的信息,所以在我们的项目里面就不需要了。
因为我们的需求只需要分享出去就可以,并不关心微信的反馈,所以可以很简单,不需要做很多额外的工作(微信接入文档中几乎80%的工作不需要做)
注册
这个是免不了的,在微信开发者注册之后,就会拿到一个appId
,(在友盟中叫appKey
)。在程序开始的时候注册一下,或者在使用的时候再注册,都是可以的。
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
*
* 需要在每次启动第三方应用程序时调用。第一次调用后,会在微信的可用应用列表中出现,默认开启MTA数据上报。
* iOS7及以上系统需要调起一次微信才会出现在微信的可用应用列表中。
* @attention 请保证在主线程中调用此函数
* @param appid 微信开发者ID
* @param typeFlag 应用支持打开的文件类型
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)registerApp:(NSString *)appid;
检查是否安装了微信
/*! @brief 检查微信是否已被用户安装
*
* @return 微信已安装返回YES,未安装返回NO。
*/
+ (BOOL)isWXAppInstalled;
检查微信版本是否支持分享。微信版本太低,是不能分享的。
/*! @brief 判断当前微信的版本是否支持OpenApi
*
* @return 支持返回YES,不支持返回NO。
*/
+ (BOOL)isWXAppSupportApi;
分享网页
需要额外提供的信息包括网页的url,标题,描述内容,图标等。可以对开发者网站上的例子代码做简单封装,就可以直接用了。
// 网页分享
+ (void)shareWebpage:(NSString *)url title:(NSString *)title content:(NSString *)content icon:(nullable NSString *)icon scene:(int)scene {
// 分享出去,没有返回信息
WXWebpageObject *webpageObject = [WXWebpageObject object];
webpageObject.webpageUrl = url;
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = content;
[message setThumbImage:[UIImage imageNamed: icon]];
message.mediaObject = webpageObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO;
req.message = message;
req.scene = scene;
[WXApi sendReq:req];
}
-
可以再简单一点,分享时的图标一般都是用
app
的图标代替的。这里的icon参数可以去掉,固定写成app
的图标名称。 -
这里的
scene
参数,表示分享的地方,常用的就是对话框和朋友圈。这里,给了一个枚举值,但是没有自定义类型,所以要用int
/*! @brief 请求发送场景
*
*/
enum WXScene {
WXSceneSession = 0, /**< 聊天界面 */
WXSceneTimeline = 1, /**< 朋友圈 */
WXSceneFavorite = 2, /**< 收藏 */
WXSceneSpecifiedSession = 3, /**< 指定联系人 */
};
分享文本
这个比较简单,只要将文本内容抽出来就可以了
// 文本分享
+ (void)shareText:(NSString *)text scene:(int)scene {
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = YES;
req.text = text;
req.scene = scene;
[WXApi sendReq:req];
}
分享图片
图片名称,图标名称
// 图片分享
+ (void)shareImage:(NSString *)imageName icon:(nullable NSString *)iconName scene:(int)scene {
WXImageObject *imageObject = [WXImageObject object];
UIImage *image = [UIImage imageNamed:imageName];
imageObject.imageData = UIImageJPEGRepresentation(image, 0.7);
WXMediaMessage *message = [WXMediaMessage message];
[message setThumbImage:[UIImage imageNamed: iconName]];
message.mediaObject = imageObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO;
req.message = message;
req.scene = scene;
[WXApi sendReq:req];
}
分享音乐、视频、小程序暂时没有需求,不封装。
用到的一些数据对象
- 分享动作发起对象;或者说是消息发送对象
#pragma mark - SendMessageToWXReq
/*! @brief 第三方程序发送消息至微信终端程序的消息结构体
*
* 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息,
* 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。
* @see SendMessageToWXResp
*/
@interface SendMessageToWXReq : BaseReq
/** 发送消息的文本内容
* @note 文本长度必须大于0且小于10K
*/
@property (nonatomic, copy) NSString *text;
/** 发送消息的多媒体内容
* @see WXMediaMessage
*/
@property (nonatomic, strong) WXMediaMessage *message;
/** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
@property (nonatomic, assign) BOOL bText;
/** 发送的目标场景,可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。
* @see WXScene
*/
@property (nonatomic, assign) int scene;
/** 指定发送消息的人
* @note WXSceneSpecifiedSession时有效
*/
@property (nonatomic, copy, nullable) NSString *toUserOpenId;
@end
- 多媒体消息对象
#pragma mark - WXMediaMessage
/*! @brief 多媒体消息结构体
*
* 用于微信终端和第三方程序之间传递消息的多媒体消息内容
*/
@interface WXMediaMessage : NSObject
+ (WXMediaMessage *)message;
/** 标题
* @note 长度不能超过512字节
*/
@property (nonatomic, copy) NSString *title;
/** 描述内容
* @note 长度不能超过1K
*/
@property (nonatomic, copy) NSString *description;
/** 缩略图数据
* @note 大小不能超过32K
*/
@property (nonatomic, strong, nullable) NSData *thumbData;
/**
* @note 长度不能超过64字节
*/
@property (nonatomic, copy, nullable) NSString *mediaTagName;
/**
*
*/
@property (nonatomic, copy, nullable) NSString *messageExt;
@property (nonatomic, copy, nullable) NSString *messageAction;
/**
* 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。
*/
@property (nonatomic, strong) id mediaObject;
/*! @brief 设置消息缩略图的方法
*
* @param image 缩略图
* @note 大小不能超过64K
*/
- (void)setThumbImage:(UIImage *)image;
@end
- 网页对象
#pragma mark - WXWebpageObject
/*! @brief 多媒体消息中包含的网页数据对象
*
* 微信终端和第三方程序之间传递消息中包含的网页数据对象。
* @see WXMediaMessage
*/
@interface WXWebpageObject : NSObject
/*! @brief 返回一个WXWebpageObject对象
*
* @note 返回的WXWebpageObject对象是自动释放的
*/
+ (WXWebpageObject *)object;
/** 网页的url地址
* @note 不能为空且长度不能超过10K
*/
@property (nonatomic, copy) NSString *webpageUrl;
@end
- 图片对象
#pragma mark - WXImageObject
/*! @brief 多媒体消息中包含的图片数据对象
*
* 微信终端和第三方程序之间传递消息中包含的图片数据对象。
* @note imageData成员不能为空
* @see WXMediaMessage
*/
@interface WXImageObject : NSObject
/*! @brief 返回一个WXImageObject对象
*
* @note 返回的WXImageObject对象是自动释放的
*/
+ (WXImageObject *)object;
/** 图片真实数据内容
* @note 大小不能超过25M
*/
@property (nonatomic, strong) NSData *imageData;
@end
另外还有音乐对象,视频对象,小程序对象,这次没有封装,就不列举了。
小结
-
从数据对象的设计来看,整体还是非常清晰的。
发送对象包含多媒体消息对象;
多媒体消息对象包含具体的内容对象,比如网页,图片,音乐,视频,小程序等等。 -
这次只需要分享就可以了,所以比较简洁
-
如果要知道分享是否成功,那么要设置代理,在代理函数中取结果,就相对复杂一点了。
#pragma mark - WXApiDelegate
/*! @brief 接收并处理来自微信终端程序的事件消息
*
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
*/
@protocol WXApiDelegate <NSObject>
@optional
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
*
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
* @param req 具体请求内容,是自动释放的
*/
- (void)onReq:(BaseReq*)req;
/*! @brief 发送一个sendReq后,收到微信的回应
*
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
* @param resp具体的回应内容,是自动释放的
*/
- (void)onResp:(BaseResp*)resp;
@end
响应基类中有错误码和错误信息
#pragma mark - BaseResp
/*! @brief 该类为微信终端SDK所有响应类的基类
*
*/
@interface BaseResp : NSObject
/** 错误码 */
@property (nonatomic, assign) int errCode;
/** 错误提示字符串 */
@property (nonatomic, copy) NSString *errStr;
/** 响应类型 */
@property (nonatomic, assign) int type;
@end
- 至于自己的
APP
和微信之间要相互调用,相互传数据,那么就要设置URL Scheme
等内容。