添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

这算是Unity接入微信开放平台的第二篇了,第一篇在这: Unity接入第三方Android SDK——之微信开放平台 作为一个既没有接触过Android开发、有没有接触过iOS开发的人员 ,完成Android和iOS的微信SDK接入,拢共花费了一周的工作时间,效率有点低。

在完成微信SDK接入的过程中,查看过网络上不少的文章,不过似乎没有哪一篇是能文章能够一气呵成解决问题的,因此自己有了斗胆一试的想法,所以才有了这两篇文章的诞生,希望能够后面接触的小伙伴节约一些时间。

本文的亮点

最后的完成品,不需要在Xcode中修改、添加任何内容,直接Unity编译到Xcode然后安装到真机

一、开始 Universal Links的配置

这部分的内容我就不细讲了,相对比较简单,主要是苹果开发者和微信开发者后台的设置,然后把apple-app-site-association这个文件放到域名根目录即可(域名必须支持HTTPS) apple-app-site-association 这个文件的内容类似下面这样:

"applinks" : { "apps" : [ ] , "details" : [ { "appID" : "TeamID.com.yourapp.bundleID" , "paths" : [ "*" ]

二、微信SDK的导入

  • 前往微信开放平台下载SDK: developers.weixin.qq.com/doc/oplatfo…
  • SDK包含4个文件: libWeChatSDK.a,WXApi.h,WXApiObject.h, WechatAuthSDK.h
  • 将这四个文件放入Unity项目的 Assets/Plugins/iOS 目录下,这个目录下的文件会自动打包至Xcode项目的Libraries目录下。
  • 在Unity的Inspector中设置libWeChatSDK.a,勾选 Framework dependencies/Security 和 Rarely used frameworks/Webkit,如下图:
  • 设置完之后记得点 Apply 。

    三、扩展UnityAppController

    扩展UnityAppController的目的很简单,这样就不需要每次导出Xcode项目之后,都去修改UnityAppController.mm中的代码。 这个我主要参考了这篇博文: blog.mutoo.im/2015/09/mak… 但是最终我用的代码版本 ,是在他的基础上去掉了一部分。 创建MyAppController.m文件 ,代码如下:

    // MyAppController.m // Unity-iPhone // Created by Jooki Tsui on 2020/11/13. #import "WXApi.h" #import "UnityAppController.h" @interface MyAppController : UnityAppController < WXApiDelegate > IMPL_APP_CONTROLLER_SUBCLASS (MyAppController) @implementation MyAppController - ( BOOL )application:( UIApplication *)application continueUserActivity:( NSUserActivity *)userActivity # if defined(__IPHONE_12_0) || defined(__TVOS_12_0) restorationHandler:( void (^)( NSArray < id < UIUserActivityRestoring > > * _Nullable restorableObjects))restorationHandler # else restorationHandler:( void (^)( NSArray * _Nullable))restorationHandler # endif return [WXApi handleOpenUniversalLink:userActivity delegate: self ]; - ( BOOL )application:( UIApplication *)application openURL:( NSURL *)url sourceApplication:( NSString *)sourceApplication annotation:( id )annotation return [WXApi handleOpenURL:url delegate: self ]; - ( BOOL )application:( UIApplication *)application handleOpenURL:( NSURL *)url return [WXApi handleOpenURL:url delegate: self ]; - ( void )onResp:(BaseResp *)resp // do something - ( void )onReq:(BaseReq *)req // do something

    具体代码我就不一句句解释了,主要是重写了continueUserActivity、openURL、handleOpenURL这三个方法。 同样将这个文件放入 Assets/Plugins/iOS 目录下。

    四、编写Unity和Objective-C的桥接文件

    创建NativeBridge.m文件,写入供Unity调用的方法,代码如下:

    // NativeBridge.m // Unity-iPhone #import <Foundation/Foundation.h> #import "WXApi.h" //这是向微信终端注册你的appid void RegisterApp( const char * appid) NSString *weichatId = [ NSString stringWithFormat: @"%s" , appid]; BOOL installed = [WXApi isWXAppInstalled]; NSLog ( @"installed result: %@" , installed? @"true" : @"false" ); BOOL result = [WXApi registerApp:weichatId universalLink:( @"https://www.mylittleenglish.com/app/hanzi/" )]; NSLog ( @"result: %@" , result? @"true" : @"false" ); // 分享链接至微信 void ShareUrlToWX( int scene, const char * url, const char * title, const char * description){ WXWebpageObject *webpageObject = [WXWebpageObject object]; webpageObject.webpageUrl = [ NSString stringWithUTF8String:url]; WXMediaMessage *message = [WXMediaMessage message]; message.title = [ NSString stringWithUTF8String:title]; message.description = [ NSString stringWithUTF8String:description]; // 用APP的Icon做缩略图 NSDictionary *infoPlist = [[ NSBundle mainBundle] infoDictionary]; NSString *icon = [[infoPlist valueForKeyPath: @"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles" ] lastObject]; [message setThumbImage:[ UIImage imageNamed:icon]]; message.mediaObject = webpageObject; SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; req.bText = NO ; req.message = message; req.scene = scene; [WXApi sendReq:req completion: nil ]; //判断是否安装微信 bool IsWechatInstalled_iOS() return [WXApi isWXAppInstalled];

    我这里实现了向微信注册APP、判断是否安装了微信App、分享链接至微信三个方法。要实现分享更多的媒体消息,比如图片、小程序等,请查看微信官方文档: developers.weixin.qq.com/doc/oplatfo… 写好之后同样将这个文件放入 Assets/Plugins/iOS 目录下。

    五、在Unity中调用NativeBridge.m中的方法

    public class WeChatController
        private string _APP_ID = "";
        #region iOS微信SDK
    #if !UNITY_EDITOR && UNITY_IOS
        [DllImport("__Internal")]
        private static extern void RegisterApp(string appid);
        [DllImport("__Internal")]
        private static extern bool IsWechatInstalled_iOS();
        [DllImport("__Internal")]
        private static extern void ShareUrlToWX(int scene, string url, string title, string description);
    #endif
        #endregion
        private static WeChatController _instance;
        public static WeChatController Instance {
            get {
                if (_instance == null) {
                    _instance = new WeChatController();
                return _instance;
        /// <summary>
    	/// 初始化微信SDK, APPID是用户在微信开放平台注册是所分配的应用唯一标识, 可在微信开放平台找到
    	/// </summary>
    	/// <param name="APPID"></param>
    	public void Init(string APPID) {
            _APP_ID = APPID;
    #if !UNITY_EDITOR && UNITY_IOS
            RegisterApp(_APP_ID);
    #endif
        /// <summary>
    	/// 判断是否是否安装了微信
    	/// </summary>
    	/// <returns></returns>
        public bool IsWeChatAppInstalled() {
    #if !UNITY_EDITOR && UNITY_IOS
            return IsWechatInstalled_iOS();
    #endif
        /// <summary>
    	/// 分享链接至微信,缩略图用的是APP Icon
    	/// </summary>
    	/// <param name="scene">分享至什么场景, 0-对话、1-朋友圈、2-收藏</param>
    	/// <param name="url">网页链接</param>
    	/// <param name="title">标题</param>
    	/// <param name="description">描述</param>
        public void ShareWebpageToWX(int scene, string url, string title, string description) {
    #if !UNITY_EDITOR && UNITY_IOS
            ShareUrlToWX(scene, url, title, description);
    #endif
    

    之后就可以再Unity任意脚本中在合适的时机调用WeChatController.Instance.Init()、WeChatController.Instance.IsWeChatAppInstalled()、WeChatController.Instance.ShareWebpageToWX()这些方法。

    至此所有的逻辑部分都完成了,接下来就剩下在Xcode中对相关项进行设置了,但是我们不打算手动设置,而是通过代码自动设置,实现打包全程自动化,不需要人工参与设置参数或者修改代码。

    六、自动完成Xcode项目的各项设置

    主要是通过PostProcessBuild来实现。 在Unity项目的 Assets/Editor 目录下新建一个文件,比如XCodePostProcessBuild.cs 这个文件的目的就是自动设置Xcode项目的相关选项,具体每句代码设置的是什么内容,代码都有注释:

    using UnityEditor;
    using System.IO;
    using UnityEngine;
    #if UNITY_IOS && UNITY_EDITOR
    using UnityEditor.Callbacks;
    using UnityEditor.iOS.Xcode;
    #endif
    public static class XCodePostProcessBuild
    #if UNITY_IOS && UNITY_EDITOR
        private static readonly string[] csAddFrameworks = new string[]{
            "Security.framework","WebKit.framework", "CoreGraphics.framework"
        [PostProcessBuild(1)]
        public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
            if(BuildTarget.iOS != buildTarget)
                return;
            string projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
            SetFrameworksAndBuildSettings(projectPath);
            SetInfoList(pathToBuiltProject, "com.yourapp.bundleApp", "wx_APP_ID");
            SetAssociatedDomains(projectPath, "www.yourdomain.com");
        private static void SetFrameworksAndBuildSettings(string path)
            PBXProject proj = new PBXProject();
            proj.ReadFromString(File.ReadAllText(path));
            string target = proj.GetUnityMainTargetGuid();
            Debug.Log("Target Name is " + target);
            // 设置 BuildSettings
            proj.AddBuildProperty(target, "Other Linker Flags", "-Objc -all_load");
            proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
            //根据微信SDK文档的要求,加入相关的Frameworks
            for (int i = 0; i < csAddFrameworks.Length; ++i)
                if (!proj.ContainsFramework(target, csAddFrameworks[i]))
                    proj.AddFrameworkToProject(target, csAddFrameworks[i], false);
            File.WriteAllText(path, proj.WriteToString());        
        public static void SetInfoList(string buildPath, string wxUrlName, string wxScheme)
            string listPath = buildPath + "/Info.plist";
            PlistDocument plist = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(listPath));
            // 在“info”标签栏的“URL type“添加“URL scheme”,值为你在微信后台注册的应用程序的 AppID
            PlistElementArray urlArray = plist.root.CreateArray("CFBundleURLTypes");
            PlistElementDict dict = urlArray.AddDict();
            dict.SetString("CFBundleTypeRole", "Editor");
            dict.SetString("CFBundleURLName", wxUrlName);
            PlistElementArray urlSchemes = dict.CreateArray("CFBundleURLSchemes");
            urlSchemes.AddString(wxScheme);
            // 在 “info”标签栏的“LSApplicationQueriesSchemes“添加weixin wechat和weixinULAPI
            PlistElementArray wxArray = plist.root.CreateArray("LSApplicationQueriesSchemes");
            wxArray.AddString("weixin");
            wxArray.AddString("wechat");
            wxArray.AddString("weixinULAPI");
            File.WriteAllText(listPath, plist.WriteToString());
        // 设置Associated Domains
        public static void SetAssociatedDomains(string pbxProjectPath, string domainUrl)
            //默认 Target Name, 你自己的可能不一样
            string targetName = "Unity-iPhone";
            //Set the entitlements file name to what you want but make sure it has this extension
            string entitlementsFileName = "my_app.entitlements";
            var entitlements = new ProjectCapabilityManager(pbxProjectPath, entitlementsFileName, targetName);
            entitlements.AddAssociatedDomains(new string[] { "applinks:" + domainUrl });
            entitlements.WriteToFile();
    #endif
    

    注意,这个文件是放在Assets/Editor目录下。

    以上就是所有流程了,应该还是比较完整的,可能代码贴的多了点,不过这篇文章对照微信开发文档来看的话,应该还是很清晰易懂的:developers.weixin.qq.com/doc/oplatfo…

    最后,觉得不错的话记得点个赞呀! 原文链接:www.yuque.com/jooki/hcm4i…

    分类:
    阅读
    标签: