1. 程式人生 > 其它 >齊桓公之ios app微信登入授權及分享對接

齊桓公之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、分享的時候分享連線一定要提供正確,這裡會報一些分享的錯誤,沒有關係有報錯就好解決

最後說一句:磚石之所以能成磚石是因為他經過了千百萬年的磨練   一切事物皆如此   倘不經歷練  何以知其真 ?何以享其樂?以此而已!