齐桓公之ios app微信登录授权及分享对接
微信sdk的引入及相关导入你可以参考这里:齐桓公(小白)首次盲接iosapp及微信sdk及发包
这里我们仅讨论并完成wxsdk的登录授权和分享编码
首先创建类文件WechatManager.mm,和头文件WechatManager.h
怎么创建? 点击file ---- new file ---- 选择objective-cfile ----- 一步步下去
微信的授权等相关操作可分为以下几步
1、向微信注册,片段代码如下
说明:
- 注释的startLogByLevel.... 及后面checkUniversalLinkReady......是微信提供的代码调试工具方法,启动可以从日志里查看问题出在什么地方
- wxid是微信公众平台的appid,universalLink:@这里的url是registerUniversalUrl,https://域名/path 当然如果没有path则直接域名url即可
2、检查微信安装状态
+(int)doIsWXAppInstalled { BOOL isInstalled = [WXApi isWXAppInstalled]; BOOL isSepport = [WXApi isWXAppSupportApi]; if (isInstalled == YES && isSepport == YES) { return 1; } else { return 0; } }
3、登录授权
说明:这里由于是js回调过来的登录,所以用了JSBridge,
wxLoginCallBack方法是jsbridge回调给js的方法,jsbridge会在ios对接内购支付的时候详解
这里要重写wxapi.h 里的这个回调方法,登录结果返回会回调到这里
- (void)onResp:(BaseResp*)resp;
+ (void)weChatLogin { if(![WeChatManger doIsWXAppInstalled]) { [JSBridge wxLoginCallBack:-3 code:@"" tip:@"登陆失败!您未安装微信!"]; } else { SendAuthReq* req = [[SendAuthReq alloc] init]; req.scope = @"snsapi_message,snsapi_userinfo,snsapi_friend,snsapi_contact"; // @"post_timeline,sns" req.state = @"none"; [WXApi sendReq:req completion:nil]; } }
接下来是返回,这里的返回兼容处理了分享
- (void) onResp:(BaseResp*)resp { if([resp isKindOfClass:[SendAuthResp class]]) { SendAuthResp *temp = (SendAuthResp*)resp; if (temp.errCode== 0 && temp.code && temp.code.length != 0) { [JSBridge wxLoginCallBack:1 code:temp.code tip:@"登录成功"]; } else{ [JSBridge wxLoginCallBack:0 code:@"" tip:@"登录失败!"]; } } else if([resp isKindOfClass:[SendMessageToWXResp class]]) { switch (resp.errCode) { case WXSuccess: [JSBridge wxShareCallBack:1 tip:@"分享成功!"]; break; case WXErrCodeAuthDeny: [JSBridge wxShareCallBack:-1 tip:@"分享已取消!"]; break; default: [JSBridge wxShareCallBack:0 tip:@"分享失败!"]; break; } } }
3、分享
注意分享的几个参数 shareTitle 、shareType、shareDesc、shareImage等
+ (void)weChatShare:(NSString*) jsonParam { NSData* data = [jsonParam dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if (json == nil) return; NSString *shareType = json[@"shareType"]; if(![WeChatManger doIsWXAppInstalled]) { [JSBridge wxShareCallBack:-3 tip:@"未安装微信!"]; } NSString *shareTitle = json[@"shareTitle"];NSString *shareIcon = json[@"shareIcon"]; NSString *shareDesc = json[@"shareDesc"];NSString *shareLink = json[@"shareLink"]; NSString *shareImageData = json[@"shareImage"]; if( shareTitle == nil || shareTitle.length < 1 || shareIcon == nil || shareIcon.length < 1 || shareDesc == nil || shareDesc.length < 1 || shareLink == nil || shareLink.length < 1 ) { [JSBridge wxShareCallBack:-5 tip:@"分享信息缺失!"]; } else { int nRet = 0; if( [shareType isEqualToString:@"text"] )nRet = 1; else if ( [shareType isEqualToString:@"webView"] )nRet = 2; else if ( [shareType isEqualToString:@"img"] )nRet = 3; switch (nRet) { case 1: { //初始化一个WXWebpageObject对象,填写url WXWebpageObject *webpageObject = [WXWebpageObject object]; webpageObject.webpageUrl = shareLink; //用WXWebpageObject对象初始化一个WXMediaMessage对象,填写标题,描述 WXMediaMessage *message = [WXMediaMessage message]; message.title = shareTitle; message.description = shareDesc; NSDictionary *infoPlist = [[NSBundle mainBundle] infoDictionary]; NSString *icon = [[infoPlist valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"] lastObject]; UIImage * shareImage = [UIImage imageNamed:icon]; [message setThumbImage:shareImage]; message.mediaObject = webpageObject; SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = WXSceneSession; [WXApi sendReq:req completion:nil]; break; } case 2: { break; } case 3: { //UIImage *image = [[ViewController GetIOSViewController] getScreenShot]; NSArray *array = [shareImageData componentsSeparatedByString:@","]; NSData *ImageData = [[NSData alloc] initWithBase64EncodedString:array[1] options:NSDataBase64DecodingIgnoreUnknownCharacters]; UIImage *image = [UIImage imageWithData:ImageData]; // 下面就是组装要分享到微信的内容 WXMediaMessage *message=[WXMediaMessage message]; [message setThumbImage:image]; WXImageObject *imageObject=[WXImageObject object]; imageObject.imageData=UIImagePNGRepresentation(image); message.mediaObject=imageObject; SendMessageToWXReq *req=[[SendMessageToWXReq alloc]init]; req.bText=NO; req.message=message; req.scene=WXSceneSession; [WXApi sendReq:req completion:nil]; break; } default:{ [JSBridge wxShareCallBack:-6 tip:@"不支持的分享类型!"]; break; } } } }
至此,微信的ios客户端对接完成,接下来就是掉登录分享的H5这边,H5这边通过jsbridge直接掉wxlogin方法,在回调方法里处理相关的逻辑,这里和web对接微信没啥区别,不过一个是引入js文件,一个是掉ios oc方法而已,代码片段如下
static doLogin() { Native.callWithBack(function (msg) { log("doLogin WXdoAuth code is :", msg["code"]); LoginHelperWXNative.onGetCode(msg["code"]); this.tag = 0; }, "wxLogin",''); this.tag = 1; }
下面是完整的WechatManager.mm和头文件WechatManager.h 内容
WechatManager.h
#import <UIKit/UIKit.h> #import <StoreKit/StoreKit.h> #import "WXApi.h" @interface WeChatManger:NSObject<WXApiDelegate> +(int)doIsWXAppInstalled; +(instancetype) sharedManager; +(void)weChatLogin; +(void)weChatShare:(NSString*) jsonParam; -(void)initSDK:(NSString*) wxid; @property (nonatomic, nonatomic,retain) NSString *wxId; @end
WechatManager.mm
#import "WeChatManger.h" #import "WXApi.h" #import "JSBridge.h" #include "SDKManager.h" @implementation WeChatManger; - (void) onReq:(BaseReq *)req { //获取开放标签传递的extinfo数据逻辑 if ([req isKindOfClass:[LaunchFromWXReq class]]) { LaunchFromWXReq *launchReq = (LaunchFromWXReq *)req; WXMediaMessage *msg = launchReq.message; NSString *extinfo = msg.messageExt; [[SDKManager getInstance] setInfoFromWxOnLaunch: extinfo]; } } - (void) onResp:(BaseResp*)resp { if([resp isKindOfClass:[SendAuthResp class]]) { SendAuthResp *temp = (SendAuthResp*)resp; if (temp.errCode== 0 && temp.code && temp.code.length != 0) { [JSBridge wxLoginCallBack:1 code:temp.code tip:@"登录成功"]; } else{ [JSBridge wxLoginCallBack:0 code:@"" tip:@"登录失败!"]; } } else if([resp isKindOfClass:[SendMessageToWXResp class]]) { switch (resp.errCode) { case WXSuccess: [JSBridge wxShareCallBack:1 tip:@"分享成功!"]; break; case WXErrCodeAuthDeny: [JSBridge wxShareCallBack:-1 tip:@"分享已取消!"]; break; default: [JSBridge wxShareCallBack:0 tip:@"分享失败!"]; break; } } } + (void)weChatLogin { if(![WeChatManger doIsWXAppInstalled]) { [JSBridge wxLoginCallBack:-3 code:@"" tip:@"登陆失败!您未安装微信!"]; } else { SendAuthReq* req = [[SendAuthReq alloc] init]; req.scope = @"snsapi_message,snsapi_userinfo,snsapi_friend,snsapi_contact"; // @"post_timeline,sns" req.state = @"none"; [WXApi sendReq:req completion:nil]; } } + (void)weChatShare:(NSString*) jsonParam { NSData* data = [jsonParam dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if (json == nil) return; NSString *shareType = json[@"shareType"]; if(![WeChatManger doIsWXAppInstalled]) { [JSBridge wxShareCallBack:-3 tip:@"未安装微信!"]; } NSString *shareTitle = json[@"shareTitle"];NSString *shareIcon = json[@"shareIcon"]; NSString *shareDesc = json[@"shareDesc"];NSString *shareLink = json[@"shareLink"]; NSString *shareImageData = json[@"shareImage"]; if( shareTitle == nil || shareTitle.length < 1 || shareIcon == nil || shareIcon.length < 1 || shareDesc == nil || shareDesc.length < 1 || shareLink == nil || shareLink.length < 1 ) { [JSBridge wxShareCallBack:-5 tip:@"分享信息缺失!"]; } else { int nRet = 0; if( [shareType isEqualToString:@"text"] )nRet = 1; else if ( [shareType isEqualToString:@"webView"] )nRet = 2; else if ( [shareType isEqualToString:@"img"] )nRet = 3; switch (nRet) { case 1: { //初始化一个WXWebpageObject对象,填写url WXWebpageObject *webpageObject = [WXWebpageObject object]; webpageObject.webpageUrl = shareLink; //用WXWebpageObject对象初始化一个WXMediaMessage对象,填写标题,描述 WXMediaMessage *message = [WXMediaMessage message]; message.title = shareTitle; message.description = shareDesc; NSDictionary *infoPlist = [[NSBundle mainBundle] infoDictionary]; NSString *icon = [[infoPlist valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"] lastObject]; UIImage * shareImage = [UIImage imageNamed:icon]; [message setThumbImage:shareImage]; message.mediaObject = webpageObject; SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = WXSceneSession; [WXApi sendReq:req completion:nil]; break; } case 2: { break; } case 3: { //UIImage *image = [[ViewController GetIOSViewController] getScreenShot]; NSArray *array = [shareImageData componentsSeparatedByString:@","]; NSData *ImageData = [[NSData alloc] initWithBase64EncodedString:array[1] options:NSDataBase64DecodingIgnoreUnknownCharacters]; UIImage *image = [UIImage imageWithData:ImageData]; // 下面就是组装要分享到微信的内容 WXMediaMessage *message=[WXMediaMessage message]; [message setThumbImage:image]; WXImageObject *imageObject=[WXImageObject object]; imageObject.imageData=UIImagePNGRepresentation(image); message.mediaObject=imageObject; SendMessageToWXReq *req=[[SendMessageToWXReq alloc]init]; req.bText=NO; req.message=message; req.scene=WXSceneSession; [WXApi sendReq:req completion:nil]; break; } default:{ [JSBridge wxShareCallBack:-6 tip:@"不支持的分享类型!"]; break; } } } } +(int)doIsWXAppInstalled { BOOL isInstalled = [WXApi isWXAppInstalled]; BOOL isSepport = [WXApi isWXAppSupportApi]; if (isInstalled == YES && isSepport == YES) { return 1; } else { return 0; } } -(void) initSDK:(NSString*) wxid{ // [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) { // NSLog(@"WeChatSDK: %@", log); // }]; //向微信注册 _wxId = '乱写的ertesgasdgasoidjga342582393245325'; [WXApi registerApp:_wxId universalLink:@"https://cccccccccccc/byapp/"]; // [WXApi checkUniversalLinkReady:^(WXULCheckStep step, WXCheckULStepResult* result) { // NSLog(@"dddddddd---%@, %u, %@, %@", @(step), result.success, result.errorInfo, result.suggestion); // }]; } +(instancetype)sharedManager { static dispatch_once_t onceToken; static WeChatManger *instance; dispatch_once(&onceToken, ^{ instance = [[WeChatManger alloc] init]; }); return instance; } @end
微信sdk的ios对接一版情况下从github上可以搬过来用,都是对接相关的部分,如果H5对接过或者公众号小程序对接过,对流程很熟悉的话,基本就没什么问题了。
天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤....对齐桓公来说确实如此,微信sdk对接遇到的问题总结如下:
1、sdk库的导入相当棘手,建议参照官网一步一步来
2、登录授权的universal url配置一定要在访问【域名+apple-app-site-association】一定要能下载这个文件,否则配置失败,微信授权会报----universal Link校验不通过 的错误
3、分享的时候分享连接一定要提供正确,这里会报一些分享的错误,没有关系有报错就好解决
最后说一句:砖石之所以能成砖石是因为他经过了千百万年的磨练 一切事物皆如此 倘不经历练 何以知其真 ?何以享其乐?以此而已!