iOS 集成微信、QQ API集成封装

iOS 集成微信、QQ 、新浪微博API进行分享、登录、支付文档
目录
一、 集成微信平台API 2
二、 SDK下载(微信平台API) 2
2.1微信官方的SDK下载地址如下: 2
2.2接入流程文档地址如下: 2
三、 手动集成的话需要添加依赖库 2
四、 工程配置属性(微信平台API) 3
五、 设置 URL Scheme(微信平台API) 3
六、 添加URL Schemes 白名单(微信平台API) 4
七、 签名安全问题(这里是客户端来签名的) 4
八、 Cocoapods 集成微信平台API( 自动集成方式) 5
九、 可以愉快的写代码了(微信平台API) 5
9.1.网络库的二次封装(基于AFNetworking网络第三方的封装) 5
9.2 BHTWeixinSDK 工具类基于WechatOpenSDK API框架的二次封装 19
十、 设置(微信平台API) 35
10.1在AppDelegate.m 文件中初始化 35
10.2openURL方法中设置回调 35
十一、 调用(微信平台API) 36
11.1调用之前需要判断是否安装了微信 36
11.2.如果上述方法返回YES,直接调用接口就好,个人喜欢类方法,调用方便,可根据喜好自行修改.当然,前提是你已经取得了微信支付和登录分享的授权 36
十二、 集成QQ平台API 37
十三、 SDK下载(QQ平台API) 37
十四、 添加依赖库(手动集成)-QQ平台API 37
十五、 工程配置属性(QQ 平台的API) 38
十六、 设置 URL Scheme (QQ 平台API) 38
十七、 添加URL Schemes 白名单(QQ 平台的API) 39
十八、 Cocoapods 集成QQ平台的API(自动集成) 40
十九、 可以写代码了(QQ平台的API) 41
二十、 设置(QQ平台的API) 47
20.1在AppDelegate.m文件中初始化 47
20.2 openURL方法中设置回调 47
二十一、 调用(QQ平台的API) 48
22.1 分享是方法,直接调用就好 48
22.2 登录需要先实列化再调用一下接口 48

一、集成微信平台API
「强制」iOS 接入微信SDK封装的工具类BHTWeixinSDK(微信登录,微信好友和朋友圈分享,微信支付(客户端签名))
二、SDK下载(微信平台API)
2.1微信官方的SDK下载地址如下:
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html?action=dir_list
2.2接入流程文档地址如下:
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html?action=dir_list
三、手动集成的话需要添加依赖库
:将SDK文件中包含的 libWeChatSDK.a,WXApi.h,WXApiObject.h 三个文件添加到你所建的工程中,在Build Phases下面的Link Binary With Libraries项中添加下面所需的依赖库:

四、工程配置属性(微信平台API)
:在你的工程文件中选择Build Setting,在"Other Linker Flags"中加入"-Objc -all_load"
五、设置 URL Scheme(微信平台API)
:修改 info.plist 文件 URL types 项中后面的URL Schemes内容为"wx+ appid",例如:wx1234567890 (我这里设置了支付宝,qq,微信,微博,只用到微信的话,就添加微信的就ok)

六、添加URL Schemes 白名单(微信平台API)
:在“Info.plist”中增加一个LSApplicationQueriesSchemes值,设置为array, 添加微信需要的几个
? ? item:
? ? wechat
? ? weixin
七、签名安全问题(这里是客户端来签名的)

八、Cocoapods 集成微信平台API( 自动集成方式)

?? ? # 微信支付 微信分享 微信登录
?? ? pod ‘WechatOpenSDK‘

? ? 1.切换到项目工程路径下:执行pod install 命令
九、可以愉快的写代码了(微信平台API)
:创建了一个继承于NSObject的 BHTWeixinSDK工具类(涉及微信登录,微信好友和朋友圈分享,微信支付),而且我在其中封装了一下微信支付时向后台请求prepayId的方法和处理回调结果用到的方法.
? ? ps:这个类中有网络请求,BHTNetworkManager是我自己对AFNetworking3.0的二次封装,感兴趣的可以看一看,不感兴趣的同学可以用AFN或者自己的网络框架.
9.1.网络库的二次封装(基于AFNetworking网络第三方的封装)
:.h 文件声明
//? BHTNetworkManager.h
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/29.
// 网络管理工具类

/*
网络的库的二次封装(基于AFNetworking网络第三方库的封装)
/

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

#pragma mark - block --声明回调数据
typedef void (^BTHrequestUploadProgressBlock)(NSProgress downloadProgress);
typedef void (^BTHrequestSuccessBlock)(NSURLSessionDataTask
_Nonnull task, id _Nullable JSONDict);
typedef void (^BTHrequestFailedBlock)(NSURLSessionDataTask _Nullable task, NSError _Nonnull error);
typedef void (^BTHrequestFormDataBlock)(id <AFMultipartFormData> formData);
typedef void (^BTHrequestCompletionHandlerBlock)(NSURLResponse response, NSURL filePath, NSError error);
typedef NSURL
_Nullable(^BTHrequestDestinationBlock)(NSURL targetPath, NSURLResponse response);

@interface BHTNetworkManager : AFHTTPSessionManager
#pragma mark - 实例化对象
/*
实例化
/

  • (instancetype)shareInstance;

#pragma mark - GET 请求方式
/*
?
? 发送get请求
?
?
? @param url? ? ? ? ? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? ? ? ? ? 请求参数
?
? @param header ? ? ? ? ? ? ? ? ? 请求头Header
?? @param downloadProgressBlock? ? 网络请求进度
?
? @param success? ? ? ? ? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param failure? ? ? ? ? ? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDataTask )GET:(NSString )url
    ?? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? httpHeaderKeyValues:(NSDictionary *)header
    ?? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

  • (NSURLSessionDataTask )GET:(NSString )url
    ?? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

#pragma mark - POST 请求方式
/*
?
? 发送post请求
?
?
? @param url? ? ? ? ? 请求路径
?? @param params ? 请求参数
?
? @param header ? ? ? 请求头Header
?? @param success? ? ? 请求成功后的回调,参数为id类型
?
? @param failure? ? ? 请求失败后的回调
?*/

  • (NSURLSessionDataTask )POST:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? httpHeaderKeyValues:(NSDictionary *)header
    ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

  • (NSURLSessionDataTask )POST:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

