iOS第三方登錄及分享入門指南 —— QQ(一)

導語:

第三方登錄和分享是現在App的「主流功能」,不管友盟,還是ShareSDK,都有很好的集成文檔,Please feel free to check!至于寫這篇指南的初衷是剛好公司最近做Standard Module,也剛好需要集成這一塊,還得做成友盟那樣以供使用。(心累,迫于老大的淫威之下

QQ SDK官方文檔

實現QQ登錄

一、準備工作

  1. 騰訊開放平臺,注冊成為開發者。
  2. 創建應用,申請你的appidappkey

!!!Ps:在準備工作的時候,可能會遇到一個坑:QQ互聯開放平臺騰訊開放平臺是相互獨立的,所以 若已在QQ互聯創建過應用,可在創建應用時選擇關聯QQ互聯,輸入在QQ互聯創建的網頁應用APPID、APPKEY即可完成關聯。(兩個平臺做一樣的事,鵝廠真心錢多

創建應用.png
appid和appkey的用途
  • appid:應用的唯一標識。在OAuth2.0認證過程中,appid的值即為oauth_consumer_key的值。
  • appkey:appid對應的密鑰,訪問用戶資源時用來驗證應用的合法性。在OAuth2.0認證過程中,appkey的值即為oauth_consumer_secret的值。

二、集成SDK

下載好完整包,如圖導入工程需要的文件。

14932765373824.jpg
  • TencentOpenAPI.framework打包了iOS SDK的頭文件定義和具體實現
  • TencentOpenApi_iOS_Bundle.bundle 打包了iOS SDK需要的資源文件

三、配置工程

1. 添加SDK依賴的系統庫文件

Security.framework
SystemConfiguration.framework
CoreTelephony.framework
CoreGraphics.Framework
libiconv.tbd
libsqlite3.tbd
libstdc++.tbd
libz.tbd

2. 修改必要的工程配置屬性

在工程配置中的Build Settings一欄中找到Linking配置區,給Other Linker Flags配置項添加屬性值-fobjc-arc

配置屬性.jpg
3. 修改Info.plist文件

在XCode中,選中TARGETS一欄,在Info標簽欄中找到URL Types,添加一條新的URL scheme。(必須填寫

Identifier: tencentopenapi
URL Schemes: tencent + "appid"

想要實現應用間跳轉,而不是打開一個登陸網頁,在Info.plist中添加LSApplicationQueriesSchemes

<key>LSApplicationQueriesSchemes</key>
<array>
<string>mqqapi</string>
<string>mqq</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqconnect</string>
<string>mqqopensdkdataline</string>
<string>mqqopensdkgrouptribeshare</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkapi</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqzoneopensdk</string>
<string>mqqopensdkapiV3</string>
<string>mqqopensdkapiV3</string>
<string>mqzone</string>
<string>mqzonev2</string>
<string>mqzoneshare</string>
<string>wtloginqzone</string>
<string>mqzonewx</string>
<string>mqzoneopensdkapiV2</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapi</string>
<string>mqzoneopensdk</string>
</array>

四、代碼實現

1.AppDelegate

在AppDelegate中添加頭文件,并重寫AppDelegate的handleOpenURLopenURL方法

  • iOS9之前,分別重寫handleOpenURL && openURL方法

      //handleOpenURL(ios10已棄用)
      NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:")
      - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
          [TencentOAuth HandleOpenURL:url];
          return YES;
      }
         
      //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{
          [TencentOAuth HandleOpenURL:url];
          return YES;
      }
    
  • iOS9之后,handleOpenURL && openURL 合成為同一個方法

      //handleOpenURL && openURL
      - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
          [TencentOAuth HandleOpenURL:url];
          return YES;
      }
    
2.登錄控制器實現對應的代理事件

在LoginViewController添加對應的頭文件,添加QQ Login點擊事件,實現TencentSessionDelegate的對應delegate事件。

#import "LoginViewController.h"
#import <TencentOpenAPI/TencentOAuth.h>
 
@interface LoginViewController ()<TencentSessionDelegate>
@property (nonatomic, strong) TencentOAuth* tencentOAuth;
@end

@implementation LoginViewController

- (void)loginBtnClicked{
    self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:@"你申請的appID" andDelegate:self];

    //在這個數組里,可以添加你想要用戶授權的信息的相關字段
    //注意,若是授權太多信息, 用戶可能會拒絕授權
    NSArray *permissions = [NSArray arrayWithObjects:
                            @"get_user_info",
                            @"get_simple_userinfo",
                            @"add_t",
                            nil];
    //授權類型
    [self.tencentOAuth setAuthShareType:AuthShareType_QQ];
    //調用SDK登錄
    [self.tencentOAuth authorize:permissions inSafari:false];
}

