|
前言:
在Unity里面能走到这一步的,多半前面已经经历了iOS 和Unity传值交互的痛苦历程。有了前面的代码经验,这次要做的事情,就是在交互基础之上,了解如何自动配置Unity生成Xcode项目,使得每次打包即可真机调试而不必每次都要去修改签名证书,添加framework累死个人。
传值系列
iOS Unity 交互(系列一)Unity调用iOS函数 Unity给iOS传值
iOS Unity 交互(系列二)iOS调用Unity函数 iOS给Unity传值
iOS Unity 交互(系列三)iOS Unity互传参数与完整示例代码
iOS Unity 交互(系列四)Unity调用iOS SDK
本次实验的环境:
1、苹果电脑安装:Xcode(Version 13.2.1 (13C100)),Unity(Version 2020.3.25f1c1 Personal),VSCode(这个随意吧)
2、苹果手机真机,用于调试。
实现场景
Unity集成支付宝和微信SDK。
让Unity生成Xcode项目,并且在生成Xcode项目的时候,脚本自动配置Xcode项目所需要的 framework,info.plist,代码签名,证书,等等。
生成项目之后即可调用支付宝和微信SDK进行付款操作。
备注
操作太多了,仔细写要写上大半天。这里就直接贴图讲解细节和一些注意的点。
工程的初始化配置
1.png
关于支付宝SDK
原始的支付宝SDK是同时支持真机架构和模拟器架构的。如果直接导入原始支付宝SDK到Unity项目里,生成的Xcode项目在运行的时候会报错,会给你搞出什么 arm64 architecture 之类的错误。所以我们需要把支付宝SDK里面的模拟器架构剔除。微信SDK则不需要。
在命令行里运行以下代码:
//1 切换到外层的文件夹,查看架构cd /Users/zhaoxin/Desktop/Ali_iOS_SDKlipo -info AlipaySDK.framework/AlipaySDK//2 切换到 cd /Users/zhaoxin/Desktop/Ali_iOS_SDK/AlipaySDK.framework 剔除模拟器lipo -remove i386 AlipaySDK -o AlipaySDKlipo -remove x86_64 AlipaySDK -o AlipaySDK
2.png
关于生成Xcode项目
Unity现在已经可以在面板上直接配置项目的某些参数,以前好像是要写脚本代码去改的。
在Unity里面依次寻找:File → Build Settings → Player Settings,如下图:
3.png
我的示例代码文件目录结构
4.png
图片中的示例代码:
C# 脚本代码 AliWxPayDemo
using System.Runtime.InteropServices;using UnityEngine;public class AliWxPayDemo : MonoBehaviour{ //定义函数 支付宝支付 [DllImport("__Internal")] private static extern void IOSAliPay(string objectName, string payOrder, string scheme); //注册微信 [DllImport("__Internal")] private static extern void IOSRegistWxApi(string objectName, string WXAppKey, string WXAppUniversalLink); //定义函数 微信支付 [DllImport("__Internal")] private static extern void IOSWxPay(string openID, string partnerId, string prepayId, string nonceStr, string timeStamp, string package, string sign); void Start() { } void Update() { } void OnGUI() { if (GUI.Button(new Rect(150, 400, 700, 150), "点击使用支付宝")) { string alipay = "这个支付字符串来自于后端,在传参的时候换成你自己的支付字符串"; alipay = "service=mobile.securitypay.pay&partner=608896586645411740&_input_charset=utf-8¬ify_url=http%7A%6F%6Fopen.jike%6Fcallback%6Falipay&out_trade_no=60664894135456448&subject=%88%B1%E5%8A%A8-%E8%AF%BE%E7%A8%8B%E9%A6%84%E7%BA%A6-606601665448&body=%E7%88%B1%E5%8A%A8-%E8%AF%BE%E8%8B%E9%A6%84%E7%BA%A6-60660166506448&payment_type=1&total_fee=0.01&seller_id=6088045411740&it_b_pay=70m&sign_type=RSA&sign=AYHT%6F0tyV8oG7Fs8s6YlqpnZb4nW74nmDkWCVOLRpB5aoPzOuiCp%6BSCvyXrtC6Q9IaxFXU79432y9hka9v87L880uPgPCqHaOC1kWBm%6FSGuIRM4WRukI7VdZWlF7TuXB%6BM1ZgJKFfd486132SDLliY4B4ZkDRZgetE%7D"; IOSAliPay("PayObject", alipay, iOSPayConfig.Ali_Pay_Schema); } if (GUI.Button(new Rect(150, 800, 700, 150), "点击使用微信")) { //先注册微信 IOSRegistWxApi("PayObject", iOSPayConfig.WXAppKey, iOSPayConfig.WXAppUniversalLink); //然后调用微信支付 IOSWxPay("wx765vb987v5123d70", "1666707801", "wx661178461614106f6b7d46c6c0b640000", "8d66017766a641fab68d86a79054071", "164717894656", "Sign=WXPay", "B561D744E816D7DD015C0D76DCE99D4"); } } //来自OC的函数 支付宝支付结果回调 public void IOS_Ali_Pay_Result(string dictionaryString) { Debug.Log("C# 收到 支付宝 回调:" + dictionaryString); } //来自OC的函数 微信支付结果回调 public void IOS_Wx_Pay_Result(string dictionaryString) { Debug.Log("C# 收到 微信 回调:" + dictionaryString); }}
C# 脚本代码 BuildCallback
using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEditor.Callbacks;using UnityEditor.iOS.Xcode;using System.IO;using UnityEditor.XCodeEditor;using System;public class BuildCallback : IPreprocessBuildWithReport, IPostprocessBuildWithReport{ int IOrderedCallback.callbackOrder { get { return 0; } } System.DateTime startTime; //打包前事件 void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report) { startTime = System.DateTime.Now; Debug.Log("开始打包 : " + startTime); } //打包后事件 void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report) { System.TimeSpan buildTimeSpan = System.DateTime.Now - startTime; Debug.Log("打包成功,耗时 : " + buildTimeSpan); } //回调 打包后处理 [PostProcessBuild(1)] public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject) { if (target != BuildTarget.iOS) { return; } var projPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj"; var proj = new PBXProject(); proj.ReadFromFile(projPath); //var targetGUID = proj.TargetGuidByName("Unity-iPhone"); //var targetGUID = proj.GetUnityMainTargetGuid(); var targetGUID = proj.GetUnityFrameworkTargetGuid(); proj.AddBuildProperty(targetGUID, "OTHER_LDFLAGS", "-ObjC -all_load"); //微信开发文档要求在 Other Link Flags 里面添加 "-ObjC -all_load" 但是实际验证发现生成的Xcode项目这句比并没有添加上,然而不影响使用 //proj.SetBuildProperty(targetGUID, "ENABLE_BITCODE", "NO"); // 添加系统库 // 这里是支付宝需要用到系统库,如果不引入系统库, Unity生成Xcode项目运行必定报错,各种缺 /* * 举例: 如果没有引入 WebKit.framework 就会报如下错误: ld: warning: arm64 function not 4-byte aligned: _unwind_tester from /Users/zhaoxin/Desktop/支付宝微信合并Demo/ios_generate_proj/Libraries/libiPhone-lib.a(unwind_test_arm64.o) Undefined symbols for architecture arm64: "_OBJC_METACLASS_$_WKWebView", referenced from: _OBJC_METACLASS_$_MQPWebView in AlipaySDK */ proj.AddFrameworkToProject(targetGUID, "libz.tbd", false); proj.AddFrameworkToProject(targetGUID, "libc++.tbd", false); proj.AddFrameworkToProject(targetGUID, "CoreText.framework", false); proj.AddFrameworkToProject(targetGUID, "CoreTelephony.framework", false); proj.AddFrameworkToProject(targetGUID, "CoreMotion.framework", false); proj.AddFrameworkToProject(targetGUID, "CoreGraphics.framework", false); proj.AddFrameworkToProject(targetGUID, "QuartzCore.framework", false); proj.AddFrameworkToProject(targetGUID, "UIKit.framework", false); proj.AddFrameworkToProject(targetGUID, "Foundation.framework", false); proj.AddFrameworkToProject(targetGUID, "CFNetwork.framework", false); proj.AddFrameworkToProject(targetGUID, "SystemConfiguration.framework", false); proj.AddFrameworkToProject(targetGUID, "WebKit.framework", false); // 这里是微信需要使用到的系统库 proj.AddFrameworkToProject(targetGUID, "CoreGraphics.framework", false); proj.AddFrameworkToProject(targetGUID, "WebKit.framework", false); proj.AddFrameworkToProject(targetGUID, "Security.framework", false); //proj.AddFrameworkToProject(targetGUID, "VideoToolbox.framework", false); //proj.AddFrameworkToProject(targetGUID, "StoreKit.framework", false); //proj.AddFrameworkToProject(targetGUID, "Security.framework", false); //proj.AddFrameworkToProject(targetGUID, "ReplayKit.framework", false); //proj.AddFrameworkToProject(targetGUID, "Photos.framework", false); //proj.AddFrameworkToProject(targetGUID, "MultipeerConnectivity.framework", false); //proj.AddFrameworkToProject(targetGUID, "MobileCoreServices.framework", false); //proj.AddFrameworkToProject(targetGUID, "MetalPerformanceShaders.framework", false); //proj.AddFrameworkToProject(targetGUID, "MediaToolbox.framework", false); //proj.AddFrameworkToProject(targetGUID, "MediaPlayer.framework", false); //proj.AddFrameworkToProject(targetGUID, "libresolv.9.tbd", false); //proj.AddFrameworkToProject(targetGUID, "libiconv.tbd", false); //proj.AddFrameworkToProject(targetGUID, "libcompression.tbd", false); //proj.AddFrameworkToProject(targetGUID, "libc++abi.tbd", false); //proj.AddFrameworkToProject(targetGUID, "JavaScriptCore.framework", false); //proj.AddFrameworkToProject(targetGUID, "GLKit.framework", false); //proj.AddFrameworkToProject(targetGUID, "AVFoundation.framework", false); //proj.AddFrameworkToProject(targetGUID, "AudioToolbox.framework", false); //proj.AddFrameworkToProject(targetGUID, "AssetsLibrary.framework", false); //proj.AddFrameworkToProject(targetGUID, "Accelerate.framework", false); //proj.AddFrameworkToProject(targetGUID, "AuthenticationServices.framework", false); //proj.AddFrameworkToProject(targetGUID, "libil2cpp.a", false); //proj.AddFrameworkToProject(targetGUID, "libiPhone-lib.a", false); //proj.AddFrameworkToProject(targetGUID, "AuthenticationServices.framework", false); //proj.AddFrameworkToProject(targetGUID, "AVKit.framework", false); //proj.AddFrameworkToProject(targetGUID, "CoreMedia.framework", false); //proj.AddFrameworkToProject(targetGUID, "CoreVideo.framework", false); //proj.AddFrameworkToProject(targetGUID, "OpenAL.framework", false); //proj.AddFrameworkToProject(targetGUID, "OpenGLES.framework", false); //proj.AddFrameworkToProject(targetGUID, "libiconv.2.dylib", false); //proj.AddFrameworkToProject(targetGUID, "LightGameSDK.framework", false); //proj.AddFrameworkToProject(targetGUID, "Metal.framework", false); //proj.AddFrameworkToProject(targetGUID, "libresolv.9.tbd", false); //proj.AddFrameworkToProject(targetGUID, "CoreLocation.framework", false); //proj.AddFrameworkToProject(targetGUID, "ImageIO.framework", false); //proj.AddFrameworkToProject(targetGUID, "AdSupport.framework", false); proj.WriteToFile(projPath); var plistPath = Path.Combine(pathToBuiltProject, "Info.plist"); var plist = new PlistDocument(); plist.ReadFromFile(plistPath); PlistElementDict rootDict = plist.root; plist.root.SetString("NSPhotoLibraryAddUsageDescription", "需要相册权限"); plist.root.SetString("NSPhotoLibraryUsageDescription", "需要相册权限"); plist.root.SetString("NSCalendarsUsageDescription", "需要日历权限"); plist.root.SetString("NSMicrophoneUsageDescription", "录制屏幕需要麦克风权限"); plist.root.SetString("NSCameraUsageDescription", "需要相机权限"); plist.root.SetString("NSLocationWhenInUseUsageDescription", "需要定位权限"); // plist 里面 允许 http 请求 if (rootDict.values.ContainsKey("NSAppTransportSecurity")) { rootDict.values.Remove("NSAppTransportSecurity");} PlistElementDict urlDict = rootDict.CreateDict("NSAppTransportSecurity"); urlDict.SetBoolean("NSAllowsArbitraryLoads", true); //添加各种白名单 PlistElementArray queriesSchemes = rootDict.CreateArray("LSApplicationQueriesSchemes"); //queriesSchemes.AddString("douyinsharesdk"); //queriesSchemes.AddString("douyinopensdk"); //queriesSchemes.AddString("snssdk1128"); //queriesSchemes.AddString("toutiaoopensdk"); //queriesSchemes.AddString("wechat"); //微信白名单 queriesSchemes.AddString("weixinULAPI"); //微信白名单 queriesSchemes.AddString("weixin"); //微信白名单 //配置urlSchemes(数组里面有字典,字典里面有子数组) PlistElementArray urlTypes = plist.root.CreateArray("CFBundleURLTypes"); PlistElementDict itemDict; //添加支付宝的 URL Scheme itemDict = urlTypes.AddDict(); itemDict.SetString("CFBundleTypeRole", "Editor"); itemDict.SetString("CFBundleURLName", "AliPay"); PlistElementArray zhifubaoSchemesArray = itemDict.CreateArray("CFBundleURLSchemes"); zhifubaoSchemesArray.AddString(iOSPayConfig.Ali_Pay_Schema); //添加微信的 URL Scheme itemDict = urlTypes.AddDict(); itemDict.SetString("CFBundleTypeRole", "Editor"); itemDict.SetString("CFBundleURLName", "weixin"); PlistElementArray weixinSchemes = itemDict.CreateArray("CFBundleURLSchemes"); weixinSchemes.AddString(iOSPayConfig.WXAppKey); //添加第2个 //itemDict = urlTypes.AddDict(); //itemDict.SetString("CFBundleTypeRole", "Editor"); //PlistElementArray schemesArray2 = itemDict.CreateArray("CFBundleURLSchemes"); //schemesArray2.AddString("xxxx"); //添加第3个 //itemDict = urlTypes.AddDict(); //itemDict.SetString("CFBundleTypeRole", "Editor"); //itemDict.SetString("CFBundleURLName", "xxxx"); //PlistElementArray schemesArray3 = itemDict.CreateArray("CFBundleURLSchemes"); //schemesArray3.AddString("xxxx"); File.WriteAllText(plistPath, plist.WriteToString()); plist.WriteToFile(plistPath); //编辑 Capability 在我这个版本,即使不添加 AssociatedDomains 也没有关系, 因为微信不走 - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity 这个方法 //在高版本原生iOS App中,需要在 AssociatedDomains 里面配置微信的 UniversalLink 用于接收微信的回调 AddCapability(proj, pathToBuiltProject); //编辑代码文件 得到xcode工程的路径 string path = Path.GetFullPath(pathToBuiltProject); EditorCode(path); UnityEngine.Debug.Log("Xcode 后续处理完成"); } //编辑Xcode代码文件 private static void EditorCode(string filePath) { //读取UnityAppController.mm文件 XClass UnityAppController = new XClass(filePath + "/Classes/UnityAppController.mm"); //在Xcode工程入口处导入类 iOSPayHelper.h, 这个代码文件集成了 支付宝和微信支付的入口 UnityAppController.WriteBelow("#import \"UnityAppController.h\"", "#import \"iOSPayHelper.h\""); //支付宝 //在Xcode工程入口函数 openurl 里添加处理支付回调拉起UnityApp的处理 UnityAppController.WriteBelow("AppController_SendNotificationWithArg(kUnityOnOpenURL, notifData);", " [[iOSPayHelper shared] handleAliPayURL:url];"); //微信 //注册微信, 一定是要在 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions 这里面注册微信, 如果只是从你写的 .mm 文件里面,使用支付的时候才去注册, 验证结果也是生效的, 为了防止后续因为版本缘故导致失效, 下面这两行写在 App启动入口的函数保留使用 //string code = " [WXApi registerApp:" + "@\"" + iOSPayConfig.WXAppKey + "\" " + "universalLink:" + "@\"" + iOSPayConfig.WXAppUniversalLink + "\"" + "];"; //UnityAppController.WriteBelow("[KeyboardDelegate Initialize];", code); //在AppDelegate里面添加匿名分类,添加一个协议 UnityAppController.WriteBefore("@implementation UnityAppController", "@interface UnityAppController()<WXApiDelegate>\n@end"); //注意,在这3个函数里面, 最好都要添加微信处理的回调处理, 自己创建空白的项目然后使用微信支付 和 从Unity生成出来的项目使用微信支付, 微信的回调走的不是同一个 Application 里面的回调函数. //在这3个地方都添加回调处理,可以最大范围涵盖微信可能走的系统回调函数, 也是因为这个, 花了大量时间去验证. UnityAppController.WriteBefore("NSURL* url = userActivity.webpageURL;", " [WXApi handleOpenUniversalLink:userActivity delegate:self];"); UnityAppController.WriteBefore("- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity", "- (BOOL)application:(UIApplication*)application handleOpenURL: (NSURL*)url {return [WXApi handleOpenURL: url delegate:self];}"); UnityAppController.WriteBelow("AppController_SendNotificationWithArg(kUnityOnOpenURL, notifData);", "[WXApi handleOpenURL: url delegate:self];"); //添加微信的代理函数 UnityAppController.WriteBefore("- (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions", "- (void)onResp:(BaseResp *)resp {\n [[iOSPayHelper shared] handleWxPayResp:resp];\n}"); } //添加 Capability private static void AddCapability(PBXProject project, string pathToBuiltProject) { //string target = project.TargetGuidByName(PBXProject.GetUnityTargetName()); var target = project.GetUnityFrameworkTargetGuid(); // Add BackgroundModes And Need to modify info.plist //project.AddCapability(target, PBXCapabilityType.BackgroundModes); //project.AddCapability(target, PBXCapabilityType.InAppPurchase); //project.AddCapability(target, PBXCapabilityType.AssociatedDomains); // Need Create entitlements string relativeEntitlementFilePath = "Unity-iPhone/Unity-iPhone.entitlements"; string absoluteEntitlementFilePath = pathToBuiltProject + "/" + relativeEntitlementFilePath; PlistDocument tempEntitlements = new PlistDocument(); //添加钥匙串 //string key_KeychainSharing = "keychain-access-groups"; //var arr = (tempEntitlements.root[key_KeychainSharing] = new PlistElementArray()) as PlistElementArray; //arr.values.Add(new PlistElementString("$(AppIdentifierPrefix)com.tencent.xxxx")); //arr.values.Add(new PlistElementString("$(AppIdentifierPrefix)com.tencent.wsj.keystoregroup")); //添加推送 //string key_PushNotifications = "aps-environment"; //tempEntitlements.root[key_PushNotifications] = new PlistElementString("development"); //添加关联网址 string key_Associated = "com.apple.developer.associated-domains"; var arr_Ass = (tempEntitlements.root[key_Associated] = new PlistElementArray()) as PlistElementArray; arr_Ass.values.Add(new PlistElementString(iOSPayConfig.WXAssociatedDomains)); arr_Ass.values.Add(new PlistElementString("")); project.AddCapability(target, PBXCapabilityType.AssociatedDomains, relativeEntitlementFilePath); //project.AddCapability(target, PBXCapabilityType.PushNotifications, relativeEntitlementFilePath); //project.AddCapability(target, PBXCapabilityType.KeychainSharing, relativeEntitlementFilePath); string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject); File.WriteAllText(projPath, project.WriteToString()); tempEntitlements.WriteToFile(absoluteEntitlementFilePath); ModifyEntitlementFile(absoluteEntitlementFilePath); } private static void ModifyEntitlementFile(string absoluteEntitlementFilePath) { if (!File.Exists(absoluteEntitlementFilePath)) return; try { StreamReader reader = new StreamReader(absoluteEntitlementFilePath); var content = reader.ReadToEnd().Trim(); reader.Close(); var needFindString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; var changeString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n" + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"; Debug.Log("Before: " + content); content = content.Replace(needFindString, changeString); Debug.Log("After: " + content); StreamWriter writer = new StreamWriter(new FileStream(absoluteEntitlementFilePath, FileMode.Create)); writer.WriteLine(content); writer.Flush(); writer.Close(); } catch (Exception e) { Debug.Log("ModifyEntitlementFile - 失败了伙计 Failed: " + e.Message); } }}
C# 脚本代码 XClass
using UnityEngine;using System.IO;namespace UnityEditor.XCodeEditor{ public partial class XClass : System.IDisposable { private string filePath; public XClass(string fPath) { filePath = fPath; if (!System.IO.File.Exists(filePath)) { Debug.LogError(filePath + "路径下文件不存在"); return; } } public void WriteBelow(string below, string text) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(below); if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标志" + below); return; } int endIndex = text_all.LastIndexOf("\n", beginIndex + below.Length); text_all = text_all.Substring(0, endIndex) + "\n" + text + "\n" + text_all.Substring(endIndex); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void WriteBefore(string before, string text) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(before); //找开始的索引 if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标志" + before); return; } text_all = text_all.Substring(0, beginIndex) + text + "\n\n" + text_all.Substring(beginIndex); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void Replace(string below, string newText) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(below); if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标致" + below); return; } text_all = text_all.Replace(below, newText); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void Dispose() { } }}
C# 脚本代码 XClass
using UnityEngine;using System.IO;namespace UnityEditor.XCodeEditor{ public partial class XClass : System.IDisposable { private string filePath; public XClass(string fPath) { filePath = fPath; if (!System.IO.File.Exists(filePath)) { Debug.LogError(filePath + "路径下文件不存在"); return; } } public void WriteBelow(string below, string text) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(below); if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标志" + below); return; } int endIndex = text_all.LastIndexOf("\n", beginIndex + below.Length); text_all = text_all.Substring(0, endIndex) + "\n" + text + "\n" + text_all.Substring(endIndex); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void WriteBefore(string before, string text) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(before); //找开始的索引 if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标志" + before); return; } text_all = text_all.Substring(0, beginIndex) + text + "\n\n" + text_all.Substring(beginIndex); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void Replace(string below, string newText) { StreamReader streamReader = new StreamReader(filePath); string text_all = streamReader.ReadToEnd(); streamReader.Close(); int beginIndex = text_all.IndexOf(below); if (beginIndex == -1) { Debug.LogError(filePath + "中没有找到标致" + below); return; } text_all = text_all.Replace(below, newText); StreamWriter streamWriter = new StreamWriter(filePath); streamWriter.Write(text_all); streamWriter.Close(); } public void Dispose() { } }}
C# 脚本代码 iOSPayConfig
// 支付SDK使用到的常量定义类// 注意,这个类放到 Assets 目录下面public static class iOSPayConfig{ //支付宝使用到的 Schema //1 用在支付方法里,作为参数 //2 在Unity工程导出Xcode工程后,写如到 info.plist 当中作为支付宝拉起Unity App的接口. (这部分功能已经写入到脚本自动添加) public static string Ali_Pay_Schema = "支付宝给你的Schema"; //微信使用到的 Key //1 在Unity工程导出Xcode工程后,写如到 info.plist 当中作为支付宝拉起Unity App的接口. (这部分功能已经写入到脚本自动添加) public static string WXAppKey = "微信给你的AppKey"; //2 在Unity工程导出Xcode工程后,写如到 info.plist 当中作为支付宝拉起Unity App的接口. (这部分功能已经写入到脚本自动添加) public static string WXAppUniversalLink = "微信给你的UniversalLink"; //3 微信 Associated Domains 链接 public static string WXAssociatedDomains = "微信给你的 Associated url 去微信开放平台弄"; //这个需要在微信开放平台去配置,把微信给的链接写到项目里,这里是直接改代码文件硬写.}
iOS 代码 iOSPayHelper.h
//// iOSPayHelper.h// UnityFramework//// Created by 童年的大灰狼 on 2020/5/13.//#import <Foundation/Foundation.h>#import <AlipaySDK/AlipaySDK.h>#import "WXApi.h"@interface iOSPayHelper : NSObject///单例对象+ (instancetype)shared;///处理支付回调URL- (void)handleAliPayURL:(NSURL *)url;///支付宝支付- (void)AliPayOrder:(NSString *)orderStr;///支付宝 挂载的Unity对象@property (nonatomic, strong) NSString *gameobject_Ali;///支付宝使用的 Schema@property (nonatomic, strong) NSString *ali_schemeStr;///处理微信支付的回调- (void)handleWxPayResp:(BaseResp *)resp;///微信 挂载的Unity对象@property (nonatomic, strong) NSString *gameobject_Wx;@end
iOS 代码 iOSPayHelper.mm
//// iOSPayHelper.m// UnityFramework//// Created by 童年的大灰狼 on 2020/5/13.//#import "iOSPayHelper.h"@interface iOSPayHelper()@end@implementation iOSPayHelperstatic iOSPayHelper *_sharedInstance = nil;static dispatch_once_t onceToken;+ (instancetype)shared { dispatch_once(&onceToken, ^{ _sharedInstance = [[iOSPayHelper alloc] init]; }); return _sharedInstance;}- (instancetype)init { self = [super init]; if (self) { } return self;}- (void)AliPayOrder:(NSString *)orderStr { [[AlipaySDK defaultService] payOrder:orderStr fromScheme:self.ali_schemeStr callback:^(NSDictionary *resultDic) { NSLog(@" %s", __func__); [self executeCompleteBlock:resultDic]; }];}- (void)handleAliPayURL:(NSURL *)url { if ([url.scheme isEqualToString:self.ali_schemeStr]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@" %s", __func__); [self executeCompleteBlock:resultDic]; }]; }}- (void)executeCompleteBlock:(NSDictionary *)resultDic { // 返回码 含义 // 9000 订单支付成功 // 8000 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 // 4000 订单支付失败 // 5000 重复请求 // 6001 用户中途取消 // 6002 网络连接出错 // 6004 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 // 其它 其它支付错误 NSInteger resultCode = [resultDic[@"resultStatus"] integerValue]; NSString *msg = nil; if (resultCode == 9000) { msg = @"订单支付成功"; } else if (resultCode == 8000) { msg = @"支付结果未知,请查询商户订单列表中订单的支付状态"; } else if (resultCode == 5000) { msg = @"重复请求"; } else if (resultCode == 6001) { msg = @"用户中途取消"; } else if (resultCode == 6002) { msg = @"网络连接出错"; } else if (resultCode == 6004) { msg = @"支付结果未知,请查询商户订单列表中订单的支付状态"; } else { msg = @"订单支付失败"; } NSMutableDictionary *tempdic = [NSMutableDictionary dictionaryWithDictionary:resultDic]; [tempdic setObject:msg forKey:@"iOS_Add_Msg"]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tempdic options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@" iOS 收到支付宝回调结果: resultDic = %@",resultDic); UnitySendMessage([self.gameobject_Ali UTF8String], "IOS_Ali_Pay_Result", [jsonString UTF8String]);}///注册微信支付- (void)registerApp:(NSString *)WXAppKey universalLink:(NSString *)WXAppUniversalLink { [WXApi registerApp:WXAppKey universalLink:WXAppUniversalLink];}///微信支付- (void)WxPayReq:(PayReq *)req { //调起微信支付,包装参数 [WXApi sendReq:req completion:^(BOOL success) {}];}///处理微信支付的回调- (void)handleWxPayResp:(BaseResp *)resp { if ([resp isKindOfClass:[PayResp class]]) { //微信支付回调中errCode值列表: //名称 描述 解决方案 //0 成功 展示成功页面 //-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。 //-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。 NSString *msg = @""; if (resp.errCode == WXSuccess) { msg = @"支付成功"; } else if(resp.errCode == WXErrCodeUserCancel) { msg = @"用户取消"; } else { msg = @"支付失败"; } NSMutableDictionary *tempdic = [NSMutableDictionary dictionary]; [tempdic setObject:msg forKey:@"iOS_Add_Msg"]; [tempdic setObject:@(resp.errCode) forKey:@"errCode"]; if (resp.errStr) { [tempdic setObject:resp.errStr forKey:@"errStr"]; } [tempdic setObject:@(resp.type) forKey:@"type"]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tempdic options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@" iOS 收到微信回调结果: tempdic = %@", tempdic); UnitySendMessage([self.gameobject_Wx UTF8String], "IOS_Wx_Pay_Result", [jsonString UTF8String]); } else { NSLog(@" iOS 收到微信支付回调对象错误! 这不是支付完成的类实例对象"); }}@end#ifdef __cplusplusextern "C" {#endif///支付宝extern void IOSAliPay(const char *objName, const char *payOrder, const char *scheme) { NSString *o = [NSString stringWithUTF8String:objName]; NSString *p = [NSString stringWithUTF8String:payOrder]; NSString *s = [NSString stringWithUTF8String:scheme]; [iOSPayHelper shared].gameobject_Ali = o; [iOSPayHelper shared].ali_schemeStr = s; [[iOSPayHelper shared] AliPayOrder:p];}///需要注册微信extern void IOSRegistWxApi(const char *objName, const char *WXAppKey, const char *WXAppUniversalLink) { NSString *o = [NSString stringWithUTF8String:objName]; [iOSPayHelper shared].gameobject_Wx = o; NSString *k = [NSString stringWithUTF8String:WXAppKey]; NSString *l = [NSString stringWithUTF8String:WXAppUniversalLink]; [[iOSPayHelper shared] registerApp:k universalLink:l];}///微信extern void IOSWxPay(const char *openID, const char *partnerId, const char *prepayId, const char *nonceStr, const char *timeStamp, const char *package, const char *sign) { //调起微信支付,包装参数 PayReq *req = [[PayReq alloc] init]; req.openID = [NSString stringWithUTF8String:openID]; req.partnerId = [NSString stringWithUTF8String:partnerId]; req.prepayId = [NSString stringWithUTF8String:prepayId]; req.nonceStr = [NSString stringWithUTF8String:nonceStr]; req.timeStamp = (UInt32)[[NSString stringWithUTF8String:timeStamp] longLongValue]; req.package = [NSString stringWithUTF8String:package]; req.sign = [NSString stringWithUTF8String:sign]; [[iOSPayHelper shared] WxPayReq:req];}#ifdef __cplusplus}#endif结语
感谢以下iOS/Unity玩家的文章:
Unity打包iOS,Xcode自动打包framework
Unity 自动打包 Part1—配置Xcode工程
Unity 配置Xcode工程--添加Capability
[Unity]配置Xcode工程(2)--添加Capability
Unity3D研究院之IOS全自动编辑framework、plist、oc代码(六十七)
Unity编译到Xcode自动添加文件及代码修改
Unity导出XCode工程的时候自动修改工程设置添加依赖
Unity 打包IOS(自动化构建)
Unity配置Xcode脚本
Unity配置Xcode脚本
IOS自动化打包,自动导入并修改文件
Unity3d Android IOS 自动设置 签名和输出 路径
Unity 打包IOS(自动化构建)
[Unity]腾讯SDK踩坑路(2)--配置Xcode工程(MSDK和米大师配置代码冲突)
使用PostProcessBuild设定Unity产生的Xcode Project
Unity iOS Xcode 自动化一些记录
Unity成功导出Xcode工程后自动修改一些设置
报错指引
iOS 微信支付SDK -canOpenURL: failed for URL: "weixinULAPI://"
微信支付无法回调函数,iOS端微信支付成功失败无法收到不执行回调微信回调函数的原因...
Undefined symbols for architecture arm64解决方案
Undefined symbols for architecture arm64:问题解决方法
解决Undefined symbols for architecture arm64问题
iOS 支付宝SDK接入详解
iOS framework分离与合并 删除SDK中的i386,x86_86架构
iOS开发 删除framework里支持模拟器的架构
微信开放平台
微信开放平台 iOS Demo下载页面
微信开放平台 iOS SDK接入官方文档 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|