Unity Xcode方式接入sdk

入口

创建 GameAppController 类 继承 UnityAppController

并且在类的实现之前 需要 加 IMPL_APP_CONTROLLER_SUBCLASS(GameAppController),表明这个是程序的入口。UnityAppController 实现了 UIApplicationDelegate。 可以简单看下 UIApplicationDelegate 的生命周期。

例:

@interface GameAppController : UnityAppController

+ (instancetype)shareAppController;

- (UIWindow*)appWindow;
@end

实现

IMPL_APP_CONTROLLER_SUBCLASS(GameAppController)

@implementation GameAppController {

@end

Unity 与 Objective-C 交互

Unity 调用 Objective-C

#define UNITY_CS_API extern "C"

/**
  微信登陆
 */
UNITY_CS_API void OCWXLogin(){
     //objective-c 代码
}

Objective-C 调用 Unity 代码

void    UnitySendMessage(const char* obj, const char* method, const char* msg);

obj 参数 表示GameObject Name

method 参数 表示要回调的方法名

msg 参数 表示回调的方法参数

Objective-C 与 Unity 的交互要注意的是

字符串使用的是 const char* 类型,而Objective-C 中使用的是NSString* 所以需要转换

字符串作为返回值返回 需要使用 strup 函数。否则程序将闪退

返回值 不能返回null 和 nil 否则闪退。所以返回值每次增加判断,如果null和nil 就用空字符串替换

例子

// const char* 转 NSString*
static inline NSString * str_c2ns(const char*s){
    if (s) {
        return [NSString stringWithUTF8String:s];
    }else{
        return [NSString stringWithUTF8String:""];
    }
}

//NSString* 转 const char*
+ (const char *) str_ns2c:(NSString *) content{
    return [content UTF8String];
}

//返回值使用 strdup 处理, 并做检查
UNITY_CS_API const char* OCReadClipBoard(){
    NSString *contentStr = [CoreManager.sharedInstance readClipBoard];
    if (contentStr == NULL || contentStr == nil) {
        contentStr = @"";
    }
    return strdup([UnityUtility str_ns2c:contentStr]);
}

Objective-C 与 Unity 交互 有时会使用到Json 进行数据传输,Unity 中 Null 在 Objectiv-C 中解析将会报错,使用NullSafe 库解决. github地址

接入微信SDK

遇到报错

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[WXApi genExtraUrlByReq:withAppData:]: unrecognized selector sent to class

微信官方文档的解释是需要在 Other Linker Flags 中添加 -ObjC -all_load 进行处理。我加入-all_load 会导致编译报错,这个方法行不通。

首先sdk 的配置都是添加在 UnityFramework 而不是 Unity-iPhone 上。如果是老的Unity 应该只有 Unity-iPhone,那就是添加到Unity-iPhone上。

然后由于-all_load 行不通,所以用-force_load 代替。-force_load 后面需要加入libWeChatSDK.a 所在到路径作为参数

比如:

关于微信登录,或者分享失效,没有回调的情况,应该是漏写了调用

接入友盟 和 阿里支付

遇到UTDID 库冲突。这里阿里官方有解释,下载去除 UTDID 的库。 下载的地方有说明

阿里的文档让人最舒服,没遇上什么问题。

这个如果没有配置好,微信登录将会照成2次弹窗确认。(那种给别人加企业签的就一定会有二次弹窗,因为没有teamid)

这个比较简单,随便找一个模板,替换teamid后,上传至服务器。然后在xcode中Signing & Capabilities 中的Associated Domains 配置 applinks: 域名

打包

如果使用Unity直接到处会覆盖xcode中我们写好的代码。所以把我们接入sdk的xcode代码放入Unity项目的Plugins 文件夹的iOS文件夹中。项目没有就自己创建。并把所有的第三方库也放入其中。这样打包的时候会自动导出至xCode项目。

此外xcode项目中还有一些自定义的配置。这个需要在打包流程完成后的回调中使用代码修改。

例如

string pbxProjectPath = PBXProject.GetPBXProjectPath(locationPath);
            
            //修改 Associated Domains 设置
            ProjectCapabilityManager capabilityManager =
                new ProjectCapabilityManager(pbxProjectPath, "Unity-iPhone.entitlements", "Unity-iPhone");
            capabilityManager.AddAssociatedDomains(new string[]{"applinks:cs1.jxhappy.top"});
            
            //wifi 信息
            capabilityManager.AddAccessWiFiInformation();
            
            // 百度持续定位
            capabilityManager.AddBackgroundModes(BackgroundModesOptions.LocationUpdates);
            
            capabilityManager.WriteToFile();
            
            PBXProject pbxProject = new PBXProject();
            pbxProject.ReadFromFile(pbxProjectPath);
            
            // string xCodeFrameworkPath = "./XCodeFramework";
            //
            // DirectoryInfo directoryInfo = new DirectoryInfo(xCodeFrameworkPath);
            //
            // foreach (var directory in directoryInfo.GetDirectories())
            // {
            //     ECKAddResourceGroupToiOSProject(locationPath, pbxProject, pbxProject.GetUnityFrameworkTargetGuid(),
            //         directory.Name);
            // }
            
            // 为类使用 @try @catch NULLSafe 中使用到了;
            pbxProject.SetBuildProperty(pbxProject.ProjectGuid(),"GCC_ENABLE_OBJC_EXCEPTIONS","YES"); 
            
            //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.GetUnityFrameworkTargetGuid;

            pbxProject.AddFrameworkToProject(target,"CoreGraphics.framework",false);
            pbxProject.AddFrameworkToProject(target,"QuartzCore.framework",false);
            pbxProject.AddFrameworkToProject(target,"Foundation.framework",false);
            pbxProject.AddFrameworkToProject(target,"UIKit.framework",false);
            
            string targetUnityTarget = pbxProject.GetUnityFrameworkTargetGuid();
            
            //添加framework
            
            //微信sdk
            pbxProject.AddFrameworkToProject(targetUnityTarget,"Security.framework",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"CoreGraphics.framework",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"WebKit.framework",false);
            
            //支付宝sdk
            pbxProject.AddFrameworkToProject(targetUnityTarget,"libc++.tbd",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"libz.tbd",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"SystemConfiguration.framework",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"CoreTelephony.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"QuartzCore.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"CoreText.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget, "CoreGraphics.framework", false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"UIKit.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"Foundation.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"CFNetwork.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"CoreMotion.framework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"AlipaySDK.framework",false);
            
            //百度地图sdk
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"BMKLocationKit.framework",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"CoreLocation.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"SystemConfiguration.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"Security.framework",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"libsqlit3.0.tbd",false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget, "CoreTelephony.framework", false);
            //pbxProject.AddFrameworkToProject(targetUnityTarget,"libz.tbd",false);
            pbxProject.AddFrameworkToProject(targetUnityTarget,"AdSupport.framework",false);
            
            //UMengsdk
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMCommon.xcframework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMCommonLog.framework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMDevice.xcframework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMRemoteConfig.framework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UTDID.framework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UYuMao.framework",false);
            //
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMAPM.xcframework",false);
            // pbxProject.AddFrameworkToProject(targetUnityTarget,"UMLink.framework",false);
            
            //[WXApi genExtraUrlByReq:withAppData:]
            //报错 原因缺少 Wxapi genExtraUrlByReq 函数, 
            //-all_load 加载 所有的 静态链接库, 但是这个存在动态链接库的函数重复的问题,编译会报错
            //-force_load 强制 指定加载 静态链接库。
            pbxProject.AddBuildProperty(targetUnityTarget,"OTHER_LDFLAGS","-ObjC -force_load $SRCROOT/Libraries/Plugins/SDK/iOS/WechatSDK/libWeChatSDK.a");
            //pbxProject.AddFrameworkToProject(target,"WechatOpenSDK-XCFramework.xcframework",false);
            
            //Unity Tests
            string targetGuid = pbxProject.TargetGuidByName(PBXProject.GetUnityTestTargetName());
            pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
 
            //Unity Framework
            pbxProject.SetBuildProperty(targetUnityTarget, "ENABLE_BITCODE", "NO");
            pbxProject.SetBuildProperty(targetUnityTarget, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
            
            pbxProject.WriteToFile(pbxProjectPath);
            
            //修改 Info.plist 文件
            var plistPath = locationPath + "/Info.plist";
            var plist = new PlistDocument();
            plist.ReadFromFile(plistPath);

            PlistElementDict rootDict = plist.root;
            
            //设置LSApplicationQueriesSchemes(数组)
            PlistElementArray loginChannelsArr;
            loginChannelsArr = rootDict.CreateArray("LSApplicationQueriesSchemes");
            loginChannelsArr.AddString("weixin");
            loginChannelsArr.AddString("weixinULAPI");
            loginChannelsArr.AddString("weixinURLParamsAPI");
            
            //百度地图权限
            rootDict.SetString("NSLocationWhenInUseUsageDescription","前台定位");
            rootDict.SetString("NSLocationAlwaysUsageDescription", "永久定位");
            rootDict.SetString("NSLocationAlwaysAndWhenInUseUsageDescription","永久定位");
            
            //添加 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("wx528f8481cec8a716");

            PlistElementDict aliPay = urlTypes.AddDict();
            aliPay.SetString("CFBundleTypeRole","Editor");
            aliPay.SetString("CFBundleURLName","alipay");
            PlistElementArray aliUrlScheme = aliPay.CreateArray("CFBundleURLSchemes");
            aliUrlScheme.AddString("hjhaGameAliPay");
            
            plist.WriteToFile(plistPath);

接 苹果SDK 做上架准备

不得不吐槽一下,苹果文档真垃圾,真垃圾,真垃圾

Apple Pay 文档

  1. 沙盒模式的测试账号创建,提示This email address is not available for use as an Apple ID. You may already have an Apple ID associated with this address. Please try again or sign in using your existing Apple ID.

这个账号不是指你当前有的账号,也就是不能输入当前存在的账号,可以随便输入,但不能跟现有的账号重复。它只是测试的

  1. 接入Apple Pay 一直提示 付费应用程序协议有新版本。但是又没有给同意条款的入口。
    这个情况应该是还有别的事务还没有处理,或者别的事务还在审核,要等审核通过,才能进行同意条款
相关推荐
谢泽浩17 分钟前
Unity 给模型贴上照片
unity·游戏引擎
z2014z17 分钟前
Unity Resource System 优化笔记
unity·游戏引擎
王维志23 分钟前
Unity 高亮插件HighlightPlus介绍
unity·游戏引擎
zaizai10071 小时前
我的demo保卫萝卜中的技术要点
unity
crasowas2 小时前
Flutter问题记录 - 适配Xcode 16和iOS 18
flutter·ios·xcode
菌菌巧乐兹3 小时前
Unity 百度AI实现无绿幕拍照抠像功能(详解版)
人工智能·百度·unity
孑么17 小时前
C# 委托与事件 观察者模式
开发语言·unity·c#·游戏引擎·游戏程序
蒙娜丽宁19 小时前
Go语言错误处理详解
ios·golang·go·xcode·go1.19
wangduqiang74719 小时前
unity的学习
学习·unity·游戏引擎
@Sunset...20 小时前
Unity程序基础框架
unity·游戏引擎