#pragma mark -? 上传文件

/*
?
? 上传文件
?
?
? @param url? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? 请求参数
?
? @param header ? ? ? ? ? 请求头Header
?? @param formDataBlock? ? 上传文件的信息
?
? @param success? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param failure? ? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDataTask )upload:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? httpHeaderKeyValues:(NSDictionary *)header
    ?? ? ? constructingBodyWithBlock:(BTHrequestFormDataBlock)formDataBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

  • (NSURLSessionDataTask )upload:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? constructingBodyWithBlock:(BTHrequestFormDataBlock)formDataBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure;

#pragma mark -? 下载文件(图片)
/*
?
? 下载
?
?
? @param url? ? ? ? ? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? ? ? ? ? 请求参数
?
? @param header ? ? ? ? ? ? ? ? ? 请求头Header
?? @param downloadProgressBlock? ? 下载进度
?
? @param destination? ? ? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param completionHandler? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDownloadTask )download:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? ? ? ? httpHeaderKeyValues:(NSDictionary *)header
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? ? destination:(BTHrequestDestinationBlock)destination
    ?? ? ? ? ? ? ? ? ? ? completionHandler:(BTHrequestCompletionHandlerBlock)completionHandler;

  • (NSURLSessionDownloadTask )download:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? ? destination:(BTHrequestDestinationBlock)destination
    ?? ? ? ? ? ? ? ? ? ? completionHandler:(BTHrequestCompletionHandlerBlock)completionHandler;

@end

NS_ASSUME_NONNULL_END
:.m 文件实现
//? BHTNetworkManager.m
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/29.
//

#import "BHTNetworkManager.h"

@implementation BHTNetworkManager

#pragma mark - 实例化对象
/*
实例化
/
static BHTNetworkManager *_instance = nil;

  • (instancetype)shareInstance{
    ? ? static dispatch_once_t onceToken;
    ? ? dispatch_once(&onceToken, ^{
    ?? ? ? ? ? _instance = [self manager];
    ? ? ? ? // 请求时,所支持的格式要求
    ?? ? ? ? ? _instance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", nil];
    ?? ? ? ? ? // 设置所有接口公用的header
    ?? ? ? ? ? NSDictionary *header = @{
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"TOKEN": @"XXXXXXXXXXX",
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"USERID": @"XXXXXXXXXXX"
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };
    ?? ? ? ? ? [_instance setHTTPHeaderKeyValues:header];
    ?? ? ? });
    ?? ? ? return _instance;
    ?? ?
    }

// 设置请求头

  • (void)setHTTPHeaderKeyValues:(NSDictionary )header {
    ? ? if (header) {
    ? ? ? ? [header enumerateKeysAndObjectsUsingBlock:^(id? _Nonnull key, id? _Nonnull obj, BOOL
    _Nonnull stop) {
    ? ? ? ? ? ? [self.requestSerializer setValue:obj forHTTPHeaderField:key];
    ? ? ? ? }];
    ? ? }
    }

#pragma mark - GET 请求方式

/*
?
? 发送get请求
?
?
? @param url? ? ? ? ? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? ? ? ? ? 请求参数
?
? @param header ? ? ? ? ? ? ? ? ? 请求头Header
?? @param downloadProgressBlock? ? 网络请求进度
?
? @param success? ? ? ? ? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param failure? ? ? ? ? ? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDataTask )GET:(NSString )url
    ?? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? httpHeaderKeyValues:(NSDictionary )header
    ?? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    //? ? 可以接受的类型
    ? ? self.responseSerializer = [AFHTTPResponseSerializer serializer];
    //? ? 请求超时的时间
    ? ? self.requestSerializer.timeoutInterval = 30;
    //? Header 请求头
    ? ? if (header) {
    ?? ? ? ? ? [self setHTTPHeaderKeyValues:header];
    ? ? }
    ?? NSURLSessionDataTask
    task = [self GET:url parameters:params progress:downloadProgressBlock success:success failure:failure];
    ?? return task;
    }

  • (NSURLSessionDataTask )GET:(NSString )url
    ?? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    ? ? return [self GET:url params:params httpHeaderKeyValues:@{} progress:downloadProgressBlock success:success failure:failure];
    ?? ?
    }

#pragma mark - POST 请求方式
/*
?
? 发送post请求
?
?
? @param url? ? ? ? ? 请求路径
?? @param params ? 请求参数
?
? @param header ? ? ? 请求头Header
?? @param success? ? ? 请求成功后的回调,参数为id类型
?
? @param failure? ? ? 请求失败后的回调
?*/

  • (NSURLSessionDataTask )POST:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? httpHeaderKeyValues:(NSDictionary )header
    ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    //? ? 可以接受的类型
    ? ? self.responseSerializer = [AFHTTPResponseSerializer serializer];
    //? ? 请求超时的时间
    ? ? self.requestSerializer.timeoutInterval = 30;
    //? ? Header 请求头
    ? ? if (header) {
    ?? ? ? ? ? [self setHTTPHeaderKeyValues:header];
    ?? ? ? }
    ? ? NSURLSessionDataTask
    task = [self POST:url parameters:params progress:downloadProgressBlock success:success failure:failure];
    ?? ? ? return task;;
    }

  • (NSURLSessionDataTask )POST:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    ? ? return [self POST:url params:params httpHeaderKeyValues:@{} progress:downloadProgressBlock success:success failure:failure];
    }

#pragma mark -? 上传文件

/*
?
? 上传文件
?
?
? @param url? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? 请求参数
?
? @param header ? ? ? ? ? 请求头Header
?? @param formDataBlock? ? 上传文件的信息
?
? @param success? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param failure? ? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDataTask )upload:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? httpHeaderKeyValues:(NSDictionary )header
    ?? ? ? constructingBodyWithBlock:(BTHrequestFormDataBlock)formDataBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    //? 可以接受的类型
    ? ? self.responseSerializer = [AFHTTPResponseSerializer serializer];
    //? 请求超时的时间
    ? ? self.requestSerializer.timeoutInterval = 30;
    // ? Header 请求头
    ? ? if (header) {
    ? ? ? ? [self setHTTPHeaderKeyValues:header];
    ? ? }
    ? ? NSURLSessionDataTask
    task = [self POST:url parameters:params constructingBodyWithBlock:formDataBlock progress:nil success:success failure:failure];
    ?? ? ? return task;
    }

  • (NSURLSessionDataTask )upload:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? constructingBodyWithBlock:(BTHrequestFormDataBlock)formDataBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? success:(BTHrequestSuccessBlock)success
    ?? ? ? ? ? ? ? ? ? ? ? ? failure:(BTHrequestFailedBlock)failure{
    ? ? return [self upload:url params:params httpHeaderKeyValues:@{} constructingBodyWithBlock:formDataBlock success:success failure:failure];
    }

#pragma mark -? 下载文件(图片)
/*
?
? 下载
?
?
? @param url? ? ? ? ? ? ? ? ? ? ? 请求路径
?? @param params ? ? ? ? ? ? ? 请求参数
?
? @param header ? ? ? ? ? ? ? ? ? 请求头Header
?? @param downloadProgressBlock? ? 下载进度
?
? @param destination? ? ? ? ? ? ? 请求成功后的回调,参数为id类型
?? @param completionHandler? ? ? ? 请求失败后的回调
?
/

  • (NSURLSessionDownloadTask )download:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ?? ? ? ? ? ? ? ? ? httpHeaderKeyValues:(NSDictionary )header
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? ? destination:(BTHrequestDestinationBlock)destination
    ?? ? ? ? ? ? ? ? ? ? completionHandler:(BTHrequestCompletionHandlerBlock)completionHandler{
    // ? Header 请求头
    ? ? if (header) {
    ?? ? ? ? ? [self setHTTPHeaderKeyValues:header];
    ?? ? ? }
    ? ? NSURLRequest
    request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    ? ? NSURLSessionDownloadTask *task = [self downloadTaskWithRequest:request progress:downloadProgressBlock destination:destination completionHandler:completionHandler];
    ? ? [task resume];
    ? ? return task;
    ?? ?
    }

  • (NSURLSessionDownloadTask )download:(NSString )url
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? params:(id)params
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? progress:(BTHrequestUploadProgressBlock)downloadProgressBlock
    ?? ? ? ? ? ? ? ? ? ? ? ? ? destination:(BTHrequestDestinationBlock)destination
    ?? ? ? ? ? ? ? ? ? ? completionHandler:(BTHrequestCompletionHandlerBlock)completionHandler{
    ? ? return [self download:url params:params httpHeaderKeyValues:@{} progress:downloadProgressBlock destination:destination completionHandler:completionHandler];
    }

@end
9.2 BHTWeixinSDK 工具类基于WechatOpenSDK API框架的二次封装

//? BHTWeixinSDK.h
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/28.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface BHTWeixinSDK : NSObject

#pragma mark - 方法声明

/*
?实例化
?
/
+(instancetype)shareInstance;

#pragma mark - 注册APPKEY
/*
?初始化微信,注册APPKEY
?
/

  • (void)registerAppKeyWithDescription:(NSString *)description;

/*
?打开其他app的回调
?
/
+(BOOL)handleOpenURL:(NSURL *)url;

#pragma mark - 微信登录
/*
?调用微信登录接口
?
/
+(void)sendWeixinLoginRequest;

/*
?查看微信是否安装
?
/

  • (BOOL)isWeiXinInstall;

#pragma mark - 微信支付的功能
/*
?根据订单信息向后台申请prepayId以调用微信支付接口
?
userId ? 用户登录app的标识id
orderId? 订单号,由后台提供
account? 金额
?
/

  • (void)sendWeixinPayRequestWithUserId:(NSString )userId orderId:(NSString )orderId account:(NSString *)account;

#pragma mark - 微信分享的功能
/*
?分享到微信好友
?
title? ? 分享的文字标题
content? 分享的文字内容
urlStr ? 分享的图片URL字符串
?
/

  • (void)shareToWeixinFriendWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )imageStr WithConnectionAddress:(NSString )urlStr;

/*
?分享到微信朋友圈
?
title? ? 分享的文字标题
content? 分享的文字内容
subImage? 分享的图片URL字符串
urlStr ? 分享链接的地址URL字符串
?
/

  • (void)shareToWeixinFriendsCircleWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )subImage WithUrlStr:(NSString )urlStr;

@end

NS_ASSUME_NONNULL_END


//? BHTWeixinSDK.m
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/28.
//

#import "BHTWeixinSDK.h"
#import "BHTNetworkManager.h"

#pragma mark - 微信接口
#define Weixin_GetAccessTokenURL? ? @"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code"
#define Weixin_isAccessTokenCanUse ? ? @"https://api.weixin.qq.com/sns/auth?access_token=%@&openid=%@"
#define Weixin_UseRefreshToken? ? ? @"https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=wx8daa93036f9c7721&grant_type=refresh_token&refresh_token=%@"
#define Weixin_GetUserInformation? @"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@"

@interface BHTWeixinSDK()<WXApiDelegate>

@end

@implementation BHTWeixinSDK

#pragma mark - 实例化对象(单列)
/*
?实例化
?
? return 返回当前对象
?
/
static BHTWeixinSDK* _instance = nil;
+(instancetype) shareInstance{
? ? static dispatch_once_t onceToken ;
? ? dispatch_once(&onceToken, ^{
? ? ? ? _instance = [[super allocWithZone:NULL] init] ;
? ? }) ;
? ? return _instance ;
}

+(id)allocWithZone:(struct _NSZone *)zone{
? ? return [BHTWeixinSDK shareInstance] ;
}

-(id)copyWithZone:(NSZone *)zone{
? ? return [BHTWeixinSDK shareInstance] ;//return _instance;
}

-(id) mutablecopyWithZone:(NSZone *)zone{
? ? return [BHTWeixinSDK shareInstance] ;
}

#pragma mark - 回调
-(void)onReq:(BaseReq *)req{
?? ?
}

/*
?
微信支付/微信登录
?/
-(void)onResp:(BaseResp
)resp{
// 微信登录
? ? if([resp isKindOfClass:[SendAuthResp class]]){
? ? ? ? if (resp.errCode == 0) {
? ? ? ? ? ? [self loginWeixinSuccessWithBaseResp:resp];
? ? ? ? }else{
? ? ? ? ? ? DSLog(@"%@",LOGINFAILED);
? ? ? ? ? ? [MBProgressHUD wj_showError:LOGINFAILED];
? ? ? ? }
? ? }
//微信支付
? ? if ([resp isKindOfClass:[PayResp class]]){
? ? ? ? [self handleWeixinPayCallBackResultWithPayResp:resp];
? ? }else{
? ? ? ? ? DSLog(@"%@",LOGINFAILED);
? ? ? ? [MBProgressHUD wj_showError:LOGINFAILED];
? ? }
}

#pragma mark - 注册APPKEY
/*
?初始化微信,注册APPKEY
?
/

  • (void)registerAppKeyWithDescription:(NSString *)description{
    ? ? [WXApi registerApp:Weixin_AppID universalLink:description];
    }

/*
?打开其他app的回调
?
/
+(BOOL)handleOpenURL:(NSURL *)url{
? ? return [WXApi handleOpenURL:url delegate:[self shareInstance]];
}

+(void)sendWeixinLoginRequest{
? ? //构造SendAuthReq结构体
? ? SendAuthReq* req =[[SendAuthReq alloc ] init ];
? ? req.scope = @"snsapi_userinfo" ;
? ? req.state = @"123" ;
? ? //第三方向微信终端发送一个SendAuthReq消息结构
? ? [WXApi sendReq:req completion:^(BOOL success) {
?? ? ? DSLog(@"%@",success);
? ? }];
}

  • (BOOL)isWeiXinInstall{
    ? ? return? [WXApi isWXAppInstalled];
    }

#pragma mark - 微信登录成功获取token
-(void)loginWeixinSuccessWithBaseResp:(BaseResp )resp{
?? ? SendAuthResp?
auth = (SendAuthResp)resp;
?? ? NSString
code = auth.code;
? ? DSLog(@"code:%@",code);
//? ? Weixin_AppID和Weixin_AppSecret是微信申请下发的.
? ? NSString strUrl = [NSString stringWithFormat:Weixin_GetAccessTokenURL,Weixin_AppID,Weixin_AppSecret,code];
? ? [[BHTNetworkManager shareInstance] GET:strUrl params:@{} progress:^(NSProgress
_Nonnull downloadProgress) {
? ? ? ? //网络请求进度条(暂时未封装-这个根据客户需求而定)
? ? } success:^(NSURLSessionDataTask _Nonnull task, id? _Nullable JSONDict) {
? ? ? ? NSDictionary
responseObject=(NSDictionary )JSONDict;
? ? ? ? NSString
access_token = responseObject[@"access_token"];
? ? ? ? NSString refresh_token = responseObject[@"refresh_token"];
? ? ? ? NSString
openid = responseObject[@"openid"];
? ? ? ? [self isAccess_tokenCanUseWithAccess_token:access_token openID:openid completionHandler:^(BOOL isCanUse) {
? ? ? ? ? ? if (isCanUse) {
? ? ? ? ? ? ? ? [self getUserInformationWithAccess_token:access_token openID:openid];
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? [self useRefresh_token:refresh_token];
? ? ? ? ? ? }
? ? ? ? }];
? ? } failure:^(NSURLSessionDataTask _Nullable task, NSError _Nonnull error) {
? ? ? ? DSLog(@"error:%@",error);
? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
? ? }];
?? ?
}

#pragma mark - 若过期,使用refresh_token获取新的access_token

  • (void)useRefresh_token:(NSString )refresh_token{
    ? ? NSString
    strOfUseRefresh_token = [NSString stringWithFormat:Weixin_UseRefreshToken, refresh_token];
    ? ? DSLog(@"%@",strOfUseRefresh_token);
    ? ? [[BHTNetworkManager shareInstance] GET:strOfUseRefresh_token params:@{} progress:^(NSProgress _Nonnull downloadProgress) {
    // ? 网络请求进度条(暂时未封装-这个根据客户需求而定)
    ? ? } success:^(NSURLSessionDataTask
    _Nonnull task, id? _Nullable JSONDict) {
    ? ? ? NSDictionary responseObject=(NSDictionary )JSONDict;
    ? ? ? NSString openid = responseObject[@"openid"];
    ? ? ? NSString
    access_token = responseObject[@"access_token"];
    ? ? ? NSString refresh_tokenNew = responseObject[@"refresh_token"];
    ? ? ? [self isAccess_tokenCanUseWithAccess_token:access_token openID:openid completionHandler:^(BOOL isCanUse) {
    ? ? ? ? ? if (isCanUse) {
    ? ? ? ? ? ? ? [self getUserInformationWithAccess_token:access_token openID:openid];
    ? ? ? ? ? }else{
    ? ? ? ? ? ? ? [self useRefresh_token:refresh_tokenNew];
    ? ? ? ? ? }
    ? ? ? }];
    ?? ? ? ?
    ? ? } failure:^(NSURLSessionDataTask
    _Nullable task, NSError * _Nonnull error) {
    ? ? ? ? DSLog(@"%@",error);
    ? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
    ? ? }];
    }

#pragma mark - 判断access_token是否过期

  • (void)isAccess_tokenCanUseWithAccess_token:(NSString )access_token openID:(NSString )openID completionHandler:(void(^)(BOOL isCanUse))completeHandler{
    ? ? NSString strOfSeeAccess_tokenCanUse = [NSString stringWithFormat:Weixin_isAccessTokenCanUse, access_token,openID];
    ? ? [[BHTNetworkManager shareInstance] GET:strOfSeeAccess_tokenCanUse params:@{} progress:^(NSProgress
    _Nonnull downloadProgress) {
    // 网络请求进度条(暂时未封装-这个根据客户需求而定)
    ? ? } success:^(NSURLSessionDataTask _Nonnull task, id? _Nullable JSONDict) {
    ? ? ? ? NSDictionary
    responseObject=(NSDictionary )JSONDict;
    ? ? ? ? if ([responseObject[@"errmsg"] isEqualToString:@"ok"]) {
    ? ? ? ? ? ? completeHandler(YES);
    ? ? ? ? }else{
    ? ? ? ? ? ? completeHandler(NO);
    ? ? ? ? }
    ? ? } failure:^(NSURLSessionDataTask
    _Nullable task, NSError * _Nonnull error) {
    ? ? ? ? DSLog(@"%@",error);
    ? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
    ? ? }];
    ?? ?
    }
    #pragma mark - 若未过期,获取用户信息
  • (void)getUserInformationWithAccess_token:(NSString )access_token openID:(NSString )openID{
    ?? NSString strOfGetUserInformation = [NSString stringWithFormat:Weixin_GetUserInformation, access_token,openID];
    ? ? [[BHTNetworkManager shareInstance] GET:strOfGetUserInformation params:@{} progress:^(NSProgress
    _Nonnull downloadProgress) {
    ?? ? ? // 网络请求进度条(暂时未封装-这个根据客户需求而定)
    ? ? } success:^(NSURLSessionDataTask _Nonnull task, id? _Nullable JSONDict) {
    ?? ? ? NSDictionary
    responseObject=(NSDictionary )JSONDict;
    ?? ? ? NSString
    nickname = responseObject[@"nickname"];//[responseObject objectForKey:@"nickname"];
    ?? ? ? DSLog(@"nickname:%@",nickname);
    ?? ? ? NSString headimgurl = responseObject[@"headimgurl"];
    ?? ? ? DSLog(@"headimgurl:%@",headimgurl);
    ?? ? ? NSNumber
    sexnumber = responseObject[@"sex"];
    ?? ? ? NSString sexstr = [NSString stringWithFormat:@"%@",sexnumber];
    ?? ? ? NSString
    sex;
    ?? ? ? if ([sexstr isEqualToString:@"1"]) {
    ?? ? ? ? ? sex = @"男";
    ?? ? ? }else if ([sexstr isEqualToString:@"2"]){
    ?? ? ? ? ? sex = @"女";
    ?? ? ? }else{
    ?? ? ? ? ? sex = @"未知";
    ?? ? ? }
    ? ? ? ? //NSString province = responseObject[@"province"];
    ? ? ? ? //NSString
    city = responseObject[@"city"];
    ? ? ? ? //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
    ? ? ? ? // NSString unionid = responseObject[@"unionid"];
    ? ? ? ? //获取到用户信息后根据需要保存在本地或上传到服务端,用作的用户信息
    ? ? } failure:^(NSURLSessionDataTask
    _Nullable task, NSError * _Nonnull error) {
    ? ? ? ? DSLog(@"%@",error);
    ? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
    ? ? }];
    }

#pragma mark - 向后台申请支付请求,获取prepayId
/**
根据订单信息向后台申请prepayId以调用微信支付接口

@param userId ? 用户登录app的标识id
@param orderId? 订单号,由后台提供
@param account? 金额
*/

  • (void)sendWeixinPayRequestWithUserId:(NSString )userId orderId:(NSString )orderId account:(NSString )account{
    ? ? NSDictionary
    paramDict = @{
    ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"userId":@(userId.integerValue),
    ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"orderId":orderId,
    ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @"account":@(account.integerValue)
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };
    ? ? NSString "";
    //? ? getWeixinPrepayID:后台提供,用来向后台请求prepayId的接口
    ? ? [[BHTNetworkManager shareInstance] POST:getWeixinPrepayID params:paramDict progress:^(NSProgress
    _Nonnull downloadProgress) {
    //? ? ? ? 网络请求进度条(暂时未封装-这个根据客户需求而定)
    ? ? } success:^(NSURLSessionDataTask _Nonnull task, id? _Nullable JSONDict) {
    ? ? ? ? NSDictionary
    responseObject=(NSDictionary )JSONDict;
    ? ? ? ? NSNumber
    state = responseObject[@"state"];
    ? ? ? ? if (state.integerValue == 0) {
    ? ? ? ? ? ? NSString prepayId = responseObject[@"data"][0][@"prepayId"];
    ? ? ? ? ? ? //获取prepayId后客户端生成签名然后发送支付请求
    ? ? ? ? ? ? [self weixinPayWithPrepayId:prepayId];
    ? ? ? ? }else{
    ? ? ? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
    ? ? ? ? }
    ? ? } failure:^(NSURLSessionDataTask
    _Nullable task, NSError * _Nonnull error) {
    ? ? ? ? DSLog(@"%@",error);
    ? ? ? ? [MBProgressHUD wj_showError:REQUESTFAIL];
    ? ? }];
    ?? ?
    }

/**
调起微信客户端,申请支付

@param prepayID ? 得到prepayId后客户端生成签名然后发送支付请求
*/

  • (void)weixinPayWithPrepayId:(NSString )prepayID{
    ? ? //正常情况下,这里所有的参数都是后台提供给我们,但是我们后台人员不给力,只能我放在客户端来做签名了.希望你们后台人员比较给力.
    ? ? PayReq
    request = [[PayReq alloc] init];
    ? ? //微信支付分配的商户号
    ? ? request.partnerId = Weixin_PartnerId;
    ? ? //后台给的订单ID
    ? ? request.prepayId= prepayID;
    ? ? //微信给的固定值,就这么写
    ? ? request.package = @"Sign=WXPay";
    ? ? //32位随机字符串
    ? ? request.nonceStr= [NSString get32RandomString];
    ? ? //时间戳
    ? ? request.timeStamp= [NSString getCurrentTimestamp].intValue;
    ? ? /*
    ? ?
    签名
    ?? ?
    ? ? Weixin_AppID:微信开放平台审核通过的应用APPID
    ? ?
    Weixin_AppKey:在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 里面设置的微信密钥
    ? ? /
    ? ? NSString
    signStr = [NSString stringWithFormat:@"appid=%@&noncestr=%@&package=%@&partnerid=%@&prepayid=%@×tamp=%u&key=%@",Weixin_AppID,request.nonceStr,request.package,request.partnerId,request.prepayId,(unsigned int)request.timeStamp,Weixin_AppID];
    ? ? //将签名进行MD5运算并转换为大写
    ? ? request.sign= [NSString stringFromUpperCaseMD5:signStr];
    ? ? //支付请求
    ? ? [WXApi sendReq:request completion:^(BOOL success) {
    ?? ? ? ? DSLog(@"%@",success);
    ? ? }];
    }

#pragma mark - 微信支付是否成功的回调
-(void)handleWeixinPayCallBackResultWithPayResp:(BaseResp )resp{
? ? PayResp
response=(PayResp *)resp;
? ? switch (response.errCode) {
?? ? ? ? ? case WXSuccess:
?? ? ? ? ? ? ? //服务器端查询支付通知或查询API返回的结果再提示成功
?? ? ? ? ? ? ? DSLog(@"支付成功");
?? ? ? ? ? ? ? break;
?? ? ? ? ? case WXErrCodeUserCancel:
?? ? ? ? ? ? ? //服务器端查询支付通知或查询API返回的结果再提示成功
?? ? ? ? ? ? ? DSLog(@"用户点击取消并返回");
?? ? ? ? ? ? ? break;
?? ? ? ? ? default:
?? ? ? ? ? ? ? DSLog(@"支付失败,retcode=%d",resp.errCode);
?? ? ? ? ? ? ? /*
? ? ? ? ? ? ? ? WXErrCodeCommon ? ? = -1, ? 普通错误类型
? ? ? ? ? ? ? ? WXErrCodeUserCancel = -2, ? 用户点击取消并返回
? ? ? ? ? ? ? ? WXErrCodeSentFail ? = -3, ? 发送失败
? ? ? ? ? ? ? ? WXErrCodeAuthDeny ? = -4, ? 授权失败
? ? ? ? ? ? ? ? WXErrCodeUnsupport? = -5, ? 微信不支持
? ? ? ? ? ? ? ?
/
?? ? ? ? ? ? ? break;
?? ? ? }
}

#pragma mark - 微信分享
/*
?分享到微信好友
?
title? ? 分享的文字标题
content? 分享的文字内容
urlStr ? 分享的图片URL字符串
?
/

  • (void)shareToWeixinFriendWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )imageStr WithConnectionAddress:(NSString )urlStr{
    ?? ? WXMediaMessage message = [WXMediaMessage message];
    ?? ? message.title = title;
    ?? ? message.description = content;
    ? ? //缩略图
    ? ? NSData
    thumbData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageStr]];
    ? ? UIImage thumbImage = [UIImage imageWithData:thumbData];
    ? ? [message setThumbImage:thumbImage];
    ? ? //大图
    ? ? WXWebpageObject
    webpageObject = [WXWebpageObject object];
    ? ? webpageObject.webpageUrl = urlStr;
    ? ? message.mediaObject = webpageObject;
    ? ? SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    ? ? req.bText = NO;
    ? ? req.message = message;
    ? ? req.scene = WXSceneSession;
    ? ? [WXApi sendReq:req completion:^(BOOL success) {
    ?? ? DSLog(@"%@",success);
    ? ? }];
    }

/*
?分享到微信朋友圈
?
title? ? 分享的文字标题
content? 分享的文字内容
urlStr ? 分享的图片URL字符串
?
/

  • (void)shareToWeixinFriendsCircleWithTitle:(NSString )title Content:(NSString )content imageURLStr:(nonnull NSString )subImage WithUrlStr:(nonnull NSString )urlStr{
    ? ? WXMediaMessage message = [WXMediaMessage message];
    ? ? message.title = title;
    ? ? message.description = content;
    ? ? //缩略图
    ? ? NSData
    thumbData = [NSData dataWithContentsOfURL:[NSURL URLWithString:subImage]];
    ? ? UIImage thumbImage = [UIImage imageWithData:thumbData];
    ? ? [message setThumbImage:thumbImage];
    ? ? //大图
    ? ? WXWebpageObject
    webpageObject = [WXWebpageObject object];
    ? ? webpageObject.webpageUrl = urlStr;
    ? ? message.mediaObject = webpageObject;
    ?? ?
    ? ? SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    ? ? req.bText = NO;
    ? ? req.message = message;
    ? ? req.scene = WXSceneTimeline;
    ? ? [WXApi sendReq:req completion:^(BOOL success) {
    ?? ? ? DSLog(@"%@",success);
    ? ? }];
  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
    //微信
    [BHTWeixinSDK registerAppKeyWithDescription:@“”];
    }
    10.2openURL方法中设置回调
    ? ? #pragma mark - OpenURL回调结果
    ? ? //iOS9-
    ? ? - (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString )sourceApplication annotation:(id)annotation{
    ? ? ? ? [BHTWeixinSDK shareInstance] handleOpenURL:url];
    ? ? ? ? return YES;
    ? ? }
    ? ? //iOS9和9+
    ? ? - (BOOL)application:(UIApplication
    )app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options{
    ? ? ? ? [BHTWeixinSDK shareInstance] handleOpenURL:url];
    ? ? ? ? return YES;
    ? ? }

? ? - (void)handleOpenURLWithURLHost:(NSURL *)url{
?? ? NSLog(@"url.host:%@", url.host);
?? ? ? //微信(登录,支付,分享)
?? ? ? if ([url.host isEqualToString:@"oauth"]||[url.host isEqualToString:@"pay"]||[url.host isEqualToString:@"platformId=wechat"]) {
? ? ? ? ? ? [BHTWeixinSDK shareInstance] handleOpenURL:url];
? }
}
十一、调用(微信平台API)
11.1调用之前需要判断是否安装了微信
/*
?查看微信是否安装
?
/

  • (BOOL)isWeiXinInstall;
    11.2.如果上述方法返回YES,直接调用接口就好,个人喜欢类方法,调用方便,可根据喜好自行修改.当然,前提是你已经取得了微信支付和登录分享的授权
    #pragma mark - 微信支付的功能
    /*
    ?根据订单信息向后台申请prepayId以调用微信支付接口
    ?
    [email protected] userId ? 用户登录app的标识id
    [email protected] orderId? 订单号,由后台提供
    [email protected] account? 金额
    ?
    /
  • (void)sendWeixinPayRequestWithUserId:(NSString )userId orderId:(NSString )orderId account:(NSString *)account;

#pragma mark - 微信分享的功能
/*
?分享到微信好友
?
[email protected] title? ? 分享的文字标题
[email protected] content? 分享的文字内容
[email protected] urlStr ? 分享的图片URL字符串
?
/

  • (void)shareToWeixinFriendWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )imageStr WithConnectionAddress:(NSString )urlStr;

/*
?分享到微信朋友圈
?
[email protected] title? ? 分享的文字标题
[email protected] content? 分享的文字内容
[email protected] subImage? 分享的图片URL字符串
[email protected] urlStr ? 分享链接的地址URL字符串
?
/

  • (void)shareToWeixinFriendsCircleWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )subImage WithUrlStr:(NSString )urlStr;
    十二、集成QQ平台API
    :iOS 接入QQSDK封装的工具类BHTTencentSDK(QQ登录,QQ好友分享,QQ空间分享)
    十三、SDK下载(QQ平台API)
    十四、添加依赖库(手动集成)-QQ平台API
    :把下载的SDK拖进工程,在Build Phases下面的Link Binary With Libraries项中添加下面所需的依赖库:
    ? ? Security.framework,
    ? ? libiconv.dylib,
    ? ? SystemConfiguration.framework,
    ? ? CoreGraphics.Framework,
    ? ? libsqlite3.dylib,
    ? ? CoreTelephony.framework,
    ? ? libstdc++.dylib,
    ? ? libz.dylib

十五、工程配置属性(QQ 平台的API)
?:在工程配置中的Build Settings一栏中找到Linking配置区,给Other Linker Flags配置项添加属性值:
? ? -fobjc-arc
十六、设置 URL Scheme (QQ 平台API)
:修改 info.plist 文件 URL types 项中后面的URL Schemes内容为"tencent + appid",例如:tencent1234567890
(我这里设置了支付宝,qq,微信,微博,只用到QQ的话,就添加QQ的就ok)

十七、添加URL Schemes 白名单(QQ 平台的API)
:在“Info.plist”中增加一个LSApplicationQueriesSchemes值,设置为array, 添加QQ和QQ空间需要的几个item(图片中我还添加了别的,只用QQ的话就填加下面这些就可以):
? ? ? ? mqqapi
? ? ? ? mqq
? ? ? ? mqqOpensdkSSoLogin
? ? ? ? mqqconnect
? ? ? ? mqqopensdkdataline
? ? ? ? mqqopensdkgrouptribeshare
? ? ? ? mqqopensdkfriend
? ? ? ? mqqopensdkapi
? ? ? ? mqqopensdkapiV2
? ? ? ? mqqopensdkapiV3
? ? ? ? mqzoneopensdk
? ? ? ? wtloginmqq
? ? ? ? wtloginmqq2
? ? ? ? mqqwpa
? ? ? ? mqzone
? ? ? ? mqzonev2
? ? ? ? mqzoneshare
? ? ? ? wtloginqzone
? ? ? ? mqzonewx
? ? ? ? mqzoneopensdkapiV2
? ? ? ? mqzoneopensdkapi19
? ? ? ? mqzoneopensdkapi
? ? ? ? Mqzoneopensdk

十八、Cocoapods 集成QQ平台的API(自动集成)

QQ 登录 分享?

? pod ‘TencentOpenApiSDK‘, ‘~> 2.9.5‘

? ? 1.切换到项目工程路径下:执行pod install 命令
十九、可以写代码了(QQ平台的API)

//? BHTTencentSDK.h
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/29.

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface BHTTencentSDK : NSObject

#pragma mark - 方法声明
/*
实例化
/
+(instancetype) shareInstance;

/*
?初始化
?
/
-(void)initSDK;

/*
?openURL
?
/
+(BOOL)handleOpenURL:(NSURL *)url;

#pragma mark -? QQ 第三方登录
/*
?请求调用qq登录
?
/

  • (void)sendQQLoginRequest;

#pragma mark ---- QQ 分享到QQ好友/分享到QQ空间
/*
?分享到QQ好友
?
[email protected] title ? ? 分享的文字标题
[email protected] content ? 分享的文字内容
[email protected] urlStr? ? 分享的图片URL字符串
?
/
+(QQApiSendResultCode)shareToQQWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString *)urlStr;

/*
?分享到QQ空间
?
[email protected] title ? ? 分享的文字标题
[email protected] content ? 分享的文字内容
[email protected] urlStr? ? 分享的图片URL字符串
?
/
+(QQApiSendResultCode)shareToQZoneWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString *)urlStr;

@end

NS_ASSUME_NONNULL_END

//
//? BHTTencentSDK.m
//? BHTIntegralMal
//
//? Created by 蔡令 on 2020/5/29.
//

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

#pragma mark - 将传过来的URL地址转成UTF8格式
static NSURL safeURL(NSString origin) {
? ? return [NSURL URLWithString:[origin stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}

static BHTTencentSDK _instance = nil;
//单例模式供外调用基类对象
+(instancetype) shareInstance{
? ? static dispatch_once_t onceToken ;
? ? dispatch_once(&onceToken, ^{
? ? ? ? _instance = [[super allocWithZone:NULL] init] ;
? ? }) ;
? ? return _instance ;
}
+(id) allocWithZone:(struct _NSZone
)zone{
? ? return [BHTTencentSDK shareInstance] ;
}

-(id) copyWithZone:(NSZone *)zone{
? ? return [BHTTencentSDK shareInstance] ;
}

-(id) mutablecopyWithZone:(NSZone *)zone{
? ? return [BHTTencentSDK shareInstance] ;
}

#pragma mark -? QQ 第三方登录

  • (void)sendQQLoginRequest{
    ? ? NSArray* permissions = [NSArray arrayWithObjects:
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? kOPEN_PERMISSION_GET_USER_INFO,
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
    ? ? ? ? ? ? ? ? ? ? ? ? ? ? nil];
    ? ? BOOL isSuccess = [_tencentOAuth authorize:permissions inSafari:NO];
    ? ? if (isSuccess) {
    ? ? ? ? DSLog(@"QQ调用登录成功");
    ? ? }else{
    ? ? ? ? DSLog(@"QQ调用登录失败");
    ? ? }
    }

//登录成功后的回调

  • (void)tencentDidLogin {
    ? ? if (_tencentOAuth.accessToken && 0 != [_tencentOAuth.accessToken length]){
    ? ? ? ? BOOL isGetUserInfo = [_tencentOAuth getUserInfo];
    ? ? ? ? if (isGetUserInfo) {
    ? ? ? ? ? ? DSLog(@"获取用户QQ信息成功");
    ? ? ? ? }
    ? ? }else{
    ? ? ? ? DSLog(@"登录不成功 没有获取accesstoken");
    ? ? }
    }

//获取用户信息回调

  • (void)getUserInfoResponse:(APIResponse) response{
    ? ? DSLog(@"getUserInfoResponse-%@",response.jsonResponse);
    ? ? if (response.jsonResponse==nil) {
    ? ? ? ? return;
    ? ? }
    ? ? NSDictionary
    dict = response.jsonResponse;
    ? ? DSLog(@"%@",dict);
    ? ? //昵称
    ? ? DSLog(@"%@",dict[@"nickname"]);
    ? ? //性别
    ? ? DSLog(@"%@",dict[@"gender"]);
    ? ? //openID:用户授权登录后对该用户的唯一标识
    ? ? DSLog(@"%@",_tencentOAuth.openId);
    ? ? //AccessToken凭证,用于后续访问各开放接口
    ? ? DSLog(@"%@",_tencentOAuth.accessToken);
    ? ? //头像
    ? ? DSLog(@"%@",dict[@"figureurl_qq_2"]);
    ? //获取到用户信息后根据需要保存在本地或上传到服务端,用作的用户信息
    }
    //登录失败后的回调(cancelled 代表用户是否主动退出登录)
  • (void)tencentDidNotLogin:(BOOL)cancelled {
    ?? ?
    }

//登录时网络有问题的回调

  • (void)tencentDidNotNetWork {
    ?? ?
    }

//初始化
-(void)initSDK{
? ? //appID:从腾讯那里申请的你的应用的AppID
? ? _tencentOAuth = [[TencentOAuth alloc] initWithAppId:QQ_AppID andDelegate:self];
}

//openURL
+(BOOL)handleOpenURL:(NSURL *)url {
? ? return [TencentOAuth HandleOpenURL:url];
}

#pragma mark ---- QQ 分享到QQ好友/分享到QQ空间
//分享到QQ好友
+(QQApiSendResultCode)shareToQQWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )urlStr{
? ? QQApiNewsObject
newsObj = [QQApiNewsObject objectWithURL:safeURL(urlStr)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? title:title
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? description:content
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? previewImageURL:safeURL(urlStr)];
? ? SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
? ? return [QQApiInterface sendReq:req];
}

//分享到QQ空间
+(QQApiSendResultCode)shareToQZoneWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString )urlStr{
? ? QQApiNewsObject
newsObj = [QQApiNewsObject objectWithURL:safeURL(urlStr)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? title:title
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? description:content
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? previewImageURL:safeURL(urlStr)];
? ? SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
? ? return [QQApiInterface SendReqToQZone:req];

  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
    ?? //qq
    ? ? [[BHTTencentSDK shareInstance] initSDK];
    }
    20.2 openURL方法中设置回调
    ? ? #pragma mark - OpenURL回调结果
    ? ? //iOS9-
    ? ? - (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString )sourceApplication annotation:(id)annotation{
    ? ? ? ? [BHTTencentSDK shareInstance] handleOpenURL:url];
    ? ? ? ? return YES;
    ? ? }
    ? ? //iOS9和9+
    ? ? - (BOOL)application:(UIApplication
    )app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options{
    ? ? ? ? [BHTTencentSDK shareInstance] handleOpenURL:url];
    ? ? ? ? return YES;
    ? ? }

? ? - (void)handleOpenURLWithURLHost:(NSURL *)url{
?? ? NSLog(@"url.host:%@", url.host);
?? ? ? ? ? //qq(分享,登录)
? ? ? ? if ([url.host isEqualToString:@"response_from_qq"]||[url.host isEqualToString:@"qzapp"]){
? ? ? ? ? ? [BHTTencentSDK shareInstance] handleOpenURL:url];
? ? ? ? }
? ? }
二十一、调用(QQ平台的API)
22.1 分享是方法,直接调用就好
#pragma mark ---- QQ 分享到QQ好友/分享到QQ空间
/*
?分享到QQ好友
?
[email protected] title ? ? 分享的文字标题
[email protected] content ? 分享的文字内容
[email protected] urlStr? ? 分享的图片URL字符串
?
/
+(QQApiSendResultCode)shareToQQWithTitle:(NSString )title Content:(NSString )content imageURLStr:(NSString *)urlStr;

/
?分享到QQ空间
?
[email protected] title ? ? 分享的文字标题
[email protected] content ? 分享的文字内容
[email protected] urlStr? ? 分享的图片URL字符串
?/
+(QQApiSendResultCode)shareToQZoneWithTitle:(NSString
)title Content:(NSString )content imageURLStr:(NSString )urlStr;
22.2 登录需要先实列化再调用一下接口
/

?请求调用qq登录
?*/

  • (void)sendQQLoginRequest;

[[BHTTencentSDK shareInstance] sendQQLoginRequest];