栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Unity SDK相关总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Unity SDK相关总结

文章目录
    • 1 安卓相关
      • 1.0 Android打包
      • 1.1 Unity Android打包原理
      • 1.2 注意事项
      • 1.3 关于原生代码修改
    • 2 IOS相关
      • 2.1 打包流程
      • 2.2 AppController.mm模板
      • 2.3 XCode库引用
    • 3 自动化构建
    • 4 其他

1 安卓相关 1.0 Android打包

需要jdk,sdk,大概是1.7~1.8的jdk太高的版本可能不行。

1.1 Unity Android打包原理

Unity大概是构建了一个只有一个MainActivity的原生安卓,然后将C#的代码跨平台转换成java的UnityPlayer类,在Unity工程Plugins/Android下的库文件则会成为安卓工程的库文件。

1.2 注意事项

/// 1 AndroidManifest.xml,Unity的Bundle Identifier,SDK开发者申请的推送包名。3个包名必须一致
/// 2 AndroidManifest中不仅更换package,同名的一些属性都要替换
/// 3 AndroidManifest更换AppKey
/// 4 jPush.aar必须在Assets/Plugins/Android下,其他目录不被识别
/// 5 多个SDK中的AndroidManifest的权限需要合并

1.3 关于原生代码修改

aar文件是安卓导出的带有资源的模块,想要修改原生代码可以在aar对应的工程下修改,然后重新导出aar。

2 IOS相关 2.1 打包流程

同安卓,要将库文件丢到Plugins/iOS路径下,不可修改路径。
在mac上打包完成后得到一份xcode工程,需要额外导入一些库以及修改AppController.mm。
然后再xcode上编译出ipa即可。证书相关不做介绍。

2.2 AppController.mm模板

Unity提供了模板机制可以在打包完成后的回调中自动修改AppController.mm,免去每次打包都要修改参数的问题。

其中类名必须为XXXAppController.mm格式

// ******************************************************************
//       / /|       @file       WarGameAppController.mm
//        V/        @brief      自定义IOS AppController
//       | "")       @author     Shadowrabbit, yingtu0401@gmail.com
//       /  |                    
//      /  \        @Modified    2021-11-04 06:54:35
//    *(___        @Copyright   Copyright (c)  2021, Shadowrabbit
// ******************************************************************

//可以在编译后的xcode工程里插入一些代码

//极光推送start
#import "JPUSHService.h"
#import "JPushEventCache.h"
#import 
//#import  //如需使用广告标识符 IDFA 则添加该头文件,否则不添加。
//极光推送end

#import  "UnityAppController.h"

@interface WarGameAppController : UnityAppController
@end

IMPL_APP_CONTROLLER_SUBCLASS (WarGameAppController) //告知Unity使用我们自定义的Controller

@implementation WarGameAppController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [[JPushEventCache sharedInstance] handFinishLaunchOption:launchOptions];
  
  [JPUSHService setupWithOption:launchOptions appKey:@"[JPushAppKey]" channel:@"" apsForProduction:NO];
  
//  NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
//  [JPUSHService setupWithOption:launchOptions appKey:@"替换成你自己的 Appkey" channel:@"" apsForProduction:NO SadvertisingIdentifier:advertisingId];
  [super application:application didFinishLaunchingWithOptions:launchOptions];
  return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  // Required.
  [JPUSHService registerDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  // Required.
  [[JPushEventCache sharedInstance] sendEvent:userInfo withKey:@"JPushPluginReceiveNotification"];
  [JPUSHService handleRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler {
  [[JPushEventCache sharedInstance] sendEvent:userInfo withKey:@"JPushPluginReceiveNotification"];
}

@end
2.3 XCode库引用

Unity同样提供了回调函数可供我们在打包完成后向XCode工程添加库依赖。

[PostProcessBuild]
public static void onPostprocessBuild(BuildTarget buildTarget, string path)
{
    if (buildTarget == BuildTarget.iOS)
    {
        string projPath = PBXProject.GetPBXProjectPath(path);
        PBXProject proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(projPath));
        string target = proj.GetUnityframeworkTargetGuid();
        //极光推送相关start
        proj.AddframeworkToProject(target, "CFNetwork.framework", false);
        proj.AddframeworkToProject(target, "CoreFoundation.framework", false);
        proj.AddframeworkToProject(target, "CoreTelephony.framework", false);
        //proj.AddframeworkToProject(target, "SystemConfiguration.framework", false);
        proj.AddframeworkToProject(target, "CoreGraphics.framework", false);
        proj.AddframeworkToProject(target, "Foundation.framework", false);
        proj.AddframeworkToProject(target, "UIKit.framework", false);
        proj.AddframeworkToProject(target, "Security.framework", false);
        proj.AddframeworkToProject(target, "libz.tbd", false); //(Xcode 7 以下版本是 libz.dylib)
        proj.AddframeworkToProject(target, "AdSupport.framework", false);
        proj.AddframeworkToProject(target, "UserNotifications.framework", false);
        proj.AddframeworkToProject(target, "libresolv.tbd",
            false); //(JPush 2.2.0 及以上版本需要,Xcode 7 以下版本是 libresolv.dylib)
        proj.AddframeworkToProject(target, "WebKit.framework", false);
        //极光推送相关end
        //拷贝添加第三方framework
        proj.AddBuildProperty(target, "frameWORK_SEARCH_PATHS", "$(PROJECT_DIR)/frameworks");
        proj.SetBuildProperty(target, "USYM_UPLOAD_AUTH_TOKEN", "0000-0000-0000-0000-000000");
        proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
        proj.SetBuildProperty(target, "MinimumOSVersion", "9.0");
        string main = proj.GetUnityMainTargetGuid();
        proj.SetBuildProperty(main, "USYM_UPLOAD_AUTH_TOKEN", "0000-0000-0000-0000-000000");
        proj.SetBuildProperty(main, "ENABLE_BITCODE", "NO");
        proj.SetBuildProperty(main, "MinimumOSVersion", "9.0");
        //保存project
        File.WriteAllText(projPath, proj.WriteToString());
        //修改Plist
        string plistPath = path + "/Info.plist";
        Plistdocument plist = new Plistdocument();
        plist.ReadFromString(File.ReadAllText(plistPath));
        PlistElementDict rootDict = plist.root;
        rootDict.SetString("NSMicrophoneUsageDescription", "麦克风");
        rootDict.SetBoolean("UIFileSharingEnabled", true); //设置Application.persistentDataPath目录共享,可以通过itune打开
        rootDict.SetBoolean("FirebaseAppStoreReceiptURLCheckEnabled", false);
        //保存plist
        File.WriteAllText(plistPath, plist.WriteToString());
    }
}
3 自动化构建

我们可以在打包前进行一些SDK相关的参数处理,比如把AppKey配置到表格里动态获取,免得频繁更换带来繁琐工作量。
Manifest清单文件中的包名更换和AppKey更换。AppController模板中的AppKey更换。可以配合Jenkins从Jenkins获取一部分参数,其余的根据表格获取。

 private const string DefaultAndroidPackageName = "xx.xx.xx"; //安卓默认包名
 private const string DefaultIosPackageName = "xx.xx.xx"; //IOS默认包名
 private const string AppKeyNameKey = "[JPushAppKey]"; //WarGameAppController.mm 与 Manifest的appKey占位符
 private const string PackageNameKeyInJenkins = "BundleIdentifier"; //Jenkins上的包名的键
 private const string PackageNameKey = "[PackageName]"; //安卓Manifest上的包名占位符

/// 
/// 极光SDK相关参数修改
/// 
private static void SetAndroidJPushSetting()
{
    //安卓清单文件包名替换 AppKey替换
    var packageName = GameUtility.GetEnvString(PackageNameKeyInJenkins);
    if (string.IsNullOrEmpty(packageName))
    {
        packageName = DefaultAndroidPackageName;
        CommonLog.Error(MAuthor.WY2, $"从Jenkins没有获取到包名,使用默认:{DefaultAndroidPackageName}");
    }

    if (!CfgSdkJPush.TryGetCfg(packageName, out var cfg))
    {
        CommonLog.Error(MAuthor.WY2,
            $"没有找到包名:{packageName}的极光推送配置!packageNameKeyInJenkins:{PackageNameKeyInJenkins}");
        return;
    }

    var appKey = cfg.JPushAppKey;
    try
    {
        var readFileSteam = new FileStream(ManifestPath, FileMode.Open, FileAccess.Read);
        var steamReader = new StreamReader(readFileSteam);
        var con = steamReader.ReadToEnd();
        con = con.Replace(PackageNameKey, packageName);
        con = con.Replace(AppKeyNameKey, appKey);
        steamReader.Close();
        readFileSteam.Close();
        var writeFileSteam = new FileStream(ManifestPath, FileMode.Open, FileAccess.Write);
        var steamWriter = new StreamWriter(writeFileSteam);
        steamWriter.WriteLine(con);
        steamWriter.Close();
        writeFileSteam.Close();
    }
    catch (Exception e)
    {
        CommonLog.Error(MAuthor.WY2, e.ToString());
        throw;
    }
}

/// 
/// 极光SDK相关参数修改
/// 
private static void SetIosJPushSetting()
{
    //IOS 模板AppKey替换
    var packageName = GameUtility.GetEnvString(PackageNameKeyInJenkins);
    if (string.IsNullOrEmpty(packageName))
    {
        packageName = DefaultIosPackageName;
        CommonLog.Error(MAuthor.WY2, $"从Jenkins没有获取到包名,使用默认:{DefaultIosPackageName}");
    }

    if (!CfgSdkJPush.TryGetCfg(packageName, out var cfg))
    {
        CommonLog.Error(MAuthor.WY2,
            $"没有找到包名:{packageName}的极光推送配置!packageNameKeyInJenkins:{PackageNameKeyInJenkins}");
        return;
    }

    var appKey = cfg.JPushAppKey;
    try
    {
        var readFileSteam = new FileStream(AppControllerPath, FileMode.Open, FileAccess.Read);
        var steamReader = new StreamReader(readFileSteam);
        var con = steamReader.ReadToEnd();
        con = con.Replace(AppKeyNameKey, appKey);
        steamReader.Close();
        readFileSteam.Close();
        var writeFileSteam = new FileStream(AppControllerPath, FileMode.Open, FileAccess.Write);
        var steamWriter = new StreamWriter(writeFileSteam);
        steamWriter.WriteLine(con);
        steamWriter.Close();
        writeFileSteam.Close();
    }
    catch (Exception e)
    {
        CommonLog.Error(MAuthor.WY2, e.ToString());
        throw;
    }
}

/// 
/// 加载表格
/// 
private static void LoadXlsx()
{
    //参数设置回调触发时,表格还没有初始化 手动加载表格
    CfgSdkJPush.GetAllCfg().Clear();
    ConfigLoader.loadDir = Path.GetFullPath(Application.dataPath + "/../../warconfig/_csv_client");
    CfgSdkJPush.Load();
}
4 其他

推送是依赖进程长链接实现的,理论上游戏进程被杀死就不会再收到推送了,但SDK可以做到依靠其他接入SDK的应用来传递消息,比如一直开着QQ,其他的应用推送消息可以走QQ的通道推送给用户。
还有就是系统级的厂商SDK推送,要接入小米、华为、oppo、vivo之类的厂商sdk,每个都要注册企业账号,比较麻烦。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/571376.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号