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 一直提示 付费应用程序协议有新版本。但是又没有给同意条款的入口。
    这个情况应该是还有别的事务还没有处理,或者别的事务还在审核,要等审核通过,才能进行同意条款
相关推荐
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
_oP_i2 小时前
unity webgl部署到iis报错
unity
Go_Accepted2 小时前
Unity全局雾效
unity
向宇it3 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
每日出拳老爷子5 小时前
【图形渲染】【Unity Shader】【Nvidia CG】有用的参考资料链接
unity·游戏引擎·图形渲染
北海65166 小时前
Dots 常用操作
unity
YY-nb14 小时前
Unity Apple Vision Pro 开发教程:物体识别跟踪
unity·游戏引擎·apple vision pro
Cool-浩14 小时前
Unity 开发Apple Vision Pro物体识别追踪ObjectTracking
unity·ar·apple vision pro·mr·物体识别·vision pro教程·objecttracking
向宇it1 天前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则
Cool-浩1 天前
Unity 开发Apple Vision Pro空间锚点应用Spatial Anchor
unity·游戏引擎·apple vision pro·空间锚点·spatial anchor·visionpro开发