cocos2d 接入微信相关api ,分为h5 和 app
1、h5
// 依赖包引入
npm i -S weixin-js-sdk
2、app 调用原生sdk api
(1)通过jsb.bridge.sendToNative("原生方法名", JSON.stringify(参数));调用原生方法
(2)通过 jsb.bridge.onNative = (arg0, arg1) => {
this.callback.apply(this, [arg0, arg1])
}
监听原生回调
其他说明
(1)base64为分享地址加密,用来加密分享参数,在初始化sdk时候获取此参数赋值全局变量,此处用来邀新,可忽略
(2)AxApp 为封装ajax可忽略
下面是测试代码,此处把相关写成sdk
cocos ts代码
sdkMng.ts
import { sys } from "cc";
import { AxApp } from "../AxApp";
import { ISdk } from "./sdk/ISdk";
import { SdkH5 } from "./sdk/SdkH5";
import { SdkNative } from "./sdk/SdkNative";
import { Base64 } from './sdk/base64'
export class sdkMng extends axModule {
authPar: string
pid: string | number
weiXinBol: boolean
authInfo: any
regInfo: any
// sdk回调
readonly callbacks = {
payBack(succ: boolean) {
// 回调预留给项目处理; 比如事件通知
AxApp.ENTER.events.post(GameEvent.Animals)
},
//微信登录回调
wxLoginResult(data: string) {
let dataJson: any = JSON.parse(data)
this.oAuth(this.pid, ['', dataJson.access_token, dataJson.openid, dataJson.refresh_token])
console.log('wxLoginResult callback oAuth', ['', dataJson.access_token, dataJson.openid, dataJson.refresh_token])
},
// 苹果登陆回调
appleLoginResult(data: string) {
console.log('appleLoginResult ', data)
// let dataJson: any = JSON.parse(data)
this.oAuth('apple', [data])
},
// 微信分享回调
wxShareResult(data: string) {
let dataJson: any = JSON.parse(data)
console.log('wxShareResult ', data)
},
// 微信支付回调
wxPayResult(data: string) {
let dataJson: any = JSON.parse(data)
console.log('wxPayResult ', data)
},
// 支付宝支付回调
aliPayResult(data: string) {
let dataJson: any = JSON.parse(data)
console.log('aliPayResult ', data)
}
}
callback(name: string) {
let back = this.callbacks[name]
if (typeof (back) === 'function') {
let args: any = arguments
back.apply(this, ab_.args(args, 1, args.length))
}
}
private _sdk: ISdk
private _base64 = new Base64()
// 初始化sdk
protected initStart(): void {
if (sys.isBrowser) {
this._sdk = new SdkH5()
let code = SdkH5.getUrlParam('code')
let ihash = SdkH5.getUrlParam('_i')
// let token = SdkH5.getUrlParam('token')
if (ihash) {
this.init(this.decode64(ihash, true))
}
this.weiXinBol = this.isWeiXin()
if (this.weiXinBol) {
if (code) {
let parms: Array<number | string> = ['web', code]
this.oAuth('wx', parms)
} else {
//微信浏览器 吊起微信支付必须要获取openid
console.log('吊起微信支付必须要获取openid')
this._sdk.snsapi_base()
}
this._sdk.wxConfig()
this.regInfo = null
}
console.log('初始化 SdkH5', code)
} else if (sys.isNative) {
// 原生监听
jsb.bridge.onNative = (arg0, arg1) => {
this.callback.apply(this, [arg0, arg1])
}
this._sdk = new SdkNative()
console.log('初始化 SdkNative')
}
}
get sdk() {
return this._sdk
}
get base64() {
return this._base64
}
// sdk 非必要实现方法,调用方法
//根据订单号获取支付参数
public payThird(pid: string | number, id: string | number) {
let app: string = 'web'
let datas = [pid, app || '', this.authPar || '', id]
if (!pid) {
pid = this.pid
} else {
this.pid = pid
}
// 获取支付参数
let uri: string = '/payThird'
if (sys.isBrowser) {
if (pid == 'ali') {
// h5支付宝支付单独处理
this._sdk.aliPay(datas)
return;
}
//
if (this.weiXinBol) {
uri += '?wx=1';
}
} else {
datas[1] = 'Farm'
}
ajax.post(1, uri, datas, (err: any, pltData: any) => {
if (pltData && pltData.payment) {
let payment = pltData.payment
if (typeof (payment) == 'object') {
payment.pid = pid
}
this._sdk.payThird(payment, pid)
}
})
}
//充值
public topUp(pid: string, cash: number) {
if (cash > 999999900 || cash <= 0) {
return;
}
cash = cash * 100;
// if (cash > 999999900 || cash < 1) {
// return;
// }
// 接口参数3 是平台后台 平台管理 - 项目列表 项目的编号 暂时默认写死是3
ajax.post(1, '/topUp', [cash, 3], (err: any, pltData: any) => {
if (pltData) {
this.payThird(pid, pltData)
}
})
}
// 登录公共方法
/**
* @param pid wx 微信登录 apple 苹果登陆
* @param params 登录参数
*/
public oAuth(pid: string, params: any) {
ajax.post(1, '/oAuth', [pid || this.pid, params, { channel: 'Farm' }, this.regInfo || {}], (err: any, pltData: any) => {
if (sys.isBrowser) {
this._sdk.wxConfig()
}
if (pltData) {
this.authPar = pltData.par || ''
this.authInfo = pltData.member || pltData.login.member
let token = pltData.token || pltData.login.token
AxApp.ME.pltClient.head('atoken', token)
ajax.post(1, '/login', [{ token: token, from: { channel: 'Farm' } }], (err: any, data: any) => {
if (data) {
console.log(“登录成功”)
}
if (sys.isBrowser) {
this._sdk.wxConfig()
}
})
}
})
}
// 判断是不是微信浏览器
public isWeiXin() {
var ua: any = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
}
// 启动参数
public init(v) {
if (v) {
try {
v = typeof (v) === 'object' ? v : JSON.parse(v)
// 注册参数[mmId,from,uri,redirect,reg{}]
if (v[0]) {
this.regInfo = {
mmId: v[0]
}
}
} catch (e) {
console.error(e)
}
}
}
// 编码
public encode64(str: string, uri: boolean) {
str = this._base64.encode(str)
if (uri) {
str = str.replace(/[+|=|/]/g, function (word) {
switch (word) {
case '+':
return '-'
case '=':
return '_'
case '/':
return '.'
}
return word
})
}
return str
}
// 解码
public decode64(str: string, uri: any) {
if (uri) {
str = str.replace(/[-|_|.]/g, function (word) {
switch (word) {
case '-':
return '+'
case '_':
return '='
case '.':
return '/'
}
return word
})
}
str = this._base64.decode(str)
return str
}
public shareUrl(uri: string, bind: boolean, reg: any) {
// 注册参数[mmId,from,uri,redirect,reg{}]
var paras: Array<any> = []
paras.push(this.authInfo?.id || AxApp.SDKMNG?.authInfo?.id || '')
if (reg) {
paras.push(reg)
} else {
paras.push({
app: 'Fram'
})
}
paras.push('13056')
console.log('shareUrl 分享参数', JSON.stringify(paras))
var p1 = uri.indexOf('?')
var shareUrl = uri
if (p1 >= 0) {
shareUrl = uri + '&_i=' + this.encode64(JSON.stringify(paras), true)
} else {
shareUrl = uri + '?_i=' + this.encode64(JSON.stringify(paras), true)
}
console.log('分享地址', shareUrl)
return shareUrl
}
// 解析url
}
SdkNative.ts
import { ISdk, ShareType, PayType } from "./ISdk";
import { AxApp } from '../../AxApp'
export class SdkNative implements ISdk {
constructor() {
// 启动初始化
}
// 微信登录 type == wx 微信登录 apple 苹果登录
public loginThird(type: string) {
console.log('native wxLogin ', type);
AxApp.SDKMNG.pid = type
if (type == 'wx') {
jsb.bridge.sendToNative("wxLogin", type);
} else if (type == 'apple') {
jsb.bridge.sendToNative("appleLogin", type);
}
}
// 苹果登录
// public appleLogin(type: string) {
// console.log('native wxLogin ');
// jsb.bridge.sendToNative("appleLogin", 'appleLogin');
// }
// 微信分享
public wxShare(data: ShareType) {
console.log('native wxShare', data);
jsb.bridge.sendToNative("wxShare", JSON.stringify(data));
}
// wx 微信支付 ali支付宝支付
public payThird(data: PayType, pid: string | number) {
console.log('native wxPay', data);
if (data.pid == 'wx') {
jsb.bridge.sendToNative("wxPay", JSON.stringify(data));
} else if (pid == 'ali' || data.pid == 'ali') {
let parms: any = data
if (typeof (data) == 'object') {
parms = JSON.stringify(parms)
}
jsb.bridge.sendToNative("aliPay", parms);
}
}
// // 支付宝支付
// public aliPay(data: PayType) {
// console.log('native aliPay', data);
// jsb.bridge.sendToNative("aliPay", JSON.stringify(data));
// }
}
SdkH5.ts
import { ISdk, ShareType, PayType } from "./ISdk";
import { AxApp } from "../../AxApp";
import axConfig from "../../AxConfig";
import wx from 'weixin-js-sdk';
export class SdkH5 implements ISdk {
constructor() {
}
static initSteps: Array<number> = [1000, 2000, 4000, 8000, 16000, 32000, 64000]
static initI = 0
// 微信登录
public loginThird(data: string) {
if (data == 'wx') {
AxApp.SDKMNG.regInfo = {}
this.snsapi_base()
this.wxConfigRe()
}
AxApp.SDKMNG.pid = 'wx'
}
// 分享
public wxShare(v: ShareType) {
v = typeof (v) === 'object' ? v : JSON.parse(v)
wx.ready(function () {
var share = {
title: v.title || '', // 分享标题
desc: v.desc || '', // 分享描述
link: v.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: v.imageUrl, // 分享图标
}
console.log('updateWx', share)
wx.updateAppMessageShareData(share)
wx.updateTimelineShareData(share)
})
}
// 微信支付
public payThird(payment: PayType) {
if (typeof payment === 'string') {
let href: string = payment + '&redirect_url=' + encodeURIComponent(location.href + '?t1=' + +new Date().getTime() + '&token=' + AxApp.ME.pltClient.headers.atoken)
window.open(href)
return;
} else if (payment.paySign) {
// @ts-ignore
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
appId: payment.appId, //公众号名称,由商户传入
timeStamp: payment.timeStamp.toString(), //时间戳,自1970年以来的秒数
nonceStr: payment.nonceStr, //随机串
package: payment.package,
signType: 'MD5', //微信签名方式:
paySign: payment.paySign //微信签名
},
function (res) {
console.log('支付成功', res)
if (res.err_msg == 'get_brand_wcpay_request:ok') {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
res.errCode = 0
} else {
res.errCode = -1
}
AxApp.SDKMNG.callback.apply(this, ['wxPayResult', JSON.stringify(res)])
}
);
}
// wx.chooseWXPay({
// timestamp: payment.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
// nonceStr: payment.nonceStr, // 支付签名随机串,不长于 32 位
// package: payment.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
// signType: payment.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
// paySign: payment.paySign, // 支付签名
// success: () => {
// // 支付成功的操作
// location.href = payment + '&redirect_url=' + encodeURIComponent(location.href + '&t1=' + +new Date().getTime() + '&token=' + AxApp.ME.pltClient.headers.atoken)
// },
// cancel: () => {
// // 取消支付的操纵
// AxApp.ME.toast('取消支付')
// },
// fail: function () {
// // 支付失败的操作
// AxApp.ME.toast('支付失败')
// }
// })
}
// 支付宝支付
public aliPay(data: Array<number | string>): void {
ajax.post(1, '/payMode', [data[3]], (err, rep) => {
if (rep) {
data[2] = null
var returnUrl = location.href + '&token=' + encodeURIComponent(AxApp.ME.pltClient.headers.atoken);
var json: Array<number | string> = [...data, ...[returnUrl]]
var toUrl = axConfig.pltHost + 'C/payThirdR?<=' + encodeURIComponent(JSON.stringify(json));
location.href = toUrl;
}
})
}
// 获取url参数
static getUrlParam(paraName: any) {
let url = window.location.href
url = decodeURI(url)
var arrObj = url.split("?");
if (arrObj.length > 1) {
var arrPara = arrObj[1].split('&');
var arr;
for (var i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split("=");
if (arr != null && arr[0] == paraName) {
return arr[1];
};
};
return "";
} else {
return "";
}
}
// 通过config接口注入权限验证配置
public wxConfig() {
ajax.post(1, '/wxConfig', ["web", location.href], (err, rep) => {
console.log('pltClient C/wxConfig err,data:', err, rep)
if (rep) {
if (rep && rep.appId) {
//rep.debug = true
rep.jsApiList = [
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareAppMessage',
'onMenuShareTimeline',
// 'chooseWXPay'
]
// rep.debug = true
console.log('wxready wx.config')
wx.config(rep)
return;
}
}
this.wxConfigRe()
wx.error(this.wxConfigRe)
})
}
// 如果wx授权失败,则定时再次获取授权
public wxConfigRe(e?: any) {
console.log('wxConfig error ' + e)
// wx.ready(() => {
// let parms = {
// title: 'farm title',
// desc: 'fram desc',
// link: location.href,
// imageUrl: 'https://ss.dev.yiyiny.com/2020/12/23/sshprc2btbrgk5h1.png'
// }
// this.wxShare(parms)
// })
setTimeout(this.wxConfig, SdkH5.initI < SdkH5.initSteps.length ? SdkH5.initSteps[SdkH5.initI++] : SdkH5.initSteps[SdkH5.initSteps.length - 1])
}
// 静默授权
public snsapi_base() {
var backUri = location.href
console.log(backUri)
var redirectUri = 'https://授权域名/wx.html?u=' + AxApp.SDKMNG.encode64(backUri, true)
redirectUri =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx59a0fb7a9bd076e5&redirect_uri=' +
encodeURIComponent(redirectUri) +
'&response_type=code&scope=snsapi_userinfo&state=1'
console.log(redirectUri)
location.replace(redirectUri)
}
}
ISdk.ts
export interface ShareType {
title: string,
desc?: string,
link: string,
imageUrl: string,
}
export interface PayType {
pid: string,
id?: string,
appId: string | number, //公众号名称,由商户传入
timeStamp: string | number, //时间戳,自1970年以来的秒数
nonceStr: string | number, //随机串
package: string | number,
signType: string | number, //微信签名方式:
paySign: string | number //微信签名
payment: string
}
export interface ISdk {
loginThird(data?: string): void;
appleLogin?(data?: string): void;
wxShare(data: ShareType): void;
payThird(data: Array<number | string> | PayType, pid: string | number): void;
aliPay?(data: Array<number | string> | PayType): void;
getUrlParam?(data: any): void;
wxConfig?(): void;
snsapi_base?(): void;
wxConfigRe?(data: any): void;
shareUrl?(uri?: string, bind?: boolean, reg?: any): void;
}
base64.ts
export class Base64 {
constructor() {
// 启动初始化
}
public _keyStr: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/**
* encode
*/
public encode(input: any) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = this._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
public decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this._utf8_decode(output);
return output;
}
/**
* _utf8_encode
*/
public _utf8_encode(string: string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
public _utf8_decode(utftext: string) {
var string = "";
var i = 0;
var c, c1, c2, c3
c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
安卓
相关sdk自行引入
WXEntryActivity.java
package com.jsyiyi.newfarm.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
import com.cocos.lib.JsbBridge;
import com.jsyiyi.newfarm.R;
import com.jsyiyi.newfarm.uikit.NetworkUtil;
import com.jsyiyi.newfarm.utils.Constants;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX;
import com.tencent.mm.opensdk.modelmsg.WXAppExtendObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
private static String TAG = "MicroMsg.WXEntryActivity";
private IWXAPI api;
private MyHandler handler;
private static class MyHandler extends Handler {
private final WeakReference<WXEntryActivity> wxEntryActivityWeakReference;
public MyHandler(WXEntryActivity wxEntryActivity){
wxEntryActivityWeakReference = new WeakReference<WXEntryActivity>(wxEntryActivity);
}
@Override
public void handleMessage(Message msg) {
int tag = msg.what;
switch (tag) {
case NetworkUtil.GET_TOKEN: {
Bundle data = msg.getData();
JSONObject json = null;
try {
json = new JSONObject(data.getString("result"));
JsbBridge.sendToScript("wxLoginResult",json.toString());
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
handler = new MyHandler(this);
try {
Intent intent = getIntent();
api.handleIntent(intent, this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
switch (req.getType()) {
case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
goToGetMsg();
break;
case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
goToShowMsg((ShowMessageFromWX.Req) req);
break;
default:
break;
}
finish();
}
@Override
public void onResp(BaseResp resp) {
int result = 0;
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
result = R.string.errcode_success;
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = R.string.errcode_cancel;
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = R.string.errcode_deny;
break;
case BaseResp.ErrCode.ERR_UNSUPPORT:
result = R.string.errcode_unsupported;
break;
default:
result = R.string.errcode_unknown;
break;
}
// Toast.makeText(this, getString(result) + ", type=" + resp.getType(), Toast.LENGTH_SHORT).show();
if (resp.getType() == ConstantsAPI.COMMAND_SUBSCRIBE_MESSAGE) {
SubscribeMessage.Resp subscribeMsgResp = (SubscribeMessage.Resp) resp;
String text = String.format("openid=%s\ntemplate_id=%s\nscene=%d\naction=%s\nreserved=%s",
subscribeMsgResp.openId, subscribeMsgResp.templateID, subscribeMsgResp.scene, subscribeMsgResp.action, subscribeMsgResp.reserved);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
if (resp.getType() == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
WXLaunchMiniProgram.Resp launchMiniProgramResp = (WXLaunchMiniProgram.Resp) resp;
String text = String.format("openid=%s\nextMsg=%s\nerrStr=%s",
launchMiniProgramResp.openId, launchMiniProgramResp.extMsg,launchMiniProgramResp.errStr);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
if (resp.getType() == ConstantsAPI.COMMAND_OPEN_BUSINESS_VIEW) {
WXOpenBusinessView.Resp launchMiniProgramResp = (WXOpenBusinessView.Resp) resp;
String text = String.format("openid=%s\nextMsg=%s\nerrStr=%s\nbusinessType=%s",
launchMiniProgramResp.openId, launchMiniProgramResp.extMsg,launchMiniProgramResp.errStr,launchMiniProgramResp.businessType);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
if (resp.getType() == ConstantsAPI.COMMAND_OPEN_BUSINESS_WEBVIEW) {
WXOpenBusinessWebview.Resp response = (WXOpenBusinessWebview.Resp) resp;
String text = String.format("businessType=%d\nresultInfo=%s\nret=%d",response.businessType,response.resultInfo,response.errCode);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) {
SendAuth.Resp authResp = (SendAuth.Resp)resp;
final String code = authResp.code;
NetworkUtil.sendWxAPI(handler, String.format("https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=%s&secret=%s&code=%s&grant_type=authorization_code", "wx50024c757b7e8f0e",
"9a1dcc56a56c28b87060754ad847d326", code), NetworkUtil.GET_TOKEN);
}
finish();
}
private void goToGetMsg() {
// Intent intent = new Intent(this, GetFromWXActivity.class);
// intent.putExtras(getIntent());
// startActivity(intent);
// finish();
}
private void goToShowMsg(ShowMessageFromWX.Req showReq) {
// WXMediaMessage wxMsg = showReq.message;
// WXAppExtendObject obj = (WXAppExtendObject) wxMsg.mediaObject;
//
// StringBuffer msg = new StringBuffer();
// msg.append("description: ");
// msg.append(wxMsg.description);
// msg.append("\n");
// msg.append("extInfo: ");
// msg.append(obj.extInfo);
// msg.append("\n");
// msg.append("filePath: ");
// msg.append(obj.filePath);
//
// Intent intent = new Intent(this, ShowFromWXActivity.class);
// intent.putExtra(Constants.ShowMsgActivity.STitle, wxMsg.title);
// intent.putExtra(Constants.ShowMsgActivity.SMessage, msg.toString());
// intent.putExtra(Constants.ShowMsgActivity.BAThumbData, wxMsg.thumbData);
// startActivity(intent);
// finish();
}
}```
WXPayEntryActivity.java
```javascript
package com.jsyiyi.newfarm.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import com.cocos.lib.JsbBridge;
import com.google.gson.Gson;
import com.jsyiyi.newfarm.utils.Constants;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import org.json.JSONObject;
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
try {
api.handleIntent(getIntent(), this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
System.out.println("");
}
@Override
public void onResp(BaseResp resp) {
int result = 0;
//有时候支付结果还需要发送给服务器确认支付状态
try {
if (resp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX) {
// if (resp.errCode==0){
// Toast.makeText(this,"支付成功",Toast.LENGTH_LONG).show();
// }else if (resp.errCode==-2){
// Toast.makeText(this,"取消支付",Toast.LENGTH_LONG).show();
// }else {
// Toast.makeText(this,"支付失败",Toast.LENGTH_LONG).show();
// }
String gson = new Gson().toJson(resp);
JsbBridge.sendToScript("wxPayResult", gson);
finish();
}else {
finish();
}
}catch (Exception e){
e.printStackTrace();
finish();
}
}
}
IOS
ViewController.mm
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#import "ViewController.h"
#include "cocos/bindings/event/EventDispatcher.h"
#include "cocos/platform/Device.h"
#import "WXSDK/WXApiRequestHandler.h"
#include "cocos/platform/apple/JsbBridge.h"
#import <AlipaySDK/AlipaySDK.h>
#import <AuthenticationServices/AuthenticationServices.h>
#import "Utils/KeyChainStore.h"
#import <AdSupport/AdSupport.h>
@interface ViewController ()<WXApiManagerDelegate,ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>
@property (nonatomic,strong) JsbBridge *jsbBridge;
@property (nonatomic) enum WXScene currentScene;
@end
@implementation ViewController
static ICallback cb = ^void (NSString* _arg0, NSString* _arg1){
[[ViewController alloc] applyMethod:_arg0 arg1:_arg1];
};
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
self.jsbBridge = [JsbBridge sharedInstance];
[self.jsbBridge setCallback:cb];
self.currentScene = WXSceneSession;
}
-(void)applyMethod:(NSString*)name arg1:(NSString*)arg1 {
if ([name isEqualToString:@"wxLogin"]) {
[self wxLogin];
}else if ([name isEqualToString:@"wxShare"]){
[self wxShare:arg1];
}else if ([name isEqualToString:@"wxPay"]){
[self wxPay:arg1];
}else if ([name isEqualToString:@"aliPay"]){
[self aliPay:arg1];
}else if ([name isEqualToString:@"appleLogin"]){
[self appleLogin];
}else if ([name isEqualToString:@"deviceSign"]){
NSString *key = [self getUUIDByKeyChain];
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@"deviceSignResult" arg1:key];
}
}
-(NSString*)getUUIDByKeyChain{
// 这个key的前缀最好是你的BundleID
NSString*strUUID = (NSString*)[KeyChainStore load:@"com.jsyiyi.newfarm.deviceonlyone"];
//首次执行该方法时,uuid为空
if([strUUID isEqualToString:@""]|| !strUUID)
{
// 获取UUID 这个是要引入<AdSupport/AdSupport.h>的
strUUID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
if(strUUID.length ==0 || [strUUID isEqualToString:@"00000000-0000-0000-0000-000000000000"])
{
//生成一个uuid的方法
CFUUIDRef uuidRef= CFUUIDCreate(kCFAllocatorDefault);
strUUID = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault,uuidRef));
CFRelease(uuidRef);
}
//将该uuid保存到keychain
[KeyChainStore save:@"com.jsyiyi.newfarm.deviceonlyone" data:strUUID];
}
return strUUID;
}
-(void)wxLogin{
[WXApiRequestHandler sendAuthRequestScope: @"snsapi_userinfo"
State:@"com.jsyiyi.newfarm"
OpenID:@""
InViewController:self];
}
-(void)wxShare:(NSString*)arg{
NSDictionary *shareInfo = [self dictionaryWithJsonString:arg];
NSString *scene = [shareInfo valueForKey:@"scene"];
if ([scene isEqualToString:@"WXSceneTimeline"]) {
self.currentScene = WXSceneTimeline;
}
NSString *shareType = [shareInfo valueForKey:@"type"];
switch ([shareType intValue]) {
case 0:
[WXApiRequestHandler sendLinkURL:[shareInfo valueForKey:@"link"]
TagName:@""
Title:[shareInfo valueForKey:@"title"]
Description:[shareInfo valueForKey:@"desc"]
ThumbImage:[self base64Toimage:[shareInfo valueForKey:@"imageUrl"]]
InScene:_currentScene];
break;
case 1:
[WXApiRequestHandler sendText:[shareInfo valueForKey:@"title"]
InScene:_currentScene];
break;
case 2:
[WXApiRequestHandler sendImageData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[shareInfo valueForKey:@"imageUrl"]]]
TagName:@""
MessageExt:@""
Action:@""
ThumbImage:[self base64Toimage:[shareInfo valueForKey:@"imageUrl"]]
InScene:_currentScene];
break;
default:
[WXApiRequestHandler sendLinkURL:[shareInfo valueForKey:@"link"]
TagName:@""
Title:[shareInfo valueForKey:@"title"]
Description:[shareInfo valueForKey:@"desc"]
ThumbImage:[self base64Toimage:[shareInfo valueForKey:@"imageUrl"]]
InScene:_currentScene];
break;
}
}
-(void)wxPay:(NSString*)arg{
NSDictionary *payInfo = [self dictionaryWithJsonString:arg];
UInt32 time_int = [[payInfo objectForKey:@"timestamp"] intValue];
PayReq *request = [[[PayReq alloc] init] autorelease];
// request.appid = @"";
request.partnerId = [payInfo valueForKey:@"partnerid"];
request.prepayId= [payInfo valueForKey:@"prepayid"];
request.package = @"Sign=WXPay";
request.nonceStr= [payInfo valueForKey:@"noncestr"];
request.timeStamp= time_int;
request.sign= [payInfo valueForKey:@"sign"];
[WXApi sendReq:request completion:nil];
}
-(void)aliPay:(NSString*)arg{
[[AlipaySDK defaultService] payOrder:arg fromScheme:@"yiyifarm" callback:^(NSDictionary *resultDic) {
NSLog(@"");
}];
}
//苹果登录的方法
-(void)appleLogin{
if (@available(iOS 13.0, *)) {
ASAuthorizationAppleIDProvider *provider = [[ASAuthorizationAppleIDProvider alloc] init];
ASAuthorizationAppleIDRequest *request = [provider createRequest];
request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
ASAuthorizationController *vc = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
vc.delegate = self;
vc.presentationContextProvider = self;
[vc performRequests];
} else {
// Fallback on earlier versions
}
}
#pragma mark - ASAuthorizationControllerPresentationContextProviding
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0))
{
return self.view.window;
}
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0))
{
if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
ASAuthorizationAppleIDCredential *credential = authorization.credential;
NSString *state = credential.state;
NSString *userID = credential.user;
NSPersonNameComponents *fullName = credential.fullName;
NSString *email = credential.email;
NSString *authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding]; // refresh token
NSString *identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding]; // access token
ASUserDetectionStatus realUserStatus = credential.realUserStatus;
NSLog(@"state: %@", state);
NSLog(@"userID: %@", userID);
NSLog(@"fullName: %@", fullName);
NSLog(@"email: %@", email);
NSLog(@"authorizationCode: %@", authorizationCode);
NSLog(@"identityToken: %@ 长度:%ld", identityToken,(long)identityToken.length);
NSLog(@"realUserStatus: %@", @(realUserStatus));
// NSString *dataStr = [NSString stringWithFormat:@"identityToken,%@", identityToken];
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@"appleLoginResult" arg1:identityToken];
}
}
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0))
{
NSString *errorMsg = nil;
switch (error.code) {
case ASAuthorizationErrorCanceled:
errorMsg = @"用户取消了授权请求";
break;
case ASAuthorizationErrorFailed:
errorMsg = @"授权请求失败";
break;
case ASAuthorizationErrorInvalidResponse:
errorMsg = @"授权请求响应无效";
break;
case ASAuthorizationErrorNotHandled:
errorMsg = @"未能处理授权请求";
break;
case ASAuthorizationErrorUnknown:
errorMsg = @"授权请求失败未知原因";
break;
}
NSLog(@"%@", errorMsg);
}
- (BOOL) shouldAutorotate {
return YES;
}
-(void)managerDidRecvAuthResponse:(SendAuthResp *)response{
__weak __typeof(self) weakself = self;
if (response.errCode == 0) {
NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",@"wx50024c757b7e8f0e",@"9a1dcc56a56c28b87060754ad847d326",response.code];
NSURL *zoneUrl = [NSURL URLWithString:url];
NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
NSData *data1 = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data1 options:NSJSONReadingMutableContainers error:nil];
NSLog(@"token、openID字典===%@",dic);
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:0];
NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@"wxLoginResult" arg1:dataStr];
}
}
-(void)managerDidRecvPayResultResponse:(PayResp *)response{
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:[NSString stringWithFormat:@"%i",response.errCode], @"errCode",nil];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:0];
NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@"wxPayResult" arg1:dataStr];
}
//fix not hide status on ios7
- (BOOL)prefersStatusBarHidden {
return YES;
}
// Controls the application's preferred home indicator auto-hiding when this view controller is shown.
- (BOOL)prefersHomeIndicatorAutoHidden {
return YES;
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
cc::Device::Orientation orientation = cc::Device::getDeviceOrientation();
// reference: https://developer.apple.com/documentation/uikit/uiinterfaceorientation?language=objc
// UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
// UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight
cc::EventDispatcher::dispatchOrientationChangeEvent(static_cast<int>(orientation));
float pixelRatio = cc::Device::getDevicePixelRatio();
cc::EventDispatcher::dispatchResizeEvent(size.width * pixelRatio
, size.height * pixelRatio);
CAMetalLayer *layer = (CAMetalLayer *)self.view.layer;
CGSize tsize = CGSizeMake(static_cast<int>(size.width * pixelRatio),
static_cast<int>(size.height * pixelRatio));
layer.drawableSize = tsize;
}
/*!
* @brief 把格式化的JSON格式的字符串转换成字典
* @param jsonString JSON格式的字符串
* @return 返回字典
*/
- (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
if (jsonString == nil) {
return nil;
}
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
return dic;
}
-(UIImage*)base64Toimage:(NSString*)strImage{
NSURL *url = [NSURL URLWithString:strImage];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData: data];
return image;
}
-(NSDate *)nsstringConversionNSDate:(NSString *)dateStr
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
NSDate *datestr = [dateFormatter dateFromString:dateStr];
return datestr;
}
-(NSString *)dateConversionTimeStamp:(NSDate *)date
{
NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[date timeIntervalSince1970]*1000];
return timeSp;
}
@end
AppDelegate.mm
/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "AppDelegate.h"
#import "ViewController.h"
#include "platform/ios/View.h"
#include "Game.h"
#include "SDKWrapper.h"
#import "WXSDK/WXApi.h"
#import "WXSDK/WXApiManager.h"
#import <AlipaySDK/AlipaySDK.h>
#include "cocos/platform/apple/JsbBridge.h"
@implementation AppDelegate
Game * game = nullptr;
@synthesize window;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[SDKWrapper shared] application:application didFinishLaunchingWithOptions:launchOptions];
// Add the view controller's view to the window and display.
CGRect bounds = [[UIScreen mainScreen] bounds];
self.window = [[UIWindow alloc] initWithFrame:bounds];
// Should create view controller first, cc::Application will use it.
_viewController = [[ViewController alloc] init];
_viewController.view = [[View alloc] initWithFrame:bounds];
_viewController.view.contentScaleFactor = UIScreen.mainScreen.scale;
_viewController.view.multipleTouchEnabled = true;
[self.window setRootViewController:_viewController];
// cocos2d application instance
game = new Game(bounds.size.width, bounds.size.height);
game->init();
[self.window makeKeyAndVisible];
[WXApi registerApp:@"APPID" universalLink:@""];
[WXApiManager sharedManager].delegate = _viewController;
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:resultDic options:0 error:0];
NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@"aliPayResult" arg1:dataStr];
}];
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
{
return [WXApi handleOpenUniversalLink:userActivity delegate:[WXApiManager sharedManager]];
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
[[SDKWrapper shared] applicationWillResignActive:application];
game->onPause();
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
[[SDKWrapper shared] applicationDidBecomeActive:application];
game->onResume();
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
[[SDKWrapper shared] applicationDidEnterBackground:application];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/*
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
*/
[[SDKWrapper shared] applicationWillEnterForeground:application];
}
- (void)applicationWillTerminate:(UIApplication *)application {
game->onClose();
[[SDKWrapper shared] applicationWillTerminate:application];
delete game;
game = nullptr;
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
[[SDKWrapper shared] applicationDidReceiveMemoryWarning:application];
cc::EventDispatcher::dispatchMemoryWarningEvent();
}
@end
注:包含的苹果登录和支付宝支付可忽略