- (void)tencentDidNotNetWork{
    NSLog(@"網絡連接失敗");
}

- (void)tencentDidLogin{
    if (self.tencentOAuth.accessToken && 0 != [self.tencentOAuth.accessToken length]){
        //accessToken有效期3個月,想要獲取用戶信息,必須調用getUserInfo
        NSLog(@"記錄登錄用戶的OpenID、Token以及過期時間");
        [self.tencentOAuth getUserInfo];
    }else{
        NSLog(@"登錄不成功 沒有獲取accesstoken");
    }
}

- (void)tencentDidNotLogin:(BOOL)cancelled{
    if (cancelled){
        NSLog(@"用戶取消登錄");
    }else{
        NSLog(@"登錄失敗");
    }
}
3.獲取用戶信息

當DidLogin調用getUserInfo,會有此回調返回userInfo

- (void)getUserInfoResponse:(APIResponse *)response{
 if (response  && response.retCode == URLREQUEST_SUCCEED) {
     NSDictionary* userInfo = [response jsonResponse];
     NSLog(@"%@",userInfo);
 }else{
     NSLog(@"QQ auth fail ,getUserInfoResponse:%d", response.detailRetCode);
 }
}
4.登錄篇注意事項
  • ?當未調起原生客戶端授權,只彈出網頁,檢查URL scheme設置 && 是否添加LSApplicationQueriesSchemesInfo.plist

  • 當Xcode提示“未選擇授權類型”,可添加:

      [self.tencentOAuth setAuthShareType:AuthShareType_QQ];
    

分割線,接下來講講QQ分享

實現QQ分享

步驟同上一、二、三

代碼實現

1.在AppDelegate中初始化OAuth
@interface AppDelegate ()<QQApiInterfaceDelegate>
@property (nonatomic, strong) TencentOAuth* tencentOAuth;
@end

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    // 根據自己的AppID初始化OAuth
    self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:@"QQAppID" andDelegate:nil];
    return YES;
}
2.在AppDelegate中實現回調事件

此回調事件,需要在AppDelegate里添加頭文件<TencentOpenAPI/QQApiInterface.h>,重寫handleOpenURL && openURL方法

  • 添加頭文件

      #import <TencentOpenAPI/QQApiInterface.h>
    
  • 重寫handleOpenURL方法

      //iOS9之前,分別重寫`handleOpenURL && openURL`方法
      //handleOpenURL(ios10已棄用)
      NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:")
      - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
          if ([url.scheme isEqualToString:[NSString stringWithFormat:@"tencent%@",QQAppID]]) {
              return [QQApiInterface handleOpenURL:url delegate:self];
      }
      else{
              return YES;
          }
      }
    
      //iOS9之后,`handleOpenURL && openURL` 合成為同一個方法
      //handleOpenURL && openURL
      - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
          if ([url.scheme isEqualToString:[NSString stringWithFormat:@"tencent%@",QQAppID]]) {
              return [QQApiInterface handleOpenURL:url delegate:self];
      }
      else{
              return YES;
          }
      }
    
  • 處理回調事件

      @interface AppDelegate ()<QQApiInterfaceDelegate>
    
      - (void)onReq:(QQBaseReq *)req{
            NSLog(@"處理來至QQ的請求");
        }
         
      - (void)onResp:(QQBaseResp *)resp{
          NSLog(@"處理來至QQ的響應");
          NSLog(@"response")
          switch (resp.type)
          {
              case ESENDMESSAGETOQQRESPTYPE:
              {
                  SendMessageToQQResp* sendResp = (SendMessageToQQResp*)resp;
                  if ([sendResp.result isEqualToString:@"0"]) {
                      UIAlertController* vc = [UIAlertController alertControllerWithTitle:@"成功" message:@"QQ分享成功" preferredStyle:UIAlertControllerStyleAlert];
                      [vc addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                      }]];
                      [self.window.rootViewController presentViewController:vc animated:YES completion:nil];
                  }
                  else {
                      UIAlertController* vc = [UIAlertController alertControllerWithTitle:@"失敗" message:@"QQ分享失敗" preferredStyle:UIAlertControllerStyleAlert];
                      [vc addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                         }]];
                      [self.window.rootViewController presentViewController:vc animated:YES completion:nil];
                  }
                  break;
              }
              default:
              {
                  break;
              }
          }
      }
         
      - (void)isOnlineResponse:(NSDictionary *)response{
          NSLog(@"處理QQ在線狀態的回調");
          NSLog(@"response : %@",response);
      }
    
3.在ShareViewController中導入對應的頭文件
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/TencentMessageObject.h>
#import <TencentOpenAPI/TencentApiInterface.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/QQApiInterfaceObject.h>
4.在ShareViewController實現分享事件示例代碼
  • 文本

      - (void)shareText {
    
          if (![TencentOAuth iphoneQQInstalled]) {
              UIAlertController* vc = [UIAlertController alertControllerWithTitle:@"你還沒有安裝QQ客戶端" message:nil preferredStyle:UIAlertControllerStyleAlert];
              [vc addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
              }]];
              [self presentViewController:vc animated:YES completion:nil];
          }
          else{
              QQApiTextObject* object = [QQApiTextObject objectWithText:@"分享的內容"];
              [object setShareDestType:ShareDestTypeQQ];
              SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:object];
      
              QQApiSendResultCode code = [QQApiInterface sendReq:req];
              NSLog(@"result code : %d",code);
          }
      }
    
  • 圖片

      - (void)shareImage {
      
          if (![TencentOAuth iphoneQQInstalled]) {
          UIAlertController* vc = [UIAlertController alertControllerWithTitle:@"你還沒有安裝QQ客戶端" message:nil preferredStyle:UIAlertControllerStyleAlert];
          [vc addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
          }]];
          [self presentViewController:vc animated:YES completion:nil];
          }
          else{
              NSString* filePath = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
              NSData* imageData = [NSData dataWithContentsOfFile:filePath];
              QQApiImageObject* obj = [QQApiImageObject objectWithData:imageData previewImageData:imageData title:@"title" description:@"github貓"];
              [obj setShareDestType:ShareDestTypeQQ];
              SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:obj];
              QQApiSendResultCode code = [QQApiInterface sendReq:req];
              NSLog(@"result code : %d",code);
          }
      }
    
  • 新聞

      - (void)shareNews {
    
          if (![TencentOAuth iphoneQQInstalled]) {
              UIAlertController* vc = [UIAlertController alertControllerWithTitle:@"你還沒有安裝QQ客戶端" message:nil preferredStyle:UIAlertControllerStyleAlert];
              [vc addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
              }]];
              [self presentViewController:vc animated:YES completion:nil];
          }
          else{
              //分享跳轉URL,注意要經過UTF8處理
              NSString *url = [@"http://xxx.xxx.xxx/" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
              //分享圖預覽圖URL地址
              NSString *previewImageUrl = @"preImageUrl.png";
              QQApiNewsObject *newsObj = [QQApiNewsObject objectWithURL :[NSURL URLWithString:url]
                                                                   title: @"title"
                                                            description :@"description"
                                                         previewImageURL:[NSURL URLWithString:previewImageUrl]];
              SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
      
              //將內容分享到qq
              //QQApiSendResultCode sent = [QQApiInterface sendReq:req];
              //將內容分享到qzone
              QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
          }
      }
    
  • 分享類型:

分享消息類型 QQ好友 QQ空間 web QQ好友 web QQ空間
QQApiTextObject ?? ? ? ?
QQApiImageObject ?? ? ? ?
QQApiNewsObject ?? ?? ?? ??
QQApiAudioObject ?? ?? ?? ??
QQApiVideoObject ?? ?? ?? ??
5.分享篇注意事項
  • 分享的回調無法執行,請注意實現<QQApiInterfaceDelegate>,即

      [QQApiInterface handleOpenURL:url delegate:self(代理對象)];
    
  • 當Xcode打印“result code 為 -2”時(未知的分享類型),請注意實現setShareDestType方法,即

      QQApiTextObject* object = [QQApiTextObject objectWithText:@"分享的內容"];
      [object setShareDestType:ShareDestTypeQQ];
    

結束語

我在使用原生集成時,遇到的這些坑都由于Tencent的文檔太久沒更新導致花了一段時間。最后仔細的查看SDK接口才發現解決方式,希望能夠給看到這篇文章的人提供到一點幫助。在接下來一段時間,還會繼續寫幾篇關于 微信、微博、Facebook等等的SDK集成指南。還在研究中,共勉啦。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內容