Commit 797e4297 authored by zhangzhe's avatar zhangzhe

iOS的修改

parent f2a162eb
......@@ -259,6 +259,7 @@ public class AdManager
Debug.unityLogger.Log("huangjunhui", "Splash加载 " + entity.adPlatform + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
GDTSplshAdUtils.Instance.LoadSplshAd(entity, listener, callback);
break;
#if UNITY_ANDROID
case ZXADConfig.PLANTFORM_AD_ZXHC:
//掌心汇川开屏广告
ZXHCSplashUtil.Instance.LoadSplshAd(entity, listener, callback);
......@@ -267,6 +268,7 @@ public class AdManager
case ZXADConfig.PLANTFORM_AD_FS:
FSSplashUtil.Instance.loadSplashAd(entity, listener, callback);
break;
#endif
default:
Debug.unityLogger.Log(ZXADConfig.ADManagerTAG, "不支持加载" + entity.adPlatform + "的Splash广告");
callback(false);
......@@ -1146,6 +1148,7 @@ public class AdManager
//广点通激励视频广告加载
GDTRewardAdUtil.Instance.LoadCacheRewardAd(entity, callback);
break;
#if UNITY_ANDROID
case ZXADConfig.PLANTFORM_AD_YLB:
//优良宝激励视频广告加载
YLBRewardAdUtil.Instance.LoadCacheRewardAd(entity, callback);
......@@ -1154,6 +1157,7 @@ public class AdManager
case ZXADConfig.PLANTFORM_AD_FS:
FSRewardUtils.Instance.LoadCacheRewardAd(entity, callback);
break;
#endif
default:
Debug.unityLogger.Log(ZXADConfig.ADManagerTAG, "不支持加载" + entity.adPlatform + "的激励视频广告");
callback(null);
......@@ -1257,6 +1261,7 @@ public class AdManager
//广点通激励视频广告播放
GDTRewardAdUtil.Instance.playCacheRewardAd(entity, listener, callback);
break;
#if UNITY_ANDROID
case ZXADConfig.PLANTFORM_AD_YLB:
//优良宝激励视频广告播放
YLBRewardAdUtil.Instance.playCacheRewardAd(entity, listener, callback);
......@@ -1265,6 +1270,7 @@ public class AdManager
case ZXADConfig.PLANTFORM_AD_FS:
FSRewardUtils.Instance.playCacheRewardAd(entity, listener, callback);
break;
#endif
default:
Debug.unityLogger.Log(ZXADConfig.ADManagerTAG, "不支持Show" + entity.adPlatform + "的激励视频广告");
callback(false);
......
......@@ -145,7 +145,7 @@ public class CSJRewardUtil
#if UNITY_IOS
EventUtils.onEventPullSuccess(entity);
this.csjAD.SetRewardVideoAdForIOS(entity.codeGroup + entity.slotName, ad);
callback(true);
callback(entity);
#endif
}
......
using System;
#if UNITY_ANDROID
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
......@@ -198,3 +199,4 @@ public class FSRewardUtils
}
}
#endif
\ No newline at end of file
using System;
#if UNITY_ANDROID
using System;
using System.Collections.Generic;
using UnityEngine;
......@@ -191,3 +192,4 @@ public class YLBRewardAdUtil
}
}
#endif
\ No newline at end of file
using System;
#if UNITY_ANDROID
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
......@@ -85,4 +86,4 @@ namespace ZXHC
}
}
#endif
using System;
#if UNITY_ANDROID
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
......@@ -102,3 +103,4 @@ public class ZXHCSplashUtil
}
#endif
\ No newline at end of file
......@@ -3,6 +3,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.SceneManagement;
......@@ -14,7 +15,29 @@ public class InitProject : MonoBehaviour
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE",
};
// Start is called before the first frame update
private bool haveNet;
#if !UNITY_EDITOR && UNITY_IOS
[DllImport("__Internal")]
public static extern void InitUMSDK(string appKey); // ios初始化友盟SDK
#endif
private void Awake()
{
Application.targetFrameRate = 60;
#if UNITY_IOS
//PingNetAddress();
StartCoroutine(CheckNetStatus());
#endif
#if !UNITY_EDITOR && UNITY_IOS
// 初始化友盟sdk
InitUMSDK("608785185844f15425ecd61a");
#endif
}
void Start()
{
#if UNITY_ANDROID
......@@ -23,16 +46,20 @@ public class InitProject : MonoBehaviour
OaidUtil.GetOaid(new Action<string>((oaid) => {
ZXHCUtils.SetDeviceOaid(oaid);
}));
#elif UNITY_IOS
StartCoroutine(StartApp());
#endif
}
private void Awake()
private IEnumerator StartApp()
{
//StartCoroutine(loadScene());
#if UNITY_IOS
while (!haveNet)
{
yield return new WaitForSeconds(0.5f);
}
#endif
private IEnumerator StartApp()
{
yield return GetPermission();
#if UNITY_ANDROID && !UNITY_EDITOR
//Android初始化参数
......@@ -46,6 +73,9 @@ public class InitProject : MonoBehaviour
if (IsOk())
{
Debug.unityLogger.Log("huangjunhui load ", "2 校验 签名 结束 开始 加载场景" + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
#if UNITY_IOS
Gettd();
#endif
}
else
{
......@@ -53,7 +83,72 @@ public class InitProject : MonoBehaviour
}
}
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void ShowIOSNoWebAlert();
IEnumerator CheckNetStatus()
{
#if UNITY_EDITOR
haveNet = false;
yield return new WaitForSeconds(0);
haveNet = true;
#endif
bool didShowAlert = false;
while (!haveNet)
{
if (Application.internetReachability == NetworkReachability.NotReachable)
{
if (!didShowAlert)
{
ShowIOSNoWebAlert();
didShowAlert = true;
}
Debug.Log("网络连接不可用");
haveNet = false;
}
else
{
Debug.Log("网络连接正常");
haveNet = true;
}
yield return new WaitForSeconds(0.1f);
}
}
/// <summary>
/// iOS 获取IDFA方法, 原生调用
/// </summary>
/// <param name="str"></param>
public void SetIDFA(string str)
{
Debug.Log("IDFA = " + str);
UserInfoManager.Instance().idfa = str;
}
/// <summary>
/// iOS 获取UDID方法, 原生调用
/// </summary>
/// <param name="str"></param>
public void SetUDID(string str)
{
Debug.Log("UDID = " + str);
UserInfoManager.Instance().udid = str;
}
#endif
public object GetPermission()
{
......@@ -101,7 +196,13 @@ public class InitProject : MonoBehaviour
Debug.unityLogger.Log("huangjunhui load ", "5 加载splash场景 " + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
}));
#else
callback("不支持");
////加载游戏场景
SceneManager.LoadSceneAsync(1);
//if (async2 != null)
//{
// async2.allowSceneActivation = true;
//}
EventUtils.OnEvent("app_start");
#endif
}
......@@ -130,6 +231,8 @@ public class InitProject : MonoBehaviour
int hashCode = Signatures[0].Call<int>("hashCode");
return hashCode == 1068458861;//我们签名的哈希值
}
#elif UNITY_IOS
return true;
#endif
return false;
}
......
......@@ -245,6 +245,31 @@ namespace EncryptHelper
return Encoding.UTF8.GetString(original);
}
/// <summary>
/// MD5加密
/// </summary>
/// <param name="value">需要加密字符串</param>
/// <returns>返回32位大写字符</returns>
public static string MD5Encrypt(string value)
{
//将输入字符串转换成字节数组 ANSI代码页编码
var buffer = Encoding.Default.GetBytes(value);
//接着,创建Md5对象进行散列计算
var data = MD5.Create().ComputeHash(buffer);
//创建一个新的Stringbuilder收集字节
var sb = new StringBuilder();
//遍历每个字节的散列数据
foreach (var t in data)
{
//转换大写十六进制字符串
// X2 大写
// x2 小写
sb.Append(t.ToString("x2"));
}
//返回十六进制字符串
return sb.ToString();
}
public static string ADCSD(string v,string v2)
{
string value;
......
......@@ -19,7 +19,11 @@ public class HttpTool : MonoBehaviour
public bool IsShowLog = false;
private static string HttpLogTag = "UnityHttp";
#if UNITY_IOS
private string appLs = "1ea6df1a7869ab78";
#elif UNITY_ANDROID
private string appLs = "c4f628fe0c45566f";
#endif
private static HttpTool _instacne = null;
......@@ -319,53 +323,43 @@ public class HttpTool : MonoBehaviour
#if UNITY_IOS
//paragrams.Add("pkg", "com.ym.animalspa");
//paragrams.Add("appLs", appLs);
//paragrams.Add("ts", UserInfoManager.getInstance().GetTimeStamp());
//paragrams.Add("platform", "ios");
//paragrams.Add("source", "AppStore");
//paragrams.Add("module", "behavior");
//paragrams.Add("ua", "Safari");
//paragrams.Add("ntt", "4G");
////paragrams.Add("device", "d0ff4c9b53d1688fc81ce8d730b2989a");
//if (UserInfoManager.getInstance().udid.Length > 0)
//{
// paragrams.Add("device", UserInfoManager.getInstance().udid);
//}
//if (UserInfoManager.getInstance().build.Length > 0)
//{
// paragrams.Add("vc", UserInfoManager.getInstance().build);
//}
//if (UserInfoManager.getInstance().version.Length > 0)
//{
// paragrams.Add("vn", UserInfoManager.getInstance().version);
//}
//if (UserInfoManager.getInstance().idfa.Length > 0)
//{
// paragrams.Add("idfa", UserInfoManager.getInstance().idfa);
//}
//if (UserInfoManager.getInstance().token.Length > 0)
//{
// paragrams.Add("token", UserInfoManager.getInstance().token);
//}
//if (UserInfoManager.getInstance().uid > 0)
//{
// paragrams.Add("uid", UserInfoManager.getInstance().uid + "");
//}
//if (IS_TGYZ)
//{
// paragrams["zygt"] = "hzwz";
// paragrams["tgtk"] = "1";
//}
//string signString = signParamsWithDict(paragrams);
//paragrams.Add("sign", signString);
paragrams["pkg"] = Application.identifier;
paragrams["appLs"] = appLs;
paragrams["ts"] = UserInfoManager.Instance().GetTimeStamp();
paragrams["platform"] = "ios";
paragrams["source"] = "AppStore";
paragrams["module"] = "behavior";
paragrams["ntt"] = "4G";
if (UserInfoManager.Instance().udid.Length > 0)
{
paragrams["device"] = UserInfoManager.Instance().udid;
}
if (UserInfoManager.Instance().build.Length > 0)
{
paragrams["vc"] = UserInfoManager.Instance().build;
}
if (UserInfoManager.Instance().version.Length > 0)
{
paragrams["vn"] = UserInfoManager.Instance().version;
}
if (UserInfoManager.Instance().idfa.Length > 0)
{
paragrams["idfa"] = UserInfoManager.Instance().idfa;
}
if (PrefenceUtils.GetInstance().getToken().Length > 0)
{
paragrams["token"] = PrefenceUtils.GetInstance().getToken();
}
if (IS_TGYZ)
{
paragrams["zygt"] = "hzwz";
paragrams["tgtk"] = "1";
paragrams["uid"] = "1";
}
else
{
paragrams["uid"] = PrefenceUtils.GetInstance().getUid();
}
#elif UNITY_ANDROID
if (IS_TGYZ)
......@@ -414,10 +408,9 @@ public class HttpTool : MonoBehaviour
paragrams["platform"] = "android";
paragrams["source"] = PrefenceUtils.GetInstance().getSource();
paragrams["ua"] = PrefenceUtils.GetInstance().getUA();
#endif
string signString = signParamsWithDict(paragrams);
paragrams["sign"] = signString;
#endif
......@@ -510,7 +503,7 @@ public class HttpTool : MonoBehaviour
return "";
#endif
}
#endregion
#endregion
}
using LitJson;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Text;
using System.IO;
// 用户单例
public class UserInfoManager : MonoBehaviour
{
private static UserInfoManager instance;
public static UserInfoManager Instance()
{
if (instance == null)
{
GameObject obj = new GameObject();
// 设置对象名字为脚本名
obj.name = typeof(UserInfoManager).ToString();
// 让这个单例模式对象 切换场景不移除
DontDestroyOnLoad(obj);
instance = obj.AddComponent<UserInfoManager>();
}
return instance;
}
// 钻石
public int avaDiamond = 0;
// 金币
public int avaCoin = 0;
// UDID
public string udid = "udid";
// IDFA
public string idfa = "";
public string token = "";
public string uid = "";
public string build = "1";
public string version = "1.0.0";
public int shubiao; // 0 shen 1 tou
public bool isBind = false; // 是否绑定wx
// public void touristLogin(Action<string> success, Action<string> fail)
// {
// NetworkTool.Instance().Post(HttpManager.URL_TOURIST_LOGIN, null, new Action<string, LoginResult>((res, model) => {
// this.token = model.token;
// this.uid = model.uid + "";
// success(res);
// AppInfo();
// }), new Action<string>((error) => {
// fail(error);
// AppInfo();
// }));
// }
// public void AppInfo()
// {
// NetworkTool.Instance().GET(HttpManager.URL_INFO, null, new Action<string, AppInfoResult>((res, model) => {
// shubiao = model.sdgowi["shubiao"];
//#if UNITY_ANDROID
// shubiao = 1;
//#endif
// IsBindWx();
// }), new Action<string>((error) => {
// IsBindWx();
// }));
// }
// public void IsBindWx()
// {
// NetworkTool.Instance().GET(HttpManager.URL_IS_BIND_WX, null, new Action<string, AppInfoBind>((res, model) => {
// isBind = model.isBind;
// Messenger.Broadcast("RefreshWXBind");
// }), new Action<string>((error) => {
// Messenger.Broadcast("RefreshWXBind");
// }));
// }
// 随机code
public string CreateRandomCode()
{
string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char[] chars = str.ToCharArray();
StringBuilder strRan = new StringBuilder();
System.Random ran = new System.Random();
for (int i = 0; i < 16; i++)
{
strRan.Append(chars[ran.Next(0, 62)]);
}
return strRan.ToString();
}
// 时间戳毫秒
public string GetTimeStamp()
{
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
string time = Convert.ToInt64(ts.TotalSeconds - 8 * 3600).ToString() + "000";
return time;
}
// 时间戳秒
public string TimeSecond()
{
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
string time = Convert.ToInt64(ts.TotalSeconds - 8 * 3600).ToString();
return time;
}
}
fileFormatVersion: 2
guid: ea02560b34b8f4fc488675d20d088960
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -14,6 +14,8 @@ public class AppInfoBean
///
/// </summary>
public @switch @switch { get; set; }
public sdgowi sdgowi;
}
public class H5_url
{
......@@ -38,3 +40,8 @@ public class @switch
/// </summary>
public int qq { get; set; }
}
public class sdgowi
{
public int vc;
}
......@@ -4,6 +4,8 @@ using UnityEngine;
using System;
using DG.Tweening;
using LitJson;
using System.Runtime.InteropServices;
public class WxLoginUtil : MonoBehaviour
{
public GameObject wxLoginBg;
......@@ -12,6 +14,18 @@ public class WxLoginUtil : MonoBehaviour
private static string WX_APPID = "wxeb614acc314efbfb";
private static string WX_APPKEY = "89abbb00107cc6255198cf1285181b4e";
#if UNITY_IOS
private static string state = "ioswdlcWxLog";
private static string universalLink = "https://feedapi.zhangxineducation.com/ioswdlc/";
//判断微信是否安装
[DllImport("__Internal")]
private static extern bool _isWechatInstalled();
[DllImport("__Internal")]
private static extern void _WechatLogin(string appid, string state, string universalLink);
#endif
private void Awake()
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
......@@ -33,6 +47,16 @@ public class WxLoginUtil : MonoBehaviour
//callBack = wxLoginCallBack;
//DeviceLogin();
#if UNITY_IOS
if (UserInfoManager.Instance().shubiao == 0)
{
callBack = wxLoginCallBack;
DeviceLogin();
wxLoginBg.SetActive(false);
return;
}
#endif
//Android打包
//Token为null 没有登录
if (PrefenceUtils.GetInstance().getToken().Equals(""))
......@@ -68,22 +92,67 @@ public class WxLoginUtil : MonoBehaviour
#if UNITY_EDITOR
DeviceLogin();
// BingWxLogin("061QyXFa1x7zSA0WBoGa1Ttfob0QyXFa");
#else
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.WxLogin();
#elif UNITY_IOS
SendWxLogin();
#endif
EventUtils.OnEvent("login_click");
}
#if UNITY_IOS
/// <summary>
/// iOS 微信登录
/// </summary>
public void SendWxLogin()
{
bool isInstalled = false;
isInstalled = _isWechatInstalled();
if (isInstalled)
{
_WechatLogin(WX_APPID, state, universalLink);
}
else
{
Debug.Log("请先安装微信客户端!");
}
}
/// <summary>
/// iOS微信登录回调
/// </summary>
/// <param name="msg"></param>
public void LoginCallBack(string msg)
{
Debug.Log("微信登录的回调在这里: " + msg);
// 051AdH000dJnkL1KyK300KeBye2AdH0d
BingWxLogin(msg);
}
#endif
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void ShowIOSWebView(string urlStr, string titleStr);
#endif
public void OnClickUserAgreement()
{
Debug.unityLogger.Log("用户协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#endif
}
public void OnClickPrivacyPolicy()
{
Debug.unityLogger.Log("隐私协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#endif
}
/// <summary>
/// 微信绑定成功
......
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
......@@ -94,24 +95,41 @@ public class SettingControl : MonoBehaviour
PlayerPrefs.SetInt(NotifIsOpen, 0);
}
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void ShowIOSWebView(string urlStr, string titleStr);
#endif
public void OnClickUserAgreement()
{
AudioUtils.ins.PlayBtnAudio();
Debug.unityLogger.Log("用户协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#endif
}
public void OnClickPrivacyPolicy()
{
AudioUtils.ins.PlayBtnAudio();
Debug.unityLogger.Log("隐私协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#endif
}
public void OnClicAboutUs()
{
AudioUtils.ins.PlayBtnAudio();
Debug.unityLogger.Log("关于我们");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.AboutUsUrl, "关于我们");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.AboutUsUrl, "关于我们");
#endif
}
public void OnclickLoginOut()
{
......
......@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using LitJson;
using Umeng;
......@@ -104,7 +105,11 @@ public class Splash : MonoBehaviour
Debug.unityLogger.Log("huangjunhui load ", "5 加载splash场景 " + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
}));
#else
callback("不支持");
////加载游戏场景
//SceneManager.LoadSceneAsync(1);
EventUtils.OnEvent("app_start");
Debug.unityLogger.Log("huangjunhui load ", "5 加载splash场景 " + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
#endif
}
......@@ -183,10 +188,38 @@ public class Splash : MonoBehaviour
PlayerDataControl.Instance.PrivacyPolicyUrl = bean.h5_url.privacy;
PlayerDataControl.Instance.MyQQ = bean.@switch.qq.ToString();
#if UNITY_IOS
if (int.Parse(UserInfoManager.Instance().build) >= bean.sdgowi.vc)
{
UserInfoManager.Instance().shubiao = 1;
}
else
{
UserInfoManager.Instance().shubiao = 0;
}
#endif
//第一次进入app 显示协议弹窗
if (PlayerDataControl.Instance.GetIsShowDialog())
{
// dialog.SetActive(true);
PlayerDataControl.Instance.SetIsShowDialog();
LoadCacheAd();
//登录
Login();
}
else
{ //不是第一次 展示开屏
Debug.unityLogger.Log("huangjunhui load ", "3 开始加载广告 " + ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString());
AdManager.Instance.LoadSplashAd(new SplshAdListener());
LoadCacheAd();
}
}), new Action<string, string>((code, errMsg) =>
{
PlayerDataControl.Instance.MyQQ = "435749473335";
}));
//第一次进入app 显示协议弹窗
if (PlayerDataControl.Instance.GetIsShowDialog())
......@@ -205,18 +238,34 @@ public class Splash : MonoBehaviour
AdManager.Instance.LoadSplashAd(new SplshAdListener());
LoadCacheAd();
}
}));
}
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void ShowIOSWebView(string urlStr, string titleStr);
#endif
public void OnClickUserAgreement()
{
Debug.unityLogger.Log("用户协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.UserAgreementUrl, "用户协议");
#endif
}
public void OnClickPrivacyPolicy()
{
Debug.unityLogger.Log("隐私协议");
#if UNITY_IOS
ShowIOSWebView(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#elif UNITY_ANDROID
CallLocalFunUtil.Instance.OpenWebPage(PlayerDataControl.Instance.PrivacyPolicyUrl, "隐私协议");
#endif
}
/// <summary>
......
fileFormatVersion: 2
guid: 88cedd93143814b95b73a503645d0b9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
//
// IOSADManager.h
// caiyuan
//
// Created by 张哲 on 2021/3/8.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface IOSADManager : NSObject
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: 5b6a371f436e0434c96e6f5089f57bfb
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// IOSADManager.m
// caiyuan
//
// Created by 张哲 on 2021/3/8.
//
#import "IOSADManager.h"
#import <BUAdSDK/BUAdSDK.h>
#import <UMCommon/UMCommon.h>
@implementation IOSADManager
#if defined(__cplusplus)
extern "C" {
#endif
// 初始化穿山甲SDK
void InitCSJSDK(char *appId)
{
NSLog(@"穿山甲appid:%@", [NSString stringWithUTF8String:appId]);
//穿山甲
[BUAdSDKManager setAppID:[NSString stringWithUTF8String:appId]];
// [BUAdSDKManager setAppID:@"5000546"];
[BUAdSDKManager setGDPR:0];
[BUAdSDKManager setCoppa:0];
[BUAdSDKManager setIsPaidApp:NO];
[BUAdSDKManager setLoglevel:BUAdSDKLogLevelDebug];
}
// 初始化友盟SDK
void InitUMSDK(char *appKey)
{
NSLog(@"unity传值:%@", [NSString stringWithUTF8String:appKey]);
[UMConfigure initWithAppkey:[NSString stringWithUTF8String:appKey] channel:@"App Store"];
[UMConfigure setLogEnabled: NO];
}
#if defined(__cplusplus)
}
#endif
@end
fileFormatVersion: 2
guid: d6e0521b9d1e445d188514697e917d63
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 13cfb14ab487b43abb55edac64a6258c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BGKeychainTool : NSObject
/**
本方法是得到 UUID 后存入系统中的 keychain 的方法
不用添加 plist 文件
程序删除后重装,仍可以得到相同的唯一标示
但是当系统升级或者刷机后,系统中的钥匙串会被清空,此时本方法失效
*/
+(NSString *)getDeviceIDInKeychain;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: aaf7a020319044d8cb7cc5a04711550d
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
#import "BGKeychainTool.h"
@implementation BGKeychainTool
+(NSString *)getDeviceIDInKeychain {
NSString *bundleId =[[NSBundle mainBundle]bundleIdentifier];
NSString *getUDIDInKeychain = (NSString *)[BGKeychainTool load:bundleId];
// NSLog(@"从keychain中获取到的 UDID_INSTEAD %@",getUDIDInKeychain);
if (!getUDIDInKeychain ||[getUDIDInKeychain isEqualToString:@""]||[getUDIDInKeychain isKindOfClass:[NSNull class]]) {
CFUUIDRef puuid = CFUUIDCreate( nil );
CFStringRef uuidString = CFUUIDCreateString( nil, puuid );
NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
CFRelease(puuid);
CFRelease(uuidString);
// NSLog(@"\n \n \n _____重新存储 UUID _____\n \n \n %@",result);
[BGKeychainTool save:bundleId data:result];
getUDIDInKeychain = (NSString *)[BGKeychainTool load:bundleId];
}
// NSLog(@"最终 ———— UDID_INSTEAD %@",getUDIDInKeychain);
return getUDIDInKeychain;
}
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassGenericPassword,(id)kSecClass,
service, (id)kSecAttrService,
service, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
if (keyData)
CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
}
@end
//这个方法是给unity调用的方法
const char * Get_UUID_By_KeyChain()
{
NSString* uuid = [BGKeychainTool getDeviceIDInKeychain];
return strdup(uuid.UTF8String);
}
fileFormatVersion: 2
guid: 740cd1c0d97714e3ba9b2b0175d9283e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// KeychainItemManager.h
// ZhiJi
//
// Created by 明津李 on 2020/6/8.
// Copyright © 2020 Company. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface KeychainItemManager : NSObject
+ (void)readKeychainIDFA;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: e709e18322f6f4217b8a59cc2d311c46
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// KeychainItemManager.m
// ZhiJi
//
// Created by 明津李 on 2020/6/8.
// Copyright © 2020 Company. All rights reserved.
//
#import "KeychainItemManager.h"
#import <AdSupport/AdSupport.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import "KeychainItemWrapper.h"
#import "UserData.h"
NSString * const FCLogin = @"SKLogin";
NSString * const FCIdentifier = @"SKIdentifier";
@implementation KeychainItemManager
+ (void)readKeychainIDFA
{
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:FCLogin accessGroup:nil];
UserData *data = [[UserData alloc] init];
[data initPlist];
[keychain setObject:@" " forKey:(__bridge id)(kSecAttrAccount)];
[keychain setObject:@" " forKey:(__bridge id)(kSecValueData)];
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
NSLog(@"app追踪权限:%lu",(unsigned long)status);
if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
NSLog(@"用户同意广告追踪");
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
if (idfa.length) {
[data writeValue:idfa Key:@"idfa"];
}
}
}];
} else {
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]){
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
if (idfa.length) {
[data writeValue:idfa Key:@"idfa"];
}
}else{
NSLog(@"用户开启了限制广告追踪");
}
}
if (![keychain objectForKey:(__bridge id)kSecAttrService]) {
NSString *identifier = [self getUUID];
if (identifier.length == 0) {
identifier = @"identifier";
}
NSDictionary *dic = @{FCIdentifier:identifier};
NSString * infoStr = [self convertToJsonData:dic];
[keychain setObject:infoStr forKey:(__bridge id)kSecAttrService];
[data writeValue:identifier Key:@"identifier"];
}else{
NSString *infoStr = [keychain objectForKey:(__bridge id)kSecAttrService];
NSDictionary *infoDic = [self dictionaryWithJsonString:infoStr];
if (infoDic) {
NSString *identifier = [NSString stringWithFormat:@"%@",infoDic[FCIdentifier]];
if (identifier.length) {
[data writeValue:identifier Key:@"identifier"];
}
}
}
}
+ (void)removeKeychainIDFA
{
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:FCLogin accessGroup:nil];
[keychain resetKeychainItem];
UserData *data = [[UserData alloc] init];
[data removeValueForKey:FCIdentifier];
}
+ (NSString *)getUUID
{
return [NSString stringWithFormat:@"%@",[self UUID]];
}
+ (NSString *)UUID
{
CFUUIDRef uuid = CFUUIDCreate(NULL);
assert(uuid != NULL);
CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
return (__bridge NSString *)(uuidStr);
}
+ (NSString *)getNickName
{
NSString *nickName = [self randomStringWithLength:10];
return [NSString stringWithFormat:@"%@",nickName];
}
+ (NSString *)randomStringWithLength:(NSInteger)len
{
NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
for (NSInteger i = 0; i < len; i++) {
int idx = arc4random() % letters.length;
[randomString appendFormat:@"%c", [letters characterAtIndex:idx]];
}
return randomString;
}
+ (NSString *)convertToJsonData:(NSDictionary *)dict{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString;
if (!jsonData) {
NSLog(@"%@",error);
}else{
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
NSRange range = {0,jsonString.length};
//去掉字符串中的空格
[mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
//去掉字符串中的换行符
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
return mutStr;
}
+ (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];
if(err)
{
NSLog(@"json解析失败:%@",err);
return nil;
}
return dic;
}
@end
fileFormatVersion: 2
guid: aed2ca79005a14fc6bc0523079f6ce90
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: x86_64
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:
/*
File: KeychainItemWrapper.h
Abstract:
Objective-C wrapper for accessing a single keychain item.
Version: 1.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
#import <UIKit/UIKit.h>
/*
The KeychainItemWrapper class is an abstraction layer for the iPhone Keychain communication. It is merely a
simple wrapper to provide a distinct barrier between all the idiosyncracies involved with the Keychain
CF/NS container objects.
*/
@interface KeychainItemWrapper : NSObject
{
NSMutableDictionary *keychainItemData; // The actual keychain item data backing store.
NSMutableDictionary *genericPasswordQuery; // A placeholder for the generic keychain item query used to locate the item.
}
@property (nonatomic, retain) NSMutableDictionary *keychainItemData;
@property (nonatomic, retain) NSMutableDictionary *genericPasswordQuery;
// Designated initializer.
- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup;
- (void)setObject:(id)inObject forKey:(id)key;
- (id)objectForKey:(id)key;
// Initializes and resets the default generic keychain item data.
- (void)resetKeychainItem;
@end
\ No newline at end of file
fileFormatVersion: 2
guid: 345b29d09ebb2478193c1904ce6904a2
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
/*
File: KeychainItemWrapper.m
Abstract:
Objective-C wrapper for accessing a single keychain item.
Version: 1.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
#import "KeychainItemWrapper.h"
#import <Security/Security.h>
/*
These are the default constants and their respective types,
available for the kSecClassGenericPassword Keychain Item class:
kSecAttrAccessGroup - CFStringRef
kSecAttrCreationDate - CFDateRef
kSecAttrModificationDate - CFDateRef
kSecAttrDescription - CFStringRef
kSecAttrComment - CFStringRef
kSecAttrCreator - CFNumberRef
kSecAttrType - CFNumberRef
kSecAttrLabel - CFStringRef
kSecAttrIsInvisible - CFBooleanRef
kSecAttrIsNegative - CFBooleanRef
kSecAttrAccount - CFStringRef
kSecAttrService - CFStringRef
kSecAttrGeneric - CFDataRef
See the header file Security/SecItem.h for more details.
*/
@interface KeychainItemWrapper (PrivateMethods)
/*
The decision behind the following two methods (secItemFormatToDictionary and dictionaryToSecItemFormat) was
to encapsulate the transition between what the detail view controller was expecting (NSString *) and what the
Keychain API expects as a validly constructed container class.
*/
- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert;
- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert;
// Updates the item in the keychain, or adds it if it doesn't exist.
- (void)writeToKeychain;
@end
@implementation KeychainItemWrapper
@synthesize keychainItemData, genericPasswordQuery;
- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup;
{
if (self = [super init])
{
// Begin Keychain search setup. The genericPasswordQuery leverages the special user
// defined attribute kSecAttrGeneric to distinguish itself between other generic Keychain
// items which may be included by the same application.
genericPasswordQuery = [[NSMutableDictionary alloc] init];
[genericPasswordQuery setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[genericPasswordQuery setObject:identifier forKey:(id)kSecAttrGeneric];
// The keychain access group attribute determines if this item can be shared
// amongst multiple apps whose code signing entitlements contain the same keychain access group.
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
// Ignore the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
#else
[genericPasswordQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
#endif
}
// Use the proper search constants, return only the attributes of the first match.
[genericPasswordQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[genericPasswordQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery];
NSMutableDictionary *outDictionary = nil;
if (! SecItemCopyMatching((CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) == noErr)
{
// Stick these default values into keychain item if nothing found.
[self resetKeychainItem];
// Add the generic attribute and the keychain access group.
[keychainItemData setObject:identifier forKey:(id)kSecAttrGeneric];
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
// Ignore the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
#else
[keychainItemData setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
#endif
}
}
else
{
// load the saved data from Keychain.
self.keychainItemData = [self secItemFormatToDictionary:outDictionary];
}
[outDictionary release];
}
return self;
}
- (void)dealloc
{
[keychainItemData release];
[genericPasswordQuery release];
[super dealloc];
}
- (void)setObject:(id)inObject forKey:(id)key
{
if (inObject == nil) return;
id currentObject = [keychainItemData objectForKey:key];
if (![currentObject isEqual:inObject])
{
[keychainItemData setObject:inObject forKey:key];
[self writeToKeychain];
}
}
- (id)objectForKey:(id)key
{
return [keychainItemData objectForKey:key];
}
- (void)resetKeychainItem
{
OSStatus junk = noErr;
if (!keychainItemData)
{
self.keychainItemData = [[NSMutableDictionary alloc] init];
}
else if (keychainItemData)
{
NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData];
junk = SecItemDelete((CFDictionaryRef)tempDictionary);
NSAssert( junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary." );
}
// Default attributes for keychain item.
[keychainItemData setObject:@"" forKey:(id)kSecAttrAccount];
[keychainItemData setObject:@"" forKey:(id)kSecAttrLabel];
[keychainItemData setObject:@"" forKey:(id)kSecAttrDescription];
// Default data for keychain item.
[keychainItemData setObject:@"" forKey:(id)kSecValueData];
}
- (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert
{
// The assumption is that this method will be called with a properly populated dictionary
// containing all the right key/value pairs for a SecItem.
// Create a dictionary to return populated with the attributes and data.
NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
// Add the Generic Password keychain item class attribute.
[returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
// Convert the NSString to NSData to meet the requirements for the value type kSecValueData.
// This is where to store sensitive data that should be encrypted.
NSString *passwordString = [dictionaryToConvert objectForKey:(id)kSecValueData];
[returnDictionary setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
return returnDictionary;
}
- (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert
{
// The assumption is that this method will be called with a properly populated dictionary
// containing all the right key/value pairs for the UI element.
// Create a dictionary to return populated with the attributes and data.
NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert];
// Add the proper search key and class attribute.
[returnDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[returnDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
// Acquire the password data from the attributes.
NSData *passwordData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData) == noErr)
{
// Remove the search, class, and identifier key/value, we don't need them anymore.
[returnDictionary removeObjectForKey:(id)kSecReturnData];
// Add the password to the dictionary, converting from NSData to NSString.
NSString *password = [[[NSString alloc] initWithBytes:[passwordData bytes] length:[passwordData length]
encoding:NSUTF8StringEncoding] autorelease];
[returnDictionary setObject:password forKey:(id)kSecValueData];
}
else
{
// Don't do anything if nothing is found.
NSAssert(NO, @"Serious error, no matching item found in the keychain.\n");
}
[passwordData release];
return returnDictionary;
}
- (void)writeToKeychain
{
NSDictionary *attributes = NULL;
NSMutableDictionary *updateItem = NULL;
OSStatus result;
if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr)
{
// First we need the attributes from the Keychain.
updateItem = [NSMutableDictionary dictionaryWithDictionary:attributes];
// Second we need to add the appropriate search key/values.
[updateItem setObject:[genericPasswordQuery objectForKey:(id)kSecClass] forKey:(id)kSecClass];
// Lastly, we need to set up the updated attribute list being careful to remove the class.
NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData];
[tempCheck removeObjectForKey:(id)kSecClass];
#if TARGET_IPHONE_SIMULATOR
// Remove the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
//
// The access group attribute will be included in items returned by SecItemCopyMatching,
// which is why we need to remove it before updating the item.
[tempCheck removeObjectForKey:(id)kSecAttrAccessGroup];
#endif
// An implicit assumption is that you can only update a single item at a time.
result = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
NSAssert( result == noErr, @"Couldn't update the Keychain Item." );
}
else
{
// No previous item found; add the new one.
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL);
NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
}
}
@end
fileFormatVersion: 2
guid: d010bb3024e7b4850a4977997c8a8ae6
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: x86_64
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags: -fno-objc-arc
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:
//
// Data.h
// zhifuxitong
//
// Created by ssp on 13-6-27.
// Copyright (c) 2013年 ssp. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface UserData: NSObject
- (NSDictionary *)readPlist;
- (void)writeValue:(id)value Key:(NSString *)key;
- (void)initPlist;
- (void)removeValueForKey:(NSString *)key;
@end
fileFormatVersion: 2
guid: 2f7d4266dd90a4242b022ea268286ba0
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
#import "UserData.h"
@interface UserData ()
@property(nonatomic,strong)NSMutableDictionary *dataDic;
@end
@implementation UserData
-(NSDictionary *)readPlist
{
NSString *plistPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject] stringByAppendingPathComponent:@"UserData.plist"];
self.dataDic = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
return self.dataDic;
}
-(void)writeValue:(id)value Key:(NSString *)key
{
if (value == nil || key == nil) {
return;
}
NSString *plistPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject] stringByAppendingPathComponent:@"UserData.plist"];
self.dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
[self.dataDic setObject:value forKey:key];
[self.dataDic writeToFile:plistPath atomically:YES];
}
- (void)removeValueForKey:(id)key
{
NSString *plistPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject] stringByAppendingPathComponent:@"UserData.plist"];
self.dataDic = [[[NSMutableDictionary alloc]initWithContentsOfFile:plistPath]mutableCopy];
[self.dataDic removeObjectForKey:key];
[self.dataDic writeToFile:plistPath atomically:YES];
}
-(void)initPlist
{
NSString *plistPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject] stringByAppendingPathComponent:@"UserData.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
self.dataDic = [[NSMutableDictionary alloc] init];
[self.dataDic writeToFile:plistPath atomically:YES];
}
}
@end
fileFormatVersion: 2
guid: d833fefb78fb04806bb21bc28040a453
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 01c81d79ebee8482e899bc332140f056
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
//
// Native.h
// iosPlugins
//
// Created by os on 2020/4/10.
// Copyright © 2020 os. All rights reserved.
//
#include "UI/UnityViewControllerBase.h"
#include "UnityAppController+ViewHandling.h"
@interface Native:NSObject
@end
extern "C"
{
void _WechatLogin(char *appid, char *state, char *universalLink);
bool _isWechatInstalled();
void _ShareByIos(int type, char* url);
}
fileFormatVersion: 2
guid: 517b97a0c8d97412e872329c9a0e7e03
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// Native.mm
// iosPlugins
//
// Created by os on 2020/4/10.
// Copyright © 2020 os. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Native.h"
#import "Libraries/Plugins/iOS/WeChat/WXApi.h"
@interface Native()
@end
@implementation Native : NSObject
//判断是否安装微信
bool _isWechatInstalled()
{
return [WXApi isWXAppInstalled];
}
//微信登录
void _WechatLogin(char *appid, char *state, char *universalLink)
{
//向微信注册appid:填写自己微信开放平台的appid信息
NSString *weichatId = [NSString stringWithFormat:@"%s", appid];
NSString *UNIVERSAL_LINK = [NSString stringWithFormat:@"%s", universalLink];
[WXApi registerApp:weichatId universalLink:UNIVERSAL_LINK];
if([WXApi isWXAppInstalled] ==false)
{
NSLog(@"请先安装微信客户端");
return;
}
//登录
SendAuthReq* req = [[SendAuthReq alloc] init];
req.scope = @"snsapi_userinfo";
req.state = [NSString stringWithFormat:@"%s", state];
//[WXApi sendReq:req];
[WXApi sendReq:req completion:^(BOOL success) { NSLog(@"唤起微信:%@", success ? @"成功" : @"失败"); }];
}
//分享图片类型接口示例
//参数:type表示分享类型(0:分享某个好友聊天;1:分享到微信朋友圈)
//参数:url为图片本地地址,当然也可以用远程地址然后下载下来。
//具体分享其他类型(如文宇类型,音乐类型,视频类型可参考微信官网API)
void _ShareByIos(int type, char* url)
{
NSString *sharePicUrl = [NSString stringWithFormat:@"%s", url];
//UIImage *image = [UIImage imageNamed:sharePicUrl];
//NSData* imageData = UIImageJPEGRepresentation(image, 0.7);
WXImageObject *imageObject = [WXImageObject object];
imageObject.imageData = [NSData dataWithContentsOfFile:sharePicUrl];
WXMediaMessage *message = [WXMediaMessage message];
[message setThumbImage:[UIImage imageNamed:@"xzqShare.png"]];
message.mediaObject = imageObject;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.bText = NO;
req.message = message;
req.scene = type ==0? WXSceneSession : WXSceneTimeline;//0表示聊天,1,表示朋友圈
[WXApi sendReq:req completion:^(BOOL success) { NSLog(@"微信分享:%@", success ? @"成功" : @"失败"); }];
}
@end
fileFormatVersion: 2
guid: bd76b9bd0af0d4972bf48a162d64eed2
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// ViewController.h
// iosPlugins
//
// Created by os on 2020/4/10.
// Copyright © 2020 os. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "WXApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface ViewController : UIResponder<UIApplicationDelegate, WXApiDelegate>
+ (instancetype)shareManager;
-(void)sendUdid;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: 3ca9905b6a7184e59adb16669bfbe932
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// ViewController.m
// iosPlugins
//
// Created by os on 2020/4/10.
// Copyright © 2020 os. All rights reserved.
//
#import "ViewController.h"
#import "UserData.h"
#import "BGKeychainTool.h"
@implementation ViewController
+(instancetype) shareManager
{
static dispatch_once_t onceToken;
static ViewController *instance;
dispatch_once(&onceToken, ^{
instance = [[ViewController alloc] init];
});
return instance;
}
//微信发送请求到第三方应用时,会回调到该方法
-(void) onReq:(BaseReq *)req {}
//第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
-(void) onResp:(BaseResp *)resp
{
NSLog(@"微信响应");
//微信登录授权回调
if([resp isKindOfClass:[SendAuthResp class]])
{
SendAuthResp *temp = (SendAuthResp*)resp;
int errorCode = temp.errCode;
switch (errorCode) {//[NSUTF8StringEncoding temp.code]
case 0:
{
printf("登录成功-xcode");
NSLog(@"code %@",temp.code);
NSString *message = temp.code;
const char* codeInfo = [message cStringUsingEncoding:NSASCIIStringEncoding];
OnShowMessage(codeInfo);
break;
}
case -2:
printf("用户取消");
OnShowMessage("-2;用户取消");
break;
case -4:
printf("用户拒绝授权");
OnShowMessage("-4;用户取消");
break;
default:
printf("登录失败");
OnShowMessage("-1;登录失败");
break;
}
}
//微信分享授权回调
else if([resp isKindOfClass:[SendMessageToWXResp class]])
{
//0成功,-2是取消,其他异常
SendMessageToWXResp *rresp = (SendMessageToWXResp*)resp;
NSString *code = [NSString stringWithFormat:@"%d",rresp.errCode];
const char* codeInfo = [code cStringUsingEncoding:NSASCIIStringEncoding];
OnShareShowMessage(codeInfo);
}
}
//防止内存泄漏,崩溃,这里进行参数转换
char* MakeStringCopy(const char* string){
if(string == NULL){
return NULL;
}
char* res = (char*)malloc(strlen(string)+1);
strcpy(res, string);
return res;
}
//信息提示
void OnShowMessage(const char* msg)
{
UnitySendMessage("WxLogin","LoginCallBack",MakeStringCopy(msg));
}
void OnShareShowMessage(const char* msg)
{
UnitySendMessage("MainPanel","ShareCallBack",MakeStringCopy(msg));
}
-(void)sendUdid
{
UserData *data = [[UserData alloc] init];
NSDictionary *userDic = [data readPlist];
if ([BGKeychainTool getDeviceIDInKeychain].length > 0) {
NSString *udid = [BGKeychainTool getDeviceIDInKeychain];
const char *codeInfo = [udid cStringUsingEncoding:NSASCIIStringEncoding];
SendUDID(codeInfo);
}
if (userDic[@"idfa"]) {
NSString *idfaString = [NSString stringWithFormat:@"%@",userDic[@"idfa"]];
const char *codeInfo = [idfaString cStringUsingEncoding:NSASCIIStringEncoding];
SendIDFA(codeInfo);
}
const char *login = [@"login" cStringUsingEncoding:NSASCIIStringEncoding];
SendTouristLogin(login);
}
void SendUDID(const char *str)
{
UnitySendMessage("Main Camera","SetUDID", MakeStringCopy(str));
}
void SendIDFA(const char *str)
{
UnitySendMessage("Main Camera","SetIDFA", MakeStringCopy(str));
}
void SendTouristLogin(const char *str)
{
UnitySendMessage("Main Camera","TouristLogin", MakeStringCopy(str));
}
@end
fileFormatVersion: 2
guid: cbcb521cb7b7e45d4bddf9861d5217ec
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// WXApi.h
// 所有Api接口
//
// Created by Wechat on 12-2-28.
// Copyright (c) 2012年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "WXApiObject.h"
NS_ASSUME_NONNULL_BEGIN
#pragma mark - WXApiDelegate
/*! @brief 接收并处理来自微信终端程序的事件消息
*
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
*/
@protocol WXApiDelegate <NSObject>
@optional
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
*
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
* @param req 具体请求内容,是自动释放的
*/
- (void)onReq:(BaseReq*)req;
/*! @brief 发送一个sendReq后,收到微信的回应
*
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
* @param resp具体的回应内容,是自动释放的
*/
- (void)onResp:(BaseResp*)resp;
@end
#pragma mark - WXApiLogDelegate
@protocol WXApiLogDelegate <NSObject>
- (void)onLog:(NSString*)log logLevel:(WXLogLevel)level;
@end
#pragma mark - WXApi
/*! @brief 微信Api接口函数类
*
* 该类封装了微信终端SDK的所有接口
*/
@interface WXApi : NSObject
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
*
* 需要在每次启动第三方应用程序时调用。
* @attention 请保证在主线程中调用此函数
* @param appid 微信开发者ID
* @param universalLink 微信开发者Universal Link
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)registerApp:(NSString *)appid universalLink:(NSString *)universalLink;
/*! @brief 处理旧版微信通过URL启动App时传递的数据
*
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
* @param url 微信启动第三方应用时传递过来的URL
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
/*! @brief 处理微信通过Universal Link启动App时传递的数据
*
* 需要在 application:continueUserActivity:restorationHandler:中调用。
* @param userActivity 微信启动第三方应用时系统API传递过来的userActivity
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity delegate:(nullable id<WXApiDelegate>)delegate;
/*! @brief 检查微信是否已被用户安装
*
* @return 微信已安装返回YES,未安装返回NO。
*/
+ (BOOL)isWXAppInstalled;
/*! @brief 判断当前微信的版本是否支持OpenApi
*
* @return 支持返回YES,不支持返回NO。
*/
+ (BOOL)isWXAppSupportApi;
/*! @brief 获取微信的itunes安装地址
*
* @return 微信的安装地址字符串。
*/
+ (NSString *)getWXAppInstallUrl;
/*! @brief 获取当前微信SDK的版本号
*
* @return 返回当前微信SDK的版本号
*/
+ (NSString *)getApiVersion;
/*! @brief 打开微信
*
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)openWXApp;
/*! @brief 发送请求到微信,等待微信返回onResp
*
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
* SendAuthReq、SendMessageToWXReq、PayReq等。
* @param req 具体的发送请求。
* @param completion 调用结果回调block
*/
+ (void)sendReq:(BaseReq *)req completion:(void (^ __nullable)(BOOL success))completion;
/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
*
* 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
* GetMessageFromWXResp、ShowMessageFromWXResp等。
* @param resp 具体的应答内容
* @param completion 调用结果回调block
*/
+ (void)sendResp:(BaseResp*)resp completion:(void (^ __nullable)(BOOL success))completion;
/*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
*
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
* @param req 具体的发送请求。
* @param viewController 当前界面对象。
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
* @param completion 调用结果回调block
*/
+ (void)sendAuthReq:(SendAuthReq *)req viewController:(UIViewController*)viewController delegate:(nullable id<WXApiDelegate>)delegate completion:(void (^ __nullable)(BOOL success))completion;
/*! @brief 测试函数,用于排查当前App通过Universal Link方式分享到微信的流程
注意1: 调用自检函数之前必须要先调用registerApp:universalLink接口, 并确认调用成功
注意2: 自检过程中会有Log产生,可以先调用startLogByLevel函数,根据Log排查问题
注意3: 会多次回调block
注意4: 仅用于新接入SDK时调试使用,请勿在正式环境的调用
*
* 当completion回调的step为WXULCheckStepFinal时,表示检测通过,Universal Link接入成功
* @param completion 回调Block
*/
+ (void)checkUniversalLinkReady:(nonnull WXCheckULCompletion)completion;
/*! @brief WXApi的成员函数,接受微信的log信息。byBlock
注意1:SDK会强引用这个block,注意不要导致内存泄漏,注意不要导致内存泄漏
注意2:调用过一次startLog by block之后,如果再调用一次任意方式的startLoad,会释放上一次logBlock,不再回调上一个logBlock
*
* @param level 打印log的级别
* @param logBlock 打印log的回调block
*/
+ (void)startLogByLevel:(WXLogLevel)level logBlock:(WXLogBolock)logBlock;
/*! @brief WXApi的成员函数,接受微信的log信息。byDelegate
注意1:sdk会弱引用这个delegate,这里可加任意对象为代理,不需要与WXApiDelegate同一个对象
注意2:调用过一次startLog by delegate之后,再调用一次任意方式的startLoad,不会再回调上一个logDelegate对象
* @param level 打印log的级别
* @param logDelegate 打印log的回调代理,
*/
+ (void)startLogByLevel:(WXLogLevel)level logDelegate:(id<WXApiLogDelegate>)logDelegate;
/*! @brief 停止打印log,会清理block或者delegate为空,释放block
* @param
*/
+ (void)stopLog;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: accad33fb5a094ba7a0889f3420e2a37
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// MMApiObject.h
// Api对象,包含所有接口和对象数据定义
//
// Created by Wechat on 12-2-28.
// Copyright (c) 2012年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/*! @brief 错误码
*
*/
enum WXErrCode {
WXSuccess = 0, /**< 成功 */
WXErrCodeCommon = -1, /**< 普通错误类型 */
WXErrCodeUserCancel = -2, /**< 用户点击取消并返回 */
WXErrCodeSentFail = -3, /**< 发送失败 */
WXErrCodeAuthDeny = -4, /**< 授权失败 */
WXErrCodeUnsupport = -5, /**< 微信不支持 */
};
/*! @brief 请求发送场景
*
*/
enum WXScene {
WXSceneSession = 0, /**< 聊天界面 */
WXSceneTimeline = 1, /**< 朋友圈 */
WXSceneFavorite = 2, /**< 收藏 */
WXSceneSpecifiedSession = 3, /**< 指定联系人 */
};
enum WXAPISupport {
WXAPISupportSession = 0,
};
/*! @brief 跳转profile类型
*
*/
enum WXBizProfileType {
WXBizProfileType_Normal = 0, //**< 普通公众号 */
WXBizProfileType_Device = 1, //**< 硬件公众号 */
};
/*! @brief 分享小程序类型
*
*/
typedef NS_ENUM(NSUInteger, WXMiniProgramType) {
WXMiniProgramTypeRelease = 0, //**< 正式版 */
WXMiniProgramTypeTest = 1, //**< 开发版 */
WXMiniProgramTypePreview = 2, //**< 体验版 */
};
/*! @brief 跳转mp网页类型
*
*/
enum WXMPWebviewType {
WXMPWebviewType_Ad = 0, /**< 广告网页 **/
};
/*! @brief log的级别
*
*/
typedef NS_ENUM(NSInteger,WXLogLevel) {
WXLogLevelNormal = 0, // 打印日常的日志
WXLogLevelDetail = 1, // 打印详细的日志
};
/*! @brief 打印回调的block
*
*/
typedef void(^WXLogBolock)(NSString *log);
/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),检查步骤枚举值
*
* WXULCheckStepParams 参数检测
* WXULCheckStepSystemVersion 当前系统版本检测
* WXULCheckStepWechatVersion 微信客户端版本检测
* WXULCheckStepSDKInnerOperation 微信SDK内部操作检测
* WXULCheckStepLaunchWechat App拉起微信检测
* WXULCheckStepBackToCurrentApp 由微信返回当前App检测
* WXULCheckStepFinal 最终结果
*/
typedef NS_ENUM(NSInteger, WXULCheckStep)
{
WXULCheckStepParams,
WXULCheckStepSystemVersion,
WXULCheckStepWechatVersion,
WXULCheckStepSDKInnerOperation,
WXULCheckStepLaunchWechat,
WXULCheckStepBackToCurrentApp,
WXULCheckStepFinal,
};
#pragma mark - WXCheckULStepResult
/*! @brief 该类为微信Universal Link检测函数结果类
*
*/
@interface WXCheckULStepResult : NSObject
/** 是否成功 */
@property(nonatomic, assign) BOOL success;
/** 当前错误信息 */
@property(nonatomic, strong) NSString* errorInfo;
/** 修正建议 */
@property(nonatomic, strong) NSString* suggestion;
- (instancetype)initWithCheckResult:(BOOL)success errorInfo:(nullable NSString*)errorInfo suggestion:(nullable NSString*)suggestion;
@end
/*! @brief 微信Universal Link检查函数 (WXApi#checkUniversalLinkReady:),回调Block
*
* @param step 当前检测步骤
* @param result 检测结果
*/
typedef void(^WXCheckULCompletion)(WXULCheckStep step, WXCheckULStepResult* result);
#pragma mark - BaseReq
/*! @brief 该类为微信终端SDK所有请求类的基类
*
*/
@interface BaseReq : NSObject
/** 请求类型 */
@property (nonatomic, assign) int type;
/** 由用户微信号和AppID组成的唯一标识,需要校验微信用户是否换号登录时填写*/
@property (nonatomic, copy) NSString *openID;
@end
#pragma mark - BaseResp
/*! @brief 该类为微信终端SDK所有响应类的基类
*
*/
@interface BaseResp : NSObject
/** 错误码 */
@property (nonatomic, assign) int errCode;
/** 错误提示字符串 */
@property (nonatomic, copy) NSString *errStr;
/** 响应类型 */
@property (nonatomic, assign) int type;
@end
#pragma mark - WXMediaMessage
@class WXMediaMessage;
#pragma mark - SendAuthReq
/*! @brief 第三方程序向微信终端请求认证的消息结构
*
* 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,
* 向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
* @see SendAuthResp
*/
@interface SendAuthReq : BaseReq
/** 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。微信终端处理完后会向第三方程序发送一个处理结果。
* @see SendAuthResp
* @note scope字符串长度不能超过1K
*/
@property (nonatomic, copy) NSString *scope;
/** 第三方程序本身用来标识其请求的唯一性,最后跳转回第三方程序时,由微信终端回传。
* @note state字符串长度不能超过1K
*/
@property (nonatomic, copy) NSString *state;
@end
#pragma mark - SendAuthResp
/*! @brief 微信处理完第三方程序的认证和权限申请后向第三方程序回送的处理结果。
*
* 第三方程序要向微信申请认证,并请求某些权限,需要调用WXApi的sendReq成员函数,向微信终端发送一个SendAuthReq消息结构。
* 微信终端处理完后会向第三方程序发送一个SendAuthResp。
* @see onResp
*/
@interface SendAuthResp : BaseResp
@property (nonatomic, copy, nullable) NSString *code;
/** 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传
* @note state字符串长度不能超过1K
*/
@property (nonatomic, copy, nullable) NSString *state;
@property (nonatomic, copy, nullable) NSString *lang;
@property (nonatomic, copy, nullable) NSString *country;
@end
#pragma mark - SendMessageToWXReq
/*! @brief 第三方程序发送消息至微信终端程序的消息结构体
*
* 第三方程序向微信发送信息需要传入SendMessageToWXReq结构体,信息类型包括文本消息和多媒体消息,
* 分别对应于text和message成员。调用该方法后,微信处理完信息会向第三方程序发送一个处理结果。
* @see SendMessageToWXResp
*/
@interface SendMessageToWXReq : BaseReq
/** 发送消息的文本内容
* @note 文本长度必须大于0且小于10K
*/
@property (nonatomic, copy) NSString *text;
/** 发送消息的多媒体内容
* @see WXMediaMessage
*/
@property (nonatomic, strong) WXMediaMessage *message;
/** 发送消息的类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
@property (nonatomic, assign) BOOL bText;
/** 发送的目标场景,可以选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)。 默认发送到会话。
* @see WXScene
*/
@property (nonatomic, assign) int scene;
/** 指定发送消息的人
* @note WXSceneSpecifiedSession时有效
*/
@property (nonatomic, copy, nullable) NSString *toUserOpenId;
@end
#pragma mark - SendMessageToWXResp
/*! @brief 微信终端向第三方程序返回的SendMessageToWXReq处理结果。
*
* 第三方程序向微信终端发送SendMessageToWXReq后,微信发送回来的处理结果,该结果用SendMessageToWXResp表示。
*/
@interface SendMessageToWXResp : BaseResp
@property(nonatomic, copy) NSString *lang;
@property(nonatomic, copy) NSString *country;
@end
#pragma mark - GetMessageFromWXReq
/*! @brief 微信终端向第三方程序请求提供内容的消息结构体。
*
* 微信终端向第三方程序请求提供内容,微信终端会向第三方程序发送GetMessageFromWXReq消息结构体,
* 需要第三方程序调用sendResp返回一个GetMessageFromWXResp消息结构体。
*/
@interface GetMessageFromWXReq : BaseReq
@property (nonatomic, strong) NSString *lang;
@property (nonatomic, strong) NSString *country;
@end
#pragma mark - GetMessageFromWXResp
/*! @brief 微信终端向第三方程序请求提供内容,第三方程序向微信终端返回的消息结构体。
*
* 微信终端向第三方程序请求提供内容,第三方程序调用sendResp向微信终端返回一个GetMessageFromWXResp消息结构体。
*/
@interface GetMessageFromWXResp : BaseResp
/** 向微信终端提供的文本内容
@note 文本长度必须大于0且小于10K
*/
@property (nonatomic, strong) NSString *text;
/** 向微信终端提供的多媒体内容。
* @see WXMediaMessage
*/
@property (nonatomic, strong) WXMediaMessage *message;
/** 向微信终端提供内容的消息类型,包括文本消息和多媒体消息两种,两者只能选择其一,不能同时发送文本和多媒体消息 */
@property (nonatomic, assign) BOOL bText;
@end
#pragma mark - ShowMessageFromWXReq
/*! @brief 微信通知第三方程序,要求第三方程序显示的消息结构体。
*
* 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
* 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
*/
@interface ShowMessageFromWXReq : BaseReq
/** 微信终端向第三方程序发送的要求第三方程序处理的多媒体内容
* @see WXMediaMessage
*/
@property (nonatomic, strong) WXMediaMessage *message;
@property (nonatomic, copy) NSString *lang;
@property (nonatomic, copy) NSString *country;
@end
#pragma mark - ShowMessageFromWXResp
/*! @brief 微信通知第三方程序,要求第三方程序显示或处理某些消息,第三方程序处理完后向微信终端发送的处理结果。
*
* 微信需要通知第三方程序显示或处理某些内容时,会向第三方程序发送ShowMessageFromWXReq消息结构体。
* 第三方程序处理完内容后调用sendResp向微信终端发送ShowMessageFromWXResp。
*/
@interface ShowMessageFromWXResp : BaseResp
@end
#pragma mark - LaunchFromWXReq
/*! @brief 微信终端打开第三方程序携带的消息结构体
*
* 微信向第三方发送的结构体,第三方不需要返回
*/
@interface LaunchFromWXReq : BaseReq
@property (nonatomic, strong) WXMediaMessage *message;
@property (nonatomic, copy) NSString *lang;
@property (nonatomic, copy) NSString *country;
@end
#pragma mark - OpenWebviewReq
/* ! @brief 第三方通知微信启动内部浏览器,打开指定网页
*
* 第三方通知微信启动内部浏览器,打开指定Url对应的网页
*/
@interface OpenWebviewReq : BaseReq
/** 需要打开的网页对应的Url
* @attention 长度不能超过1024
*/
@property(nonatomic, copy) NSString *url;
@end
#pragma mark - OpenWebviewResp
/*! @brief 微信终端向第三方程序返回的OpenWebviewReq处理结果
*
* 第三方程序向微信终端发送OpenWebviewReq后,微信发送回来的处理结果,该结果用OpenWebviewResp表示
*/
@interface OpenWebviewResp : BaseResp
@end
#pragma mark - WXOpenBusinessWebViewReq
/*! @brief 第三方通知微信启动内部浏览器,打开指定业务的网页
*
*
*/
@interface WXOpenBusinessWebViewReq : BaseReq
/** 网页业务类型
* @attention
*/
@property (nonatomic, assign) UInt32 businessType;
/** 网页业务参数
* @attention
*/
@property (nonatomic, strong, nullable) NSDictionary *queryInfoDic;
@end
#pragma mark - WXOpenBusinessWebViewResp
/*! @brief 微信终端向第三方程序返回的WXOpenBusinessWebViewResp处理结果。
*
* 第三方程序向微信终端发送WXOpenBusinessWebViewReq后,微信发送回来的处理结果,该结果用WXOpenBusinessWebViewResp表示。
*/
@interface WXOpenBusinessWebViewResp : BaseResp
/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
* @attention 长度不能超过2k
*/
@property (nonatomic, copy) NSString *result;
/** 网页业务类型
* @attention
*/
@property (nonatomic, assign) UInt32 businessType;
@end
#pragma mark - OpenRankListReq
/* ! @brief 第三方通知微信,打开硬件排行榜
*
* 第三方通知微信,打开硬件排行榜
*/
@interface OpenRankListReq : BaseReq
@end
#pragma mark - OpenRanklistResp
/*! @brief 微信终端向第三方程序返回的OpenRankListReq处理结果。
*
* 第三方程序向微信终端发送OpenRankListReq后,微信发送回来的处理结果,该结果用OpenRankListResp表示。
*/
@interface OpenRankListResp : BaseResp
@end
#pragma mark - WXCardItem
@interface WXCardItem : NSObject
/** 卡id
* @attention 长度不能超过1024字节
*/
@property (nonatomic, copy) NSString *cardId;
/** ext信息
* @attention 长度不能超过2024字节
*/
@property (nonatomic, copy, nullable) NSString *extMsg;
/**
* @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
*/
@property (nonatomic, assign) UInt32 cardState;
/**
* @attention req不需要填,chooseCard返回的。
*/
@property (nonatomic, copy) NSString *encryptCode;
/**
* @attention req不需要填,chooseCard返回的。
*/
@property (nonatomic, copy) NSString *appID;
@end;
#pragma mark - WXInvoiceItem
@interface WXInvoiceItem : NSObject
/** 卡id
* @attention 长度不能超过1024字节
*/
@property (nonatomic, copy) NSString *cardId;
/** ext信息
* @attention 长度不能超过2024字节
*/
@property (nonatomic, copy, nullable) NSString *extMsg;
/**
* @attention 卡的状态,req不需要填。resp:0为未添加,1为已添加。
*/
@property (nonatomic, assign) UInt32 cardState;
/**
* @attention req不需要填,chooseCard返回的。
*/
@property (nonatomic, copy) NSString *encryptCode;
/**
* @attention req不需要填,chooseCard返回的。
*/
@property (nonatomic, copy) NSString *appID;
@end
#pragma mark - AddCardToWXCardPackageReq
/* ! @brief 请求添加卡券至微信卡包
*
*/
@interface AddCardToWXCardPackageReq : BaseReq
/** 卡列表
* @attention 个数不能超过40个 类型WXCardItem
*/
@property (nonatomic, strong) NSArray *cardAry;
@end
#pragma mark - AddCardToWXCardPackageResp
/** ! @brief 微信返回第三方添加卡券结果
*
*/
@interface AddCardToWXCardPackageResp : BaseResp
/** 卡列表
* @attention 个数不能超过40个 类型WXCardItem
*/
@property (nonatomic, strong) NSArray *cardAry;
@end
#pragma mark - WXChooseCardReq
/* ! @brief 请求从微信选取卡券
*
*/
@interface WXChooseCardReq : BaseReq
@property (nonatomic, copy) NSString *appID;
@property (nonatomic, assign) UInt32 shopID;
@property (nonatomic, assign) UInt32 canMultiSelect;
@property (nonatomic, copy) NSString *cardType;
@property (nonatomic, copy) NSString *cardTpID;
@property (nonatomic, copy) NSString *signType;
@property (nonatomic, copy) NSString *cardSign;
@property (nonatomic, assign) UInt32 timeStamp;
@property (nonatomic, copy) NSString *nonceStr;
@end
#pragma mark - WXChooseCardResp
/** ! @brief 微信返回第三方请求选择卡券结果
*
*/
@interface WXChooseCardResp : BaseResp
@property (nonatomic, strong ) NSArray* cardAry;
@end
#pragma mark - WXChooseInvoiceReq
/* ! @brief 请求从微信选取发票
*
*/
@interface WXChooseInvoiceReq : BaseReq
@property (nonatomic, copy) NSString *appID;
@property (nonatomic, assign) UInt32 shopID;
@property (nonatomic, copy) NSString *signType;
@property (nonatomic, copy) NSString *cardSign;
@property (nonatomic, assign) UInt32 timeStamp;
@property (nonatomic, copy) NSString *nonceStr;
@end
#pragma mark - WXChooseInvoiceResp
/** ! @brief 微信返回第三方请求选择发票结果
*
*/
@interface WXChooseInvoiceResp : BaseResp
@property (nonatomic, strong) NSArray* cardAry;
@end
#pragma mark - WXSubscriptionReq
@interface WXSubscribeMsgReq : BaseReq
@property (nonatomic, assign) UInt32 scene;
@property (nonatomic, copy) NSString *templateId;
@property (nonatomic, copy, nullable) NSString *reserved;
@end
#pragma mark - WXSubscriptionReq
@interface WXSubscribeMsgResp : BaseResp
@property (nonatomic, copy) NSString *templateId;
@property (nonatomic, assign) UInt32 scene;
@property (nonatomic, copy) NSString *action;
@property (nonatomic, copy) NSString *reserved;
@property (nonatomic, copy, nullable) NSString *openId;
@end
#pragma mark - WXSubscribeMiniProgramMsg
/** ! @brief 第三方请求订阅小程序消息
*
*/
@interface WXSubscribeMiniProgramMsgReq : BaseReq
@property (nonatomic, copy) NSString *miniProgramAppid;
@end
#pragma mark - WXSubscriptionReq
@interface WXSubscribeMiniProgramMsgResp : BaseResp
@property(nonatomic, copy) NSString *openId; // 小程序openid
@property(nonatomic, copy) NSString *unionId; // unionId
@property(nonatomic, copy) NSString *nickName; // 用户昵称
@end
#pragma mark - WXinvoiceAuthInsertReq
@interface WXInvoiceAuthInsertReq : BaseReq
@property (nonatomic, copy) NSString *urlString;
@end
#pragma mark - WXinvoiceAuthInsertResp
@interface WXInvoiceAuthInsertResp : BaseResp
@property (nonatomic, copy) NSString *wxOrderId;
@end
#pragma mark - WXMediaMessage
/*! @brief 多媒体消息结构体
*
* 用于微信终端和第三方程序之间传递消息的多媒体消息内容
*/
@interface WXMediaMessage : NSObject
+ (WXMediaMessage *)message;
/** 标题
* @note 长度不能超过512字节
*/
@property (nonatomic, copy) NSString *title;
/** 描述内容
* @note 长度不能超过1K
*/
@property (nonatomic, copy) NSString *description;
/** 缩略图数据
* @note 大小不能超过64K
*/
@property (nonatomic, strong, nullable) NSData *thumbData;
/**
* @note 长度不能超过64字节
*/
@property (nonatomic, copy, nullable) NSString *mediaTagName;
/**
*
*/
@property (nonatomic, copy, nullable) NSString *messageExt;
@property (nonatomic, copy, nullable) NSString *messageAction;
/**
* 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。
*/
@property (nonatomic, strong) id mediaObject;
/*! @brief 设置消息缩略图的方法
*
* @param image 缩略图
* @note 大小不能超过64K
*/
- (void)setThumbImage:(UIImage *)image;
@end
#pragma mark - WXImageObject
/*! @brief 多媒体消息中包含的图片数据对象
*
* 微信终端和第三方程序之间传递消息中包含的图片数据对象。
* @note imageData成员不能为空
* @see WXMediaMessage
*/
@interface WXImageObject : NSObject
/*! @brief 返回一个WXImageObject对象
*
* @note 返回的WXImageObject对象是自动释放的
*/
+ (WXImageObject *)object;
/** 图片真实数据内容
* @note 大小不能超过25M
*/
@property (nonatomic, strong) NSData *imageData;
@end
#pragma mark - WXMusicObject
/*! @brief 多媒体消息中包含的音乐数据对象
*
* 微信终端和第三方程序之间传递消息中包含的音乐数据对象。
* @note musicUrl和musicLowBandUrl成员不能同时为空。
* @see WXMediaMessage
*/
@interface WXMusicObject : NSObject
/*! @brief 返回一个WXMusicObject对象
*
* @note 返回的WXMusicObject对象是自动释放的
*/
+ (WXMusicObject *)object;
/** 音乐网页的url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *musicUrl;
/** 音乐lowband网页的url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *musicLowBandUrl;
/** 音乐数据url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *musicDataUrl;
/**音乐lowband数据url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *musicLowBandDataUrl;
/**音乐封面图Url
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *songAlbumUrl;
/**歌词信息 LRC格式
* @note 长度不能超过32K
*/
@property (nonatomic, copy, nullable) NSString *songLyric;
@end
#pragma mark - WXMusicVideoObject
@interface WXMusicVideoObject : NSObject
/*! @brief 返回一个WXMusicVideoObject对象
*
* @note 返回的WXMusicVideoObject对象是自动释放的
*/
+ (WXMusicVideoObject *)object;
/** 音乐网页的url地址
* @note 长度不能超过10K,不能为空
*/
@property (nonatomic, copy) NSString *musicUrl;
/** 音乐数据url地址
* @note 长度不能超过10K,不能为空
*/
@property (nonatomic, copy) NSString *musicDataUrl;
/**歌手名
* @note 长度不能超过1k,不能为空
*/
@property (nonatomic, copy) NSString *singerName;
/**
* @note 音乐时长, 单位毫秒
*/
@property (nonatomic, assign) UInt32 duration;
/**歌词信息 LRC格式
* @note 长度不能超过32K
*/
@property (nonatomic, copy) NSString *songLyric;
/**高清封面图
* @note 大小不能超过1M
*/
@property (nonatomic, strong) NSData *hdAlbumThumbData;
/**音乐专辑名称
* @note 长度不能超过1k
*/
@property (nonatomic, copy, nullable) NSString *albumName;
/**音乐流派
* @note 长度不能超过1k
*/
@property (nonatomic, copy, nullable) NSString *musicGenre;
/**发行时间
* @note Unix时间戳,单位为秒
*/
@property (nonatomic, assign) UInt64 issueDate;
/**音乐标识符
* @note 长度不能超过1K,从微信跳回应用时会带上
*/
@property (nonatomic, copy, nullable) NSString *identification;
@end
#pragma mark - WXVideoObject
/*! @brief 多媒体消息中包含的视频数据对象
*
* 微信终端和第三方程序之间传递消息中包含的视频数据对象。
* @note videoUrl和videoLowBandUrl不能同时为空。
* @see WXMediaMessage
*/
@interface WXVideoObject : NSObject
/*! @brief 返回一个WXVideoObject对象
*
* @note 返回的WXVideoObject对象是自动释放的
*/
+ (WXVideoObject *)object;
/** 视频网页的url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *videoUrl;
/** 视频lowband网页的url地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *videoLowBandUrl;
@end
#pragma mark - WXWebpageObject
/*! @brief 多媒体消息中包含的网页数据对象
*
* 微信终端和第三方程序之间传递消息中包含的网页数据对象。
* @see WXMediaMessage
*/
@interface WXWebpageObject : NSObject
/*! @brief 返回一个WXWebpageObject对象
*
* @note 返回的WXWebpageObject对象是自动释放的
*/
+ (WXWebpageObject *)object;
/** 网页的url地址
* @note 不能为空且长度不能超过10K
*/
@property (nonatomic, copy) NSString *webpageUrl;
@end
#pragma mark - WXAppExtendObject
/*! @brief 多媒体消息中包含的App扩展数据对象
*
* 第三方程序向微信终端发送包含WXAppExtendObject的多媒体消息,
* 微信需要处理该消息时,会调用该第三方程序来处理多媒体消息内容。
* @note url,extInfo和fileData不能同时为空
* @see WXMediaMessage
*/
@interface WXAppExtendObject : NSObject
/*! @brief 返回一个WXAppExtendObject对象
*
* @note 返回的WXAppExtendObject对象是自动释放的
*/
+ (WXAppExtendObject *)object;
/** 若第三方程序不存在,微信终端会打开该url所指的App下载地址
* @note 长度不能超过10K
*/
@property (nonatomic, copy) NSString *url;
/** 第三方程序自定义简单数据,微信终端会回传给第三方程序处理
* @note 长度不能超过2K
*/
@property (nonatomic, copy, nullable) NSString *extInfo;
/** App文件数据,该数据发送给微信好友,微信好友需要点击后下载数据,微信终端会回传给第三方程序处理
* @note 大小不能超过10M
*/
@property (nonatomic, strong, nullable) NSData *fileData;
@end
#pragma mark - WXEmoticonObject
/*! @brief 多媒体消息中包含的表情数据对象
*
* 微信终端和第三方程序之间传递消息中包含的表情数据对象。
* @see WXMediaMessage
*/
@interface WXEmoticonObject : NSObject
/*! @brief 返回一个WXEmoticonObject对象
*
* @note 返回的WXEmoticonObject对象是自动释放的
*/
+ (WXEmoticonObject *)object;
/** 表情真实数据内容
* @note 大小不能超过10M
*/
@property (nonatomic, strong) NSData *emoticonData;
@end
#pragma mark - WXFileObject
/*! @brief 多媒体消息中包含的文件数据对象
*
* @see WXMediaMessage
*/
@interface WXFileObject : NSObject
/*! @brief 返回一个WXFileObject对象
*
* @note 返回的WXFileObject对象是自动释放的
*/
+ (WXFileObject *)object;
/** 文件后缀名
* @note 长度不超过64字节
*/
@property (nonatomic, copy) NSString *fileExtension;
/** 文件真实数据内容
* @note 大小不能超过10M
*/
@property (nonatomic, strong) NSData *fileData;
@end
#pragma mark - WXLocationObject
/*! @brief 多媒体消息中包含的地理位置数据对象
*
* 微信终端和第三方程序之间传递消息中包含的地理位置数据对象。
* @see WXMediaMessage
*/
@interface WXLocationObject : NSObject
/*! @brief 返回一个WXLocationObject对象
*
* @note 返回的WXLocationObject对象是自动释放的
*/
+ (WXLocationObject *)object;
/** 地理位置信息
* @note 经纬度
*/
@property (nonatomic, assign) double lng; //经度
@property (nonatomic, assign) double lat; //纬度
@end
#pragma mark - WXTextObject
/*! @brief 多媒体消息中包含的文本数据对象
*
* 微信终端和第三方程序之间传递消息中包含的文本数据对象。
* @see WXMediaMessage
*/
@interface WXTextObject : NSObject
/*! @brief 返回一个WXTextObject对象
*
* @note 返回的WXTextObject对象是自动释放的
*/
+ (WXTextObject *)object;
/** 地理位置信息
* @note 文本内容
*/
@property (nonatomic, copy) NSString *contentText;
@end
#pragma mark - WXMiniProgramObject
@interface WXMiniProgramObject : NSObject
/*! @brief WXMiniProgramObject对象
*
* @note 返回的WXMiniProgramObject对象是自动释放的
*/
+ (WXMiniProgramObject *)object;
/** 低版本网页链接
* @attention 长度不能超过1024字节
*/
@property (nonatomic, copy) NSString *webpageUrl;
/** 小程序username */
@property (nonatomic, copy) NSString *userName;
/** 小程序页面的路径
* @attention 不填默认拉起小程序首页
*/
@property (nonatomic, copy, nullable) NSString *path;
/** 小程序新版本的预览图
* @attention 大小不能超过128k
*/
@property (nonatomic, strong, nullable) NSData *hdImageData;
/** 是否使用带 shareTicket 的转发 */
@property (nonatomic, assign) BOOL withShareTicket;
/** 分享小程序的版本
* @attention (正式,开发,体验)
*/
@property (nonatomic, assign) WXMiniProgramType miniProgramType;
/** 是否禁用转发 */
@property (nonatomic, assign) BOOL disableForward;
@property (nonatomic, assign) BOOL isUpdatableMessage;
@property (nonatomic, assign) BOOL isSecretMessage;
/** 业务所需的额外信息 */
@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
@end
#pragma mark - WXGameLiveObject
/*! @brief WXGameLiveObject对象
*
* @note 游戏直播消息类型
*/
@interface WXGameLiveObject : NSObject
+ (WXGameLiveObject *)object;
/** 业务所需的额外信息 */
@property (nonatomic, strong, nullable) NSDictionary *extraInfoDic;
@end
#pragma mark - WXLaunchMiniProgramReq
/*! @brief WXLaunchMiniProgramReq对象, 可实现通过sdk拉起微信小程序
*
* @note 返回的WXLaunchMiniProgramReq对象是自动释放的
*/
@interface WXLaunchMiniProgramReq : BaseReq
+ (WXLaunchMiniProgramReq *)object;
/** 小程序username */
@property (nonatomic, copy) NSString *userName;
/** 小程序页面的路径
* @attention 不填默认拉起小程序首页
*/
@property (nonatomic, copy, nullable) NSString *path;
/** 分享小程序的版本
* @attention (正式,开发,体验)
*/
@property (nonatomic, assign) WXMiniProgramType miniProgramType;
/** ext信息
* @attention json格式
*/
@property (nonatomic, copy, nullable) NSString *extMsg;
/** extDic
* @attention 字典,可存放图片等比较大的数据
*/
@property (nonatomic, copy, nullable) NSDictionary *extDic;
@end
#pragma mark - WXLaunchMiniProgramResp
/*! @brief 微信终端向第三方程序返回的WXLaunchMiniProgramReq处理结果。
*
* 第三方程序向微信终端发送WXLaunchMiniProgramReq后,微信发送回来的处理结果,该结果用WXLaunchMiniProgramResp表示。
*/
@interface WXLaunchMiniProgramResp : BaseResp
@property (nonatomic, copy, nullable) NSString *extMsg;
@end
#pragma mark - WXOpenBusinessViewReq
/*! @brief WXOpenBusinessViewReq对象, 可实现第三方通知微信启动,打开业务页面
*
* @note 返回的WXOpenBusinessViewReq对象是自动释放的
*/
@interface WXOpenBusinessViewReq : BaseReq
+ (WXOpenBusinessViewReq *)object;
/** 业务类型
*/
@property (nonatomic, copy) NSString *businessType;
/** 业务参数
*/
@property (nonatomic, copy, nullable) NSString *query;
/** ext信息
* @note 选填,json格式
*/
@property (nonatomic, copy, nullable) NSString *extInfo;
/** extData数据
* @note
*/
@property (nonatomic, strong, nullable) NSData *extData;
@end
@interface WXOpenBusinessViewResp : BaseResp
/** 业务类型
*/
@property (nonatomic, copy) NSString *businessType;
/** 业务返回数据
*/
@property (nonatomic, copy, nullable) NSString *extMsg;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: 4804ab27a6fcc42e6a0b76e4f28ba140
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// WechatAuthSDK.h
// WechatAuthSDK
//
// Created by 李凯 on 13-11-29.
// Copyright (c) 2013年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
enum AuthErrCode {
WechatAuth_Err_Ok = 0, //Auth成功
WechatAuth_Err_NormalErr = -1, //普通错误
WechatAuth_Err_NetworkErr = -2, //网络错误
WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
WechatAuth_Err_Cancel = -4, //用户取消授权
WechatAuth_Err_Timeout = -5, //超时
};
@protocol WechatAuthAPIDelegate<NSObject>
@optional
- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
- (void)onQrcodeScanned; //二维码被扫描
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
@end
@interface WechatAuthSDK : NSObject{
NSString *_sdkVersion;
__weak id<WechatAuthAPIDelegate> _delegate;
}
@property(nonatomic, weak, nullable) id<WechatAuthAPIDelegate> delegate;
@property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
/*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
*
* @param appId 微信开发者ID
* @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
* @param timeStamp 时间戳
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
* @param signature 签名
* @param schemeData 会在扫码后拼在scheme后
* @return 成功返回YES,失败返回NO
注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
*/
- (BOOL)Auth:(NSString *)appId
nonceStr:(NSString *)nonceStr
timeStamp:(NSString *)timeStamp
scope:(NSString *)scope
signature:(NSString *)signature
schemeData:(nullable NSString *)schemeData;
/*! @brief 暂停登录请求
*
* @return 成功返回YES,失败返回NO。
*/
- (BOOL)StopAuth;
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: 9fcd68daa4077463cbac8118038cd87c
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 2b45e75b1af0a4dafbee5aee61b24410
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7d5d495f194394494bbcd4b7ff0584a8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
//
// WKWebViewController.h
// Gardening
//
// Created by GY.Z on 2021/1/4.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WKWebViewController : UIViewController
@property (nonatomic, copy) NSString * url;
@property (nonatomic, copy) NSString * webTitle;
@property (nonatomic, assign) bool showNav;
@property (nonatomic, assign) NSInteger countDown;
@property (nonatomic, copy) NSString * details;
@property (nonatomic, strong) NSMutableDictionary * adsDict;
@property (nonatomic, copy) void(^dismissCallBack)(void);
@end
NS_ASSUME_NONNULL_END
fileFormatVersion: 2
guid: 4e145fed4a87e4b53b7de315c9181cc5
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
//
// WKWebViewController.m
// Gardening
//
// Created by GY.Z on 2021/1/4.
//
#import "WKWebViewController.h"
#import <WebKit/WebKit.h>
@interface WKWebViewController ()<WKUIDelegate, WKNavigationDelegate>
#define KWidth [UIScreen mainScreen].bounds.size.width
#define KHeight [UIScreen mainScreen].bounds.size.height
#define UIColorFromRGBA(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
#define UIColorFromRGB(r,g,b) UIColorFromRGBA(r,g,b,1.0)
#define WEAKSELF __weak __typeof(self) weakSelf = self;
@property (nonatomic, strong) WKWebView * webView;
@property (nonatomic, strong) NSMutableURLRequest *requestW;
@property (nonatomic, strong) UIProgressView *progressView;
@end
@implementation WKWebViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Do any additional setup after loading the view.
self.navigationItem.title = self.webTitle;
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc] init];
// 视频页面播放支持
webViewConfig.allowsAirPlayForMediaPlayback = YES;
webViewConfig.allowsInlineMediaPlayback = YES;
if (@available(iOS 10.0, *)) {
webViewConfig.mediaTypesRequiringUserActionForPlayback = NO;
} else {
// Fallback on earlier versions
}
//屏蔽底部黑框
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KWidth, KHeight) configuration:webViewConfig];
if(self.navigationController.viewControllers.count == 1 && !self.presentingViewController){
self.webView.frame = CGRectMake(0, 0, KWidth, KHeight-self.tabBarController.tabBar.frame.size.height);
}
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
_webView.opaque = NO;
_webView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_webView];
_webView.frame = self.view.bounds;
self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, KWidth, 2)];
_progressView.backgroundColor = [UIColor groupTableViewBackgroundColor];
// _progressView.progressTintColor = kColorWithRGB(112, 156, 246);
_progressView.progressTintColor = UIColorFromRGB(112, 156, 246);
_progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
[self.view addSubview:_progressView];
[self.view bringSubviewToFront:self.progressView];
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
_requestW = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_url]];
[self.webView loadRequest:_requestW];
if (!_showNav){
if (@available(iOS 11.0, *)) {
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
// Fallback on earlier versions
}
}
//
// gyz 注释
// [self addLeftItme:[UIImage imageNamed:@"set_1"] selecedImage:nil orText:@" " selectedText:@""];
// if (self.countDown > 0) {
// _countDownView = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([GYCountDownTimeView class]) owner:self options:nil].firstObject;;
// _countDownView.frame = CGRectMake(KWidth-260-24, SafeAreaTopHeight+36, 260, 64);
// _countDownView.countDownMaxValue = self.countDown;
// _countDownView.details = self.details;
// [self.view addSubview:_countDownView];
//
// __weak typeof (self)weakSelf = self;
// _countDownView.countDownCallBcak = ^(BOOL result) {
// [weakSelf storeCoin];
// };
//
// UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem];
// backButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// backButton.frame = CGRectMake(0, 0, 50, 44);
// [backButton setImage:[UIImage imageNamed:@"nav_back_icon"] forState:UIControlStateNormal];
// [backButton addTarget:self action:@selector(goBackController) forControlEvents:UIControlEventTouchUpInside];
// self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
// }
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(goBackController)];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:!_showNav animated:true];
[_webView reload];
}
- (void)viewWillDisappear:(BOOL)animated
{
UnityPause(false);
}
- (void)leftBarButtonItemAction:(UIButton *)btn;{
[self onBack:btn];
}
- (void)onBack:(UIButton *)button{
[self goBackController];
}
- (void)goSetting{
// gyz 注释
// if(![self.navigationController.viewControllers.lastObject isMemberOfClass:[BaseSetViewController class]]){
// BaseSetViewController * setting = [[BaseSetViewController alloc]init];
// [self.navigationController pushViewController:setting animated:YES];
// }
}
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
self.progressView.hidden = NO;
self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
[self.view bringSubviewToFront:self.progressView];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
// 禁止放大缩小
NSString *injectionJSString = @"var script = document.createElement('meta');"
"script.name = 'viewport';"
"script.content=\"width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no\";"
"document.getElementsByTagName('head')[0].appendChild(script);";
[webView evaluateJavaScript:injectionJSString completionHandler:nil];
NSString* method = [NSString stringWithFormat:@"getStatusBarHeight(\"%.0f\")", UIApplication.sharedApplication.statusBarFrame.size.height / 2 + 44];
[webView evaluateJavaScript:method completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
if (error) {
NSLog(@"%@", error);
} else {
NSLog(@"getStatusBarHeight JS方法调用成功");
}
}];
WEAKSELF;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.webView.scrollView setContentOffset:CGPointMake(0, 0)];
});
//getVersionName
NSString* versionMethod = [NSString stringWithFormat:@"getVersionName(\"%@\")", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]];
[webView evaluateJavaScript:versionMethod completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
if (error) {
NSLog(@"%@", error);
} else {
NSLog(@"getVersionName JS方法调用成功");
}
}];
}
//加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}
// 当web content处理完成时,会回调
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}else{
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
// 允许跳转
decisionHandler(WKNavigationActionPolicyAllow);
}
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
WKFrameInfo *frameInfo = navigationAction.targetFrame;
if (![frameInfo isMainFrame]) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{
}
- (void)goBackController{
if (self.countDown > 0) {
}else{
if ([_webView canGoBack]) {
[_webView goBack];
return;
}
}
if (_dismissCallBack) {
_dismissCallBack();
}
[self dismissViewControllerAnimated:YES completion:nil];
// [self.navigationController popViewControllerAnimated:YES];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"]) {
self.progressView.progress = _webView.estimatedProgress;
if (self.progressView.progress == 1) {
WEAKSELF
[UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f);
} completion:^(BOOL finished) {
weakSelf.progressView.hidden = YES;
}];
}
}else{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc {
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
[_webView.configuration.userContentController removeScriptMessageHandlerForName:@"backTrack"];
[_webView.configuration.userContentController removeScriptMessageHandlerForName:@"settingCallBack"];
}
// alert
//此方法作为js的alert方法接口的实现,默认弹出窗口应该只有提示信息及一个确认按钮,当然可以添加更多按钮以及其他内容,但是并不会起到什么作用
//点击确认按钮的相应事件需要执行completionHandler,这样js才能继续执行
////参数 message为 js 方法 alert(<message>) 中的<message>
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
// confirm
//作为js中confirm接口的实现,需要有提示信息以及两个相应事件, 确认及取消,并且在completionHandler中回传相应结果,确认返回YES, 取消返回NO
//参数 message为 js 方法 confirm(<message>) 中的<message>
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
// prompt
//作为js中prompt接口的实现,默认需要有一个输入框一个按钮,点击确认按钮回传输入值
//当然可以添加多个按钮以及多个输入框,不过completionHandler只有一个参数,如果有多个输入框,需要将多个输入框中的值通过某种方式拼接成一个字符串回传,js接收到之后再做处理
//参数 prompt 为 prompt(<message>, <defaultValue>);中的<message>
//参数defaultText 为 prompt(<message>, <defaultValue>);中的 <defaultValue>
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
fileFormatVersion: 2
guid: 116ed979ac679451eb8e6cb4a35ffaf5
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
userData:
assetBundleName:
assetBundleVariant:
......@@ -6,13 +6,18 @@
"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.spriteshape": "3.0.14",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.ads": "3.6.1",
"com.unity.analytics": "3.3.5",
"com.unity.collab-proxy": "1.2.16",
"com.unity.ide.rider": "1.1.4",
"com.unity.ide.vscode": "1.2.3",
"com.unity.multiplayer-hlapi": "1.0.8",
"com.unity.purchasing": "2.2.1",
"com.unity.test-framework": "1.1.20",
"com.unity.textmeshpro": "2.1.1",
"com.unity.timeline": "1.2.17",
"com.unity.ugui": "1.0.0",
"com.unity.xr.legacyinputhelpers": "2.1.7",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
......
......@@ -11,7 +11,7 @@
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.uielements": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.common": {
"version": "2.1.0",
......@@ -21,21 +21,21 @@
"com.unity.2d.sprite": "1.0.0",
"com.unity.modules.uielements": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.path": {
"version": "2.1.0",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.pixel-perfect": {
"version": "2.1.0",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.psdimporter": {
"version": "2.1.6",
......@@ -46,7 +46,7 @@
"com.unity.2d.animation": "3.2.5",
"com.unity.2d.sprite": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.sprite": {
"version": "1.0.0",
......@@ -63,7 +63,7 @@
"com.unity.2d.common": "2.0.2",
"com.unity.2d.path": "2.0.6"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.2d.tilemap": {
"version": "1.0.0",
......@@ -71,19 +71,37 @@
"source": "builtin",
"dependencies": {}
},
"com.unity.ads": {
"version": "3.6.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.analytics": {
"version": "3.3.5",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "1.2.16",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "1.1.4",
......@@ -92,21 +110,39 @@
"dependencies": {
"com.unity.test-framework": "1.1.1"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.3",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.1.0",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.multiplayer-hlapi": {
"version": "1.0.8",
"depth": 0,
"source": "registry",
"dependencies": {
"nuget.mono-cecil": "0.1.6-preview"
},
"url": "https://packages.unity.com"
},
"com.unity.purchasing": {
"version": "2.2.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.20",
......@@ -117,7 +153,7 @@
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.textmeshpro": {
"version": "2.1.1",
......@@ -126,14 +162,14 @@
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.2.17",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
......@@ -144,6 +180,23 @@
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.xr.legacyinputhelpers": {
"version": "2.1.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.xr": "1.0.0"
},
"url": "https://packages.unity.com"
},
"nuget.mono-cecil": {
"version": "0.1.6-preview",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
......
......@@ -17,7 +17,7 @@ MonoBehaviour:
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.cn
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
m_UserSelectedRegistryName:
......
......@@ -41,12 +41,6 @@ PlayerSettings:
height: 1
m_SplashScreenLogos: []
m_VirtualRealitySplashScreen: {fileID: 0}
m_ShowUnitySplashAds: 0
m_AdsAndroidGameId:
m_AdsIosGameId:
m_ShowSplashAdsSlogan: 0
m_SloganImage: {fileID: 0}
m_SloganHeight: 150
m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1024
defaultScreenHeight: 768
......@@ -124,14 +118,13 @@ PlayerSettings:
vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0
vulkanEnableLateAcquireNextImage: 0
useSecurityBuild: 0
m_SupportedAspectRatios:
4:3: 1
5:4: 1
16:10: 1
16:9: 1
Others: 1
bundleVersion: 0.1
bundleVersion: 1.0.0
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
......@@ -176,6 +169,7 @@ PlayerSettings:
androidMaxAspectRatio: 2.1
applicationIdentifier:
Android: com.ym.wdcy
iPhone: com.ym.ioswdcy
buildNumber: {}
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 21
......@@ -366,7 +360,6 @@ PlayerSettings:
m_Kind: 1
m_SubKind:
m_BuildTargetBatching: []
m_BuildTargetEncrypting: []
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment