导语:
完成原生QQ的SDK集成后,接下来就是微信的了,这两家的SDK我怀疑是同个人写的,如此相像,虽不难,但还是有一些坑需要注意。
微信 SDK官方文档
实现微信登录
一、准备工作
- 在微信·开放平台,注册成为开发者。
- 创建应用,申请你的AppID和AppSecret。
二、集成SDK
下载好完整包,如图导入工程需要的文件。
微信SDK.png三、配置工程
1. 添加SDK依赖的系统库文件
SystemConfiguration.framework
Security.framework
CFNetwork.framework
CoreTelephony.framework
libsqlite3.0.tbd
libstdc++.tbd
libz.tbd
libc++.tbd
2. 修改必要的工程配置属性
在工程配置中的Build Settings
一栏中找到Linking
配置区,给Other Linker Flags
配置项添加属性值-Objc
、-all_load
3. 修改Info.plist文件
在XCode中,选中TARGETS
一栏,在Info
标签栏中找到URL Types
,添加一条新的URL scheme
。(必须填写
Identifier: wexin
URL Schemes: wx + "appid"
想要实现应用间跳转,而不是打开一个登陆网页,在Info.plist
中添加LSApplicationQueriesSchemes
:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>wechat</string>
<string>weixin</string>
</array>
四、代码实现
1.AppDelegate
在AppDelegate中添加头文件,并重写AppDelegate的handleOpenURL
和openURL
方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"appid"];
return YES;
}
-
iOS9之前,分别重写
handleOpenURL && openURL
方法//handleOpenURL(ios10已弃用) NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:") - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{ return [WXApi handleOpenURL:url delegate:self]; } //openURL(iOS10已弃用) NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:") - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ return [WXApi handleOpenURL:url delegate:self]; }
-
iOS9之后,
handleOpenURL && openURL
合成为同一个方法//handleOpenURL && openURL - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{ return [WXApi handleOpenURL:url delegate:self]; }
2.实现代理方法
- (void)onReq:(BaseReq *)req{
NSLog(@"wx onReq");
}
- (void)onResp:(BaseResp *)resp{
NSLog(@"wx onResp");
//登录 分享 都走同一个回调
if ([resp isKindOfClass:[SendAuthResp class]]) {
SendAuthResp* authResp = (SendAuthResp *)resp;
[self loginResponse:authResp];
}
}
- (void)loginResponse:(SendAuthResp*)response{
switch (response.errCode) {
case WXSuccess:{
[self getUserToken:response.code];
}
break;
case WXErrCodeCommon:
break;
case WXErrCodeUserCancel:
break;
case WXErrCodeSentFail:
break;
case WXErrCodeAuthDeny:
break;
case WXErrCodeUnsupport:
break;
}
}
3.请求code,通过login点击事件
-(void)sendAuthRequest{
//构造SendAuthReq结构体
SendAuthReq* req =[[[SendAuthReq alloc ] init ] autorelease ];
req.scope = @"snsapi_userinfo" ;
req.state = @"123" ;
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApi sendReq:req];
}
4.通过code获取access_token
- (void)getUserToken:(NSString*)code{
NSString* url = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",WXAppID,WXSecret,code];
//获取第一步的code后,请求以下链接获取access_token:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
//将获取到的userToken && openID 继续网络请求获取userInfo
[self getUserInfo:response[@"access_token"] openID:response[@"openid"]];
}
参数 | 说明 |
---|---|
access_token | 接口调用凭证(有效期30天) |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
unionid | 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段 |
5.刷新access_token有效期
获取第一步的code后,请求以下链接进行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
6.根据获取到的userToken && openID 继续网络请求获取userInfo
- (void)getUserInfo:(NSString*)token openID:(NSString*)openID{
NSString* url = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",token,openID];
//网络请求 返回response包含UserInfo
}
实现微信分享
步骤同上一、二、三
微信 SDK官方文档
代码实现
1.AppDelegate
设置分享支持类型
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"appid"];
UInt64 typeFlag = MMAPP_SUPPORT_TEXT | MMAPP_SUPPORT_PICTURE |
MMAPP_SUPPORT_LOCATION | MMAPP_SUPPORT_VIDEO |
MMAPP_SUPPORT_AUDIO | MMAPP_SUPPORT_WEBPAGE |
MMAPP_SUPPORT_DOC | MMAPP_SUPPORT_DOCX |
MMAPP_SUPPORT_PPT | MMAPP_SUPPORT_PPTX |
MMAPP_SUPPORT_XLS | MMAPP_SUPPORT_XLSX |
MMAPP_SUPPORT_PDF;
[WXApi registerAppSupportContentFlag:typeFlag];
return YES;
}
2.实现代理方法
- (void)onReq:(BaseReq *)req{
NSLog(@"wx onReq");
}
- (void)onResp:(BaseResp *)resp{
NSLog(@"wx onResp");
//登录 分享 都走同一个回调
if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
SendMessageToWXResp* messageResp = (SendMessageToWXResp *)resp;
[self shareResponse:messageResp];
}
}
- (void)shareResponse:(SendAuthResp*)response{
switch (response.errCode) {
case WXSuccess:{
//分享成功
}
break;
case WXErrCodeCommon:
break;
case WXErrCodeUserCancel:
break;
case WXErrCodeSentFail:
break;
case WXErrCodeAuthDeny:
break;
case WXErrCodeUnsupport:
break;
}
}
3.分享示例
WXSceneSession
发送到聊天界面
WXSceneTimeline
发送到朋友圈
WXSceneFavorite
添加到微信收藏
-
文字
// 第三方程序发送消息至微信终端程序的消息结构体 SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.text = @"分享的内容"; // 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 req.bText = YES; req.scene = WXSceneTimeline; [WXApi sendReq:req];
-
图片
WXMediaMessage *message = [WXMediaMessage message]; [message setThumbImage:[UIImage imageNamed:@"图片.png"]]; WXImageObject *imageObject = [WXImageObject object]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"res1" ofType:@"jpg"]; // 图片真实数据内容 imageObject.imageData = [NSData dataWithContentsOfFile:filePath]; message.mediaObject = imageObject; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = WXSceneTimeline;// 分享到朋友圈 [WXApi sendReq:req];
-
音乐
WXMediaMessage *message = [WXMediaMessage message]; message.title = @"音乐标题"; message.description = @"音乐描述"; [message setThumbImage:[UIImage imageNamed:@"缩略图.jpg"]]; WXMusicObject *musicObject = [WXMusicObject object]; musicObject.musicUrl = @"音乐url"; musicObject.musicLowBandDataUrl = @"音乐lowband数据url地址"; musicObject.musicDataUrl = @"音乐数据url"; musicObject.musicLowBandDataUrl = @"音乐lowband数据url地址"; message.mediaObject = musicObject; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = WXSceneTimeline; [WXApi sendReq:req];
-
网页
WXMediaMessage *message = [WXMediaMessage message]; message.title = @"标题"; message.description = @"描述"; [message setThumbImage:[UIImage imageNamed:@"res2.png"]]; WXWebpageObject *webpageObject = [WXWebpageObject object]; webpageObject.webpageUrl = @"https://opne.weixin.qq.com"; message.mediaObject = webpageObject; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = WXSceneTimeline; [WXApi sendReq:req];
结束语
-
如果同时集成QQ SDK和微信 SDK,需要注意两者的回调方法会冲突。解决办法可以分别创建对应的管理类来管理代理方法。
-(void)onReq:(BaseReq *)req; -(void)onResp:(BaseResp *)resp;
-
微信登录和分享的回调方法为同一个
-
纯文字分享可以跳转,其他类型无法跳转时,请注意缩略图(thumbImage)大小是否超过32kb (重要
网友评论