cocos2dx android sharesdk,cocos2dx中IOS/Android跨平台微信登录和分享

转载请注明出处:

来自pur_e的博客

现在微信应用太广泛,稍微有点社交属性的都会集成微信登录和分享功能。cocos2dx中要实现跨平台登录和分享,有点麻烦。虽然可以使用ShareSdk/友盟等集成,不过看帮助文档也是分平台去分别集成的。官方之前推荐使用plugin-x来集成第三方的sdk,不过研究了一天,发现也就是稍微封装了一下,实现复杂且需要添加新的依赖库。现在官方又推荐他们自己的项目AnySdk,不过这个sdk封装平台其实也就是在上面又封装了一层,分享还可以接受,登录、支付如果还需要和AnySdk的服务器交互、生成订单,是不能容忍的。也许对于小的开发者可以提高开发效率,但订单信息实在是太敏感,不方便透露给第三者。

后来在网上看到一篇文章,用他的思路成功实现了跨平台的实现,用起来还是挺简单的,思路也比较清晰。

具体实现请参考文章,这里说一下微信登录功能的实现。

一、分享和登录的不同

分享比较简单,申请appid后,成功调起微信就可以分享成功了,其实分享也有结果返回,不过上面的文章中没有进行处理。

登录则要麻烦不少,首先登录分为好几个步骤:

调起微信拿到临时code

拿到code,和之前申请的appid/secret一起去拿到access_token

根据access_token去做后续操作,如拿用户信息等

这中间就涉及到http的调用,异步的回调,json结果解析等实现。

二、具体实现

1、ios端

因为前面提过的文章没有说明如何去实现微信回调,这里提一下:

1.1、在AppController.mm文件中,添加回调handleOpenUrl:

//这样,微信的回调就去调用到WXApiManager中去,WXApiManager需要实现WXApiDelegate接口

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {

return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];

}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];

}

1.2、WXApiManager需要实现WXApiDelegate协议,主要是onResp和onReq接口

@interface WXApiManager : NSObject

+ (instancetype)sharedManager;

@end

//WXApiManager.mm文件

@implementation WXApiManager

#pragma mark - LifeCycle

+(instancetype)sharedManager {

static dispatch_once_t onceToken;

static WXApiManager *instance;

dispatch_once(&onceToken, ^{

instance = [[WXApiManager alloc] init];

});

return instance;

}

- (void)dealloc {

[super dealloc];

}

#pragma mark - WXApiDelegate

- (void)onResp:(BaseResp *)resp {

//这里去调用SocialUtils中的具体实现接口

SocialUtils::wxRespForIos(resp);

}

- (void)onReq:(BaseReq *)req {

}

@end

1.3、调用HttpRequest,异步发起http请求,其实HttpRequest是对curl的一个封装,send请求会自动创建线程

//SocialUtils_ios.mm

void SocialUtils::wxRespForIos(void* resp){

auto authResp = static_cast(resp);

if(authResp == nullptr) return;

char url[256];

sprintf(url,WX_ACCESS_TOKEN_URL,WX_APP_ID,WX_SECRET,[[authResp code] UTF8String]);

CCLOG("%s",url);

//使用HttpRequest,异步调用http请求,这里可以简单使用CC_CALLBACK_2来实现回调函数封装

HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,CMD_ACCESS_TOKEN,std::placeholders::_1,std::placeholders::_2)

, url, "", HttpRequest::Type::GET, 10);

}

1.4、看看HttpUtils具体实现

//网络异步连接方法

void HttpUtils::requestHttp(HttpUtilsCallBack callback,const char* url,const char* data,network::HttpRequest::Type type,int timeout){

network::HttpRequest* request = new network::HttpRequest();

//设置请求类型

request->setRequestType(type);

request->setUrl(url);

//设置回调函数

request->setResponseCallback(std::bind(HttpUtils::onResponse,callback,std::placeholders::_1,std::placeholders::_2));

request->setRequestData(data, strlen(data));

network::HttpClient* httpClient=network::HttpClient::getInstance();

//设置超时时间

httpClient->setTimeoutForConnect(timeout);

httpClient->setTimeoutForRead(timeout);

httpClient->send(request);

request->release();

}

void HttpUtils::onResponse(HttpUtilsCallBack callback,HttpClient *client, HttpResponse *response){

if(callback == nullptr){

return;

}

if(!response) {

std::string temp("");

callback(temp, ERROR);

CCLOG("Log:response =null,plase check it.");

return;

}

//请求失败

if(!response->isSucceed())

{

std::string temp("");

callback(temp, ERROR);

CCLOG("ERROR BUFFER:%s",response->getErrorBuffer());

return;

}

int codeIndex=response->getResponseCode();

const char* tag=response->getHttpRequest()->getTag();

//请求成功

std::vector* buffer=response->getResponseData();

std::string temp(buffer->begin(),buffer->end());

callback(temp,SUCCUSS);

}

1.5 处理最终回调,会根据请求类型,做不同处理

//HttpRequest的回调函数,处理微信返回的json信息

void SocialUtils::onResponse(int cmd,std::string& data,int status){

if(status == HttpUtils::ERROR){

CCLOG("HelloWorld::onResponse,ERROR=%d",status);

return;

}

rapidjson::Document readdoc;

readdoc.Parse<0>(data.c_str());

if(readdoc.HasParseError())

{

CCLOG("GetParseError=%d\n", readdoc.GetParseError());

}

switch(cmd){

case CMD_ACCESS_TOKEN://获取到access_token

if(readdoc.HasMember("access_token")){

const char* access_token = readdoc["access_token"].GetString();

const char* openid = readdoc["openid"].GetString();

char url[256];

sprintf(url,WX_USER_INFO_URL,access_token,openid);

CCLOG("%s",url);

//继续请求用户信息

HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,CMD_USER_INFO,std::placeholders::_1,std::placeholders::_2)

, url, "", HttpRequest::Type::GET, 10);

}

break;

case CMD_USER_INFO://获取用户信息

if(_node != nullptr){

ViewUtils::showToast(_node, data, 5);

}

break;

}

}

至此,所有处理完成,拿到了用户的最终信息。当然,这只是客户端的处理,拿到open_id其实就可以请求服务端进行登录处理了。

2、Android端处理

Android上,处理思路也是一样,在微信的回调时,从Java端调用Native代码,只要将code返回就可以了。native拿到code后,处理和ios后续完全一样。

2.1 添加java端,native代码映射

package org.cocos2dx.cpp.tools;

public class JniHelper {

public static native void onResp(String code);

}

2.2 java处理微信回调

微信回调,需要在包名的目录下,建立一个wxapi目录,在其中创建一个WXEntryActivity,继承Activity,实现IWXAPIEventHandler接口,所有回调都会在这里处理。

android:configChanges="keyboardHidden|orientation|screenSize"

android:exported="true"

android:screenOrientation="portrait"

android:theme="@android:style/Theme.Translucent.NoTitleBar" />

@Override

public void onResp(BaseResp baseResp) {

SendAuth.Resp resp = (SendAuth.Resp)baseResp;

//调用native代码

JniHelper.onResp(resp.code);

Log.d("","tet");

this.finish();

}

2.3 native代码处理调用

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

//必须是C语言的函数,因为C++的函数会有不同的符号生成规则

//1.Java_:是格式,必须加的

//2.org_cocos2dx_cpp_tools_JniHelper:是包名+类名

//3.onResp:是Andriod工程中声明的名字

//4.中间需要_分开

extern "C"{

//给android调用的native代码,微信回调后会调用这个函数

JNIEXPORT void Java_org_cocos2dx_cpp_tools_JniHelper_onResp(JNIEnv *env, jobject thiz, jstring code)

{

const char *szCode = env->GetStringUTFChars(code, NULL);

char url[256];

sprintf(url,WX_ACCESS_TOKEN_URL,WX_APP_ID,WX_SECRET,szCode);

CCLOG("%s",url);

//调用HttpRequest去请求微信api,设置回调函数

HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,SocialUtils::CMD_ACCESS_TOKEN,std::placeholders::_1,std::placeholders::_2)

, url, "", HttpRequest::Type::GET, 10);

env->ReleaseStringUTFChars(code, szCode);

}

}

#endif

可以看到,从这里开始就和Ios一样了,调用HttpRequest去做下一步处理。跨平台到此结束。

结语

有了上面的框架后,其他sdk的集成都大同小异,稍微麻烦点就是了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值