官方教程:iOS接入指南 | 微信开放文档
我是用cocoapods集成的,因为手动集成老有下面这个问题,一时解决不了
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[WXApi genExtraUrlByReq:withAppData:]: unrecognized selector sent to class
- Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[WXApi genExtraUrlByReq:withAppData:]: unrecognized selector sent to class
复制代码 一、安装cocoapods
1、安装Homebrew
国内源:HomebrewCN: Homebrew 国内安装脚本,快速部署 brew ,国内镜像
这个源真的很棒,安装很快。
安装Homebrew
- /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
复制代码 2、安装cocoapods
二、接入微信登录
1、下载微信sdk
前往下载基本信息 | 微信开放文档,打开压缩文件
我把三个文件放在Plugins/iOS/文件夹下的同一个文件夹内了
2、编写ObjectiveC代码调用微信api
创建WeChatUnity.mm、WXApiManager.h、WXApiManager.mm这三个文件,文件也放在Plugins/iOS/文件夹下
代码内容如下,参考网上大佬的:
WeChatUnity.mm
- // WeChatUnity.mm
- #import <Foundation/Foundation.h>
- #import "WXApiManager.h"
- #import <UIKit/UIKit.h>
- #import <WXApi.h>
- #define UNITY_CS_API extern "C"
- static NSString *mWXAppid = nil;
- // 将c字符串const char* 转为 oc字符串NSString
- static inline NSString * str_c2ns(const char*s)
- {
- if (s)
- return [NSString stringWithUTF8String: s];
- else
- return [NSString stringWithUTF8String: ""];
- }
- // 初始化
- UNITY_CS_API void WeChatInit(const char* appId, const char* universalLink)
- {
- NSLog(@"WeChatInit");
- //在register之前打开log, 后续可以根据log排查问题,第一次测试sdk时可以取消注释
- // [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
- // NSLog(@"WeChatSDK: %@", log);
- // }];
- // 向微信注册
- mWXAppid = str_c2ns(appId);
- NSString *link = str_c2ns(universalLink);
- NSLog(@"init: %@ %@", mWXAppid, link);
- [WXApi registerApp:mWXAppid universalLink:link];
- // 调用自检函数,第一次测试sdk时可以取消注释
- // [WXApi checkUniversalLinkReady:^(WXULCheckStep step, WXCheckULStepResult* result) {
- // NSLog(@"%@, %u, %@, %@", @(step), result.success, result.errorInfo, result.suggestion);
- // }];
- }
- // WeChatUnity.mm
- UNITY_CS_API void WeChatLogin(const char* state)
- {
- NSLog(@"WeChatLogin");
- SendAuthReq* req = [[SendAuthReq alloc] init];
- req.scope = @"snsapi_userinfo";;
- req.state = str_c2ns(state);
- [WXApi sendReq:req completion:nil];
- // 此时会拉起微信,授权后会回调WXApiManager的onResp方法
- }
复制代码 WXApiManager.h
- // WXApiManager.h
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
- #import "WXApi.h"
- // @end
- @interface WXApiManager : UIResponder<UIApplicationDelegate, WXApiDelegate>
- @property (strong, nonatomic) UIWindow *window;
- + (instancetype)sharedManager;
- @end
复制代码 WXApiManager.mm
- #import "WXApiManager.h"
- @implementation WXApiManager
- // 单例
- +(instancetype)sharedManager {
- static dispatch_once_t onceToken;
- static WXApiManager *instance;
- dispatch_once(&onceToken, ^{
- instance = [[WXApiManager alloc] init];
- });
- return instance;
- }
- // WXApiManager.mm
- - (void)onResp:(BaseResp *)resp {
- if ([resp isKindOfClass:[SendAuthResp class]]) {
- NSLog(@"微信授权回调");
- if (resp.errCode == 0) {
- UnitySendMessage("UnityAndroidConnector", "WeChatLoginSuccess", ((SendAuthResp *)resp).code.UTF8String);
- }
- else
- {
- // 失败,回调给Unity
- NSString *stringNumber = [NSString stringWithFormat:@"%d", resp.errCode];
- UnitySendMessage("UnityAndroidConnector", "WeChatLoginFail", stringNumber.UTF8String);
- }
- }
- }
- - (void)onReq:(BaseReq *)req {
- // TODO 微信回调,从微信端主动发送过来的请求
- }
- @end
复制代码 创建xxxAppController.mm文件,我这里叫CustomAppController,也放在Plugins/iOS/文件夹下
CustomAppController.mm,内容如下
- // CustomAppController.mm
- #import "WXApiManager.h"
- #import "UnityAppController.h"
- @interface CustomAppController : UnityAppController
- @end
- IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)
- @implementation CustomAppController
- - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
- {
- [super application:application didFinishLaunchingWithOptions:launchOptions];
-
- // 可以在这里自动注册微信,也可以在手动调用WeChatUnity.mm的WeChatInit进行注册
- // [WXApi registerApp:@"wx123123123" universalLink:@"https://xxx.com/app/"];
-
- return YES;
- }
- - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
- return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
- }
- - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
- return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
- }
- - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
- {
- return [WXApi handleOpenUniversalLink:userActivity delegate:[WXApiManager sharedManager]];
- }
- @end
复制代码 3、编写Unity代码调用和处理回调
调用方法如下:
- void iOSInit()
- {
- WeChatInit("wx12312312", "https://www.xxx.com/app/");
- }
- void iOSLogin()
- {
- WeChatLogin("app_wechat");
- }
- [DllImport("__Internal")]
- static extern void WeChatInit(string appId, string universalLink);
- [DllImport("__Internal")]
- static extern void WeChatLogin(string state);
复制代码 回调处理:UnityAndroidConnector.cs
- public class UnityAndroidConnector : MonoSingleton<UnityAndroidConnector>
- {
-
- public void WeChatLoginSuccess(string code)
- {
- // 传给服务器
- }
- public void WeChatLoginFail(string codestr)
- {
- int code = int.Parse(codestr);
- // 错误码处理
- }
- }
复制代码 WXApiManager.mm中的UnitySendMessage方法里的参数就对应UnityAndroidConnector.cs里的方法。
记得:UnityAndroidConnector.cs必要挂载在名为UnityAndroidConnector的组件上,即组件名和脚本名保持一致,这个名字你也可以取你喜欢的
- UnitySendMessage("UnityAndroidConnector", "WeChatLoginSuccess", ((SendAuthResp *)resp).code.UTF8String);
- UnitySendMessage("UnityAndroidConnector", "WeChatLoginFail", stringNumber.UTF8String);
复制代码 三、打包
1、引入External Dependency Manager for Unity
GitHub - googlesamples/unity-jar-resolver: Unity plugin which resolves Android & iOS dependencies and performs version management
打开设置,Assets--External Dependency Manager--iOS Resolver--Settings,设置我这边用的是默认的,然后 Always add the main target to Podfile 这个设置取消勾选(否则会在Build Phases--Link Binary With Libraries里添加上一个Pod_xxxx_framework,打包时会报错,必要手动删除)
2、创建xxxDependencies.xml
在任意Editor文件夹下创建一个xxxDependencies.xml,用于cocoapods打包用,我这里是WechatDependencies.xml
WechatDependencies.xml
- <?xml version="1.0" encoding="utf-8"?>
- <dependencies>
- <iosPods>
- <iosPod name="WechatOpenSDK-XCFramework" bitcodeEnabled="true" > </iosPod>
- </iosPods>
- </dependencies>
复制代码 3、xcode配置
直接用脚本配置xcode配置项,该脚本也必要放在任意Editor文件夹下
- using UnityEditor;
- using UnityEditor.Build;
- using UnityEditor.Build.Reporting;
- using UnityEngine;
- #if UNITY_IOS
- using UnityEditor.iOS.Xcode;
- class iOSBuildTool : IPostprocessBuildWithReport
- {
- public int callbackOrder { get { return 0; } }
- public void OnPostprocessBuild(BuildReport report)
- {
- if (report.summary.platform == BuildTarget.iOS)
- {
- string projectPath = report.summary.outputPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
- PBXProject pbxProject = new PBXProject();
- pbxProject.ReadFromFile(projectPath);
- //Disabling Bitcode on all targets
- //Main
- string target = pbxProject.GetUnityMainTargetGuid();
- pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
- pbxProject.SetBuildProperty(target, "CONFIGURATION", "Release");
- pbxProject.SetBuildProperty(target, "CONFIGURATION_BUILD_DIR", "$(BUILD_DIR)/$(CONFIGURATION)");
- pbxProject.SetBuildProperty(target, "OTHER_LDFLAGS", "-ObjC -all_load -lstdc++ -lsqlite3");
- // 添加framework
- pbxProject.AddFrameworkToProject(target, "Security.framework", false);
- pbxProject.AddFrameworkToProject(target, "CoreGraphics.framework", false);
- pbxProject.AddFrameworkToProject(target, "WebKit.framework", false);
- //Unity Tests
- string targetGuid = pbxProject.TargetGuidByName(PBXProject.GetUnityTestTargetName());
- pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
- //Unity Framework
- string frameworkTarget = pbxProject.GetUnityFrameworkTargetGuid();
- pbxProject.SetBuildProperty(frameworkTarget, "ENABLE_BITCODE", "NO");
- pbxProject.SetBuildProperty(frameworkTarget, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO");
- // 写入
- pbxProject.WriteToFile(projectPath);
- // 修改Info.plist文件
- var plistPath = report.summary.outputPath + "/Info.plist";
- var plist = new PlistDocument();
- plist.ReadFromFile(plistPath);
- PlistElementDict rootDict = plist.root;
- // example of adding a boolean key...
- //设置LSApplicationQueriesSchemes(数组)
- PlistElementArray loginChannelsArr;
- loginChannelsArr = rootDict.CreateArray("LSApplicationQueriesSchemes");
- loginChannelsArr.AddString("weixin");
- loginChannelsArr.AddString("weixinULAPI");
- loginChannelsArr.AddString("weixinURLParamsAPI");
- // 添加 url scheme
- PlistElementArray urlTypes = rootDict.CreateArray("CFBundleURLTypes");
- PlistElementDict wxUrl = urlTypes.AddDict();
- wxUrl.SetString("CFBundleTypeRole", "Editor");
- wxUrl.SetString("CFBundleURLName", "weixin");
- PlistElementArray wxUrlScheme = wxUrl.CreateArray("CFBundleURLSchemes");
- wxUrlScheme.AddString("wx12312312");
- // 是否加密
- rootDict.SetBoolean("ITSAppUsesNonExemptEncryption", false);
- // 麦克风权限
- rootDict.SetString("NSMicrophoneUsageDescription", "允许访问您的麦克风,以便您能够在xxxx中使用语音功能");
- // 应用修改
- plist.WriteToFile(plistPath);
- //xxx是项目得名称,一定要修改成对应的项目名称
- ProjectCapabilityManager projectCapabilityManager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", "Unity-iPhone");
- // 添加关联域名
- projectCapabilityManager.AddAssociatedDomains(new string[] {
- "applinks:www.xxx.com",
-
- });
- // 添加通知
- // projectCapabilityManager.AddPushNotifications(true);
- projectCapabilityManager.WriteToFile();
- }
- }
- }
- #endif
复制代码 4、Unity--Build Settings--Build
打包后运行.xcworkspace这个工程,别运行xcodeproj那个工程,然后真机测试。
大致流程应该就这些,有问题就参考一下官方辣鸡教程或者其他大佬的方法。
关于Universal Link的阐明
微信开发者后台必要配置Universal Link,一般格式为https://xxx.com/yyy/,xxx.com就是你的域名,yyy就是path
同时必要在你的域名根目次下或者.well-known目次下有一个apple-app-site-association文件,大致内容如下,内容格式为json格式,但文件不带任何后缀名(即你可以先创建一个json文件,保存好后删除文件名里的'.json'后缀)。
- {
- "applinks": {
- "apps": [],
- "details": [
- {
- "appID": "teamid.bundle_id",
- "paths": ["/app/*"]
- }
- ]
- }
- }
复制代码 teamid可在apple开发者后台拿到,网上搜一下就知道了;bundle_id就是你Unity项目的包名com.xxx.xxxx;paths里的app就对应上面说的app,后面记得加一个‘*’号。
还和Universal Link有关的就是上面提到的WeChatUnity.mm和CustomAppController.mm里的微信注册,那个universalLink的值就是Universal Link,即https://xxx.com/app/,而xcode配置脚本里的applink则是域名,即www.xxx.com,别搞错了。
在安装了你的app的手机safari欣赏器地址输入你的Universal Link加随机码(如https://xxx.com/app/abc),转到这个链接时,顶部应该是能出现打开你的app的下拉窗口的,这就表现你的Universal Link配置正确了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |