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

前端之家收集整理的这篇文章主要介绍了cocos2dx中IOS/Android跨平台微信登录和分享前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载请注明出处:

来自pur_e的博客

http://www.jb51.cc/article/p-wrlyknov-ya.html


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

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

文章连接:Cocos2d-x 集成微信分享功能

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

一、分享登录的不同

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

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

  1. 调起微信拿到临时code
  2. 拿到code,和之前申请的appid/secret一起去拿到access_token
  3. 根据access_token去做后续操作,如拿用户信息等

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

二、具体实现

1、ios端

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

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

  1. //这样,微信的回调就去调用到WXApiManager中去,WXApiManager需要实现WXApiDelegate接口
  2. - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
  3. return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
  4. }
  5.  
  6. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  7. return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
  8. }
1.2、WXApiManager需要实现WXApiDelegate协议,主要是onResp和onReq接口

  1. @interface WXApiManager : NSObject<WXApiDelegate>
  2.  
  3. + (instancetype)sharedManager;
  4.  
  5. @end
  6.  
  7. //WXApiManager.mm文件
  8. @implementation WXApiManager
  9.  
  10. #pragma mark - LifeCycle
  11. +(instancetype)sharedManager {
  12. static dispatch_once_t onceToken;
  13. static WXApiManager *instance;
  14. dispatch_once(&onceToken,^{
  15. instance = [[WXApiManager alloc] init];
  16. });
  17. return instance;
  18. }
  19.  
  20. - (void)dealloc {
  21. [super dealloc];
  22. }
  23.  
  24. #pragma mark - WXApiDelegate
  25. - (void)onResp:(BaseResp *)resp {
  26. //这里去调用SocialUtils中的具体实现接口
  27. SocialUtils::wxRespForIos(resp);
  28. }
  29.  
  30. - (void)onReq:(BaseReq *)req {
  31. }
  32.  
  33. @end

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

  1. //SocialUtils_ios.mm
  2. void SocialUtils::wxRespForIos(void* resp){
  3. auto authResp = static_cast<SendAuthResp*>(resp);
  4. if(authResp == nullptr) return;
  5. char url[256];
  6. sprintf(url,WX_ACCESS_TOKEN_URL,WX_APP_ID,WX_SECRET,[[authResp code] UTF8String]);
  7. CCLOG("%s",url);
  8. //使用HttpRequest,异步调用http请求,这里可以简单使用CC_CALLBACK_2来实现回调函数封装
  9. HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,CMD_ACCESS_TOKEN,std::placeholders::_1,std::placeholders::_2),url,"",HttpRequest::Type::GET,10);
  10. }

1.4、看看HttpUtils具体实现

  1. //网络异步连接方法
  2. void HttpUtils::requestHttp(HttpUtilsCallBack callback,const char* url,const char* data,network::HttpRequest::Type type,int timeout){
  3. network::HttpRequest* request = new network::HttpRequest();
  4. //设置请求类型
  5. request->setRequestType(type);
  6. request->setUrl(url);
  7. //设置回调函数
  8. request->setResponseCallback(std::bind(HttpUtils::onResponse,callback,std::placeholders::_2));
  9. request->setRequestData(data,strlen(data));
  10.  
  11. network::HttpClient* httpClient=network::HttpClient::getInstance();
  12. //设置超时时间
  13. httpClient->setTimeoutForConnect(timeout);
  14. httpClient->setTimeoutForRead(timeout);
  15. httpClient->send(request);
  16. request->release();
  17. }
  18.  
  19. void HttpUtils::onResponse(HttpUtilsCallBack callback,HttpClient *client,HttpResponse *response){
  20. if(callback == nullptr){
  21. return;
  22. }
  23. if(!response) {
  24. std::string temp("");
  25. callback(temp,ERROR);
  26. CCLOG("Log:response =null,plase check it.");
  27. return;
  28. }
  29.  
  30. //请求失败
  31. if(!response->isSucceed())
  32. {
  33. std::string temp("");
  34. callback(temp,ERROR);
  35. CCLOG("ERROR BUFFER:%s",response->getErrorBuffer());
  36. return;
  37. }
  38.  
  39. int codeIndex=response->getResponseCode();
  40. const char* tag=response->getHttpRequest()->getTag();
  41.  
  42. //请求成功
  43. std::vector<char>* buffer=response->getResponseData();
  44. std::string temp(buffer->begin(),buffer->end());
  45. callback(temp,SUCCUSS);
  46.  
  47. }

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

  1. //HttpRequest的回调函数,处理微信返回的json信息
  2. void SocialUtils::onResponse(int cmd,std::string& data,int status){
  3. if(status == HttpUtils::ERROR){
  4. CCLOG("HelloWorld::onResponse,ERROR=%d",status);
  5. return;
  6. }
  7. rapidjson::Document readdoc;
  8. readdoc.Parse<0>(data.c_str());
  9. if(readdoc.HasParseError())
  10. {
  11. CCLOG("GetParseError=%d\n",readdoc.GetParseError());
  12. }
  13.  
  14. switch(cmd){
  15. case CMD_ACCESS_TOKEN://获取到access_token
  16. if(readdoc.HasMember("access_token")){
  17. const char* access_token = readdoc["access_token"].GetString();
  18. const char* openid = readdoc["openid"].GetString();
  19. char url[256];
  20. sprintf(url,WX_USER_INFO_URL,access_token,openid);
  21. CCLOG("%s",url);
  22. //继续请求用户信息
  23. HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,CMD_USER_INFO,10);
  24. }
  25. break;
  26. case CMD_USER_INFO://获取用户信息
  27. if(_node != nullptr){
  28. ViewUtils::showToast(_node,data,5);
  29. }
  30. break;
  31. }
  32.  
  33. }

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

2、Android端处理

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

2.1 添加java端,native代码映射

  1. package org.cocos2dx.cpp.tools;
  2. public class JniHelper {
  3. public static native void onResp(String code);
  4. }

2.2 java处理微信回调

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

  1. <activity android:name=".wxapi.WXEntryActivity"
  2. android:configChanges="keyboardHidden|orientation|screenSize"
  3. android:exported="true"
  4. android:screenOrientation="portrait"
  5. android:theme="@android:style/Theme.Translucent.NoTitleBar" />
  6.  
  7. @Override
  8. public void onResp(BaseResp baseResp) {
  9. SendAuth.Resp resp = (SendAuth.Resp)baseResp;
  10. //调用native代码
  11. JniHelper.onResp(resp.code);
  12. Log.d("","tet");
  13. this.finish();
  14. }

2.3 native代码处理调用

  1. #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  2. //必须是C语言的函数,因为C++的函数会有不同的符号生成规则
  3. //1.Java_:是格式,必须加的
  4. //2.org_cocos2dx_cpp_tools_JniHelper:是包名+类名
  5. //3.onResp:是Andriod工程中声明的名字
  6. //4.中间需要_分开
  7. extern "C"{
  8.  
  9. //给android调用的native代码,微信回调后会调用这个函数
  10. JNIEXPORT void Java_org_cocos2dx_cpp_tools_JniHelper_onResp(JNIEnv *env,jobject thiz,jstring code)
  11. {
  12. const char *szCode = env->GetStringUTFChars(code,NULL);
  13. char url[256];
  14. sprintf(url,szCode);
  15. CCLOG("%s",url);
  16. //调用HttpRequest去请求微信api,设置回调函数
  17. HttpUtils::requestHttp(std::bind(SocialUtils::onResponse,SocialUtils::CMD_ACCESS_TOKEN,10);
  18. env->ReleaseStringUTFChars(code,szCode);
  19. }
  20. }
  21. #endif

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


结语

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

猜你在找的Cocos2d-x相关文章