Unity iOS 省心打包(二)

http://www.jianshu.com/p/f347e00abb9c

Unity iOS 省心打包(二)_第1张图片
Paste_Image.png
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;
using UnityEditor.iOS.Xcode;
using System.Collections.Generic;
using System.Linq;
using Babybus.Framework.Extension;

namespace Babybus.Builder
{
    public class BuildiOSPlayer : BuildPlayerBase
    {
        public const string projectFrameworks = "./../ProjectFrameworks";

        [PostProcessBuild]
        static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
        {
            if (target != BuildTarget.iOS)
                return;

            Debug.Log("pathToBuiltProject = " + pathToBuiltProject);

            EditProj(pathToBuiltProject);
            EditInfoPlist(pathToBuiltProject);

            if (Application.platform == RuntimePlatform.OSXEditor)
                Xcode2IPA(pathToBuiltProject);
        }

        static void Xcode2IPA(string pathToBuiltProject)
        {
            var workspace = BabySystem.workspace;
            Debug.Log(workspace);

            var channel = currentPackChannelItem.Channel;
            var ipaName = GetProductPath(currentPackChannelItem);
            var ipaPath = workspace + ipaName;

            var bashPath = Application.dataPath + "/BabyFramework/Shell/xcodebuild.sh";
            ProcessHelper.StartProcess("/bin/chmod", "+x " + bashPath);

            var xcodeVersion = EditorPrefs.GetString("JenkinsBuilder.xcodeVersion");
            if (xcodeVersion == "")
                xcodeVersion = "7.3.1";

            var mobileprovision = EditorPrefs.GetString("JenkinsBuilder.mobileprovision");
            mobileprovision = "\"" + mobileprovision + "\"";

            ProcessHelper.StartProcess("/bin/bash", bashPath + " /Applications/Xcode_" + xcodeVersion + ".app " + workspace + pathToBuiltProject + " " + ipaPath + " " + mobileprovision);
        }

        private static List GetBuildFiles(string path)
        {
            var directories = Directory.GetDirectories(path);

            var files = Directory.GetFiles(path).ToList();

            foreach (var directory in directories)
            {
                var name = Path.GetFileName(directory);

                if (name == ".svn")
                    continue;

                if (name == "Languages")
                    continue;

                if (name == "AdPlatform" && !BabySystem.HasAD())
                    continue;

#if BABYBUS_SHARE
                if (name == "WeChat" && !directory.Contains("UMSocial"))
                    continue;
#else
                if (name == "UMSocial")
                    continue;
#endif

                if (directory.EndsWith(".framework") || directory.EndsWith(".bundle") || directory.EndsWith(".xcassets"))
                    files.Add(directory);
                else
                    files.AddRange(GetBuildFiles(directory));
            }

            return files;
        }

        static void EditProj(string pathToBuiltProject)
        {
            var projPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";

            var pbxProj = new PBXProject();
            pbxProj.ReadFromFile(projPath);

            var targetGuid = pbxProj.TargetGuidByName("Unity-iPhone");
            //string debugConfig = pbxProj.BuildConfigByName(target, "Debug");
            //string releaseConfig = pbxProj.BuildConfigByName(target, "Release");
            //pbxProj.SetBuildPropertyForConfig(debugConfig, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
            //pbxProj.SetBuildPropertyForConfig(releaseConfig, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
            pbxProj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
            pbxProj.SetBuildProperty(targetGuid, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");

            var sign = EditorPrefs.GetString("JenkinsBuilder.sign", "iPhone Distribution: BABYBUS CO., LIMITED (AMSTN4PRF9)");
            pbxProj.SetBuildProperty(targetGuid, "CODE_SIGN_IDENTITY", sign);

            var provision = EditorPrefs.GetString("JenkinsBuilder.provision", "f4f9a377-57f0-4e0d-81c0-00904ac17378");
            pbxProj.SetBuildProperty(targetGuid, "PROVISIONING_PROFILE", provision);

            pbxProj.SetBuildProperty(targetGuid, "CODE_SIGN_ENTITLEMENTS", "Libraries/BabyFrameWork/Babybus.entitlements");

            pbxProj.SetBuildProperty(targetGuid, "GCC_C_LANGUAGE_STANDARD", "gnu99");

            var definitions = "BB_APP_3D";

            if (BabySystem.GetIsForKids())
                definitions += " BB_PUBLISH_KIDS";

            if (!BabySystem.HasAD())
                definitions += " BABYBUS_NOAD";

#if BABYBUS_SHARE
            definitions += " BABYBUS_SHARE";
#endif

            pbxProj.SetBuildProperty(targetGuid, "GCC_PREPROCESSOR_DEFINITIONS", definitions);

            pbxProj.AddFrameworkToProject(targetGuid, "AVKit.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "Security.framework", true);

            pbxProj.AddFrameworkToProject(targetGuid, "ImageIO.framework", true);

            pbxProj.AddFrameworkToProject(targetGuid, "AssetsLibrary.framework", true);

            if (BabySystem.HasAD())
                pbxProj.AddFrameworkToProject(targetGuid, "AdSupport.framework", true);

#if BABYBUS_TALK2KIKI
            pbxProj.AddFrameworkToProject(targetGuid, "AddressBook.framework", true);//讯飞语言识别需要用到
#endif

            pbxProj.AddFrameworkToProject(targetGuid, "EventKit.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "EventKitUI.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CFNetwork.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "WebKit.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CoreGraphics.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CoreTelephony.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CoreLocation.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "MessageUI.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "MediaPlayer.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CoreMotion.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "StoreKit.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "CoreMedia.framework", true);
            pbxProj.AddFrameworkToProject(targetGuid, "MobileCoreServices.framework", true);


            pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libsqlite3.dylib", "libsqlite3.dylib", PBXSourceTree.Sdk));
            pbxProj.AddFileToBuild(targetGuid, pbxProj.AddFile("usr/lib/libz.dylib", "libz.dylib", PBXSourceTree.Sdk));

            pbxProj.AddBuildProperty(targetGuid, "OTHER_LDFLAGS", "-ObjC");

            pbxProj.AddBuildProperty(targetGuid, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");
            pbxProj.AddBuildProperty(targetGuid, "HEADER_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");
            pbxProj.AddBuildProperty(targetGuid, "LIBRARY_SEARCH_PATHS", "$(SRCROOT)/Libraries/BabyFrameWork/**");

            var framework = BabySystem.workspace + projectFrameworks;

            var files = GetBuildFiles(framework);

            var compileFlags = new List()
            {
                "-fno-objc-arc"
            };

            string[] arcDirectories = { "/AFNetworking/", "/BabyBusPlayer/", "/HBRSAHandler/",
                                        "/SVPProgressHUD/", "/UIKit+AFNetworking/", "/Masonry/",
                                        "/UMSocial/"
                                      };

            foreach (var file in files)
            {
                var path = file.Replace("\\", "/");

                var projectPath = "Libraries/BabyFrameWork/" + path.Replace(framework, "");

                FileTools.CopyFileOrDirectory(path, pathToBuiltProject + "/" + projectPath, true);

                var fileGuid = pbxProj.AddFile(projectPath, projectPath, PBXSourceTree.Source);

                pbxProj.AddFileToBuild(targetGuid, fileGuid);

                if (path.EndsWith(".a") || path.EndsWith(".m") || path.EndsWith(".mm") || path.EndsWith(".c") || path.EndsWith(".cpp"))
                {
                    var hasCompileFlags = true;
                    foreach (var directory in arcDirectories)
                    {
                        if (path.Contains(directory))
                        {
                            hasCompileFlags = false;
                            break;
                        }
                    }

                    if (hasCompileFlags)
                        pbxProj.SetCompileFlagsForFile(targetGuid, fileGuid, compileFlags);
                }
            }


            var languages = Directory.GetDirectories(framework + "/Languages");

            foreach (var lprojPath in languages)
            {
                var lprojName = Path.GetFileName(lprojPath);

                if (!lprojName.EndsWith(".lproj"))
                    continue;

                if (BabySystem.IsArabicApp && lprojName != "ar.lproj" || !BabySystem.IsArabicApp && lprojName == "ar.lproj")
                    continue;

                var language = "";

                if (lprojName == "zh_CN.lproj" && BabySystem.IsLanguageSupported("zh"))
                    language = "zh";

                if (lprojName == "zh_TW.lproj" && BabySystem.IsLanguageSupported("zht"))
                    language = "zht";

                if (language == "")
                {
                    language = lprojName.Remove(lprojName.Length - ".lproj".Length);
                    if (!BabySystem.IsLanguageSupported(language))
                        continue;
                }

                var projectPath = lprojName;
                FileTools.CopyFileOrDirectory(lprojPath, pathToBuiltProject + "/" + projectPath, true);

                File.WriteAllText(pathToBuiltProject + "/" + projectPath + "/InfoPlist.strings", "\"CFBundleDisplayName\"=\"" + BabySystem.GetProductName(language) + "\";");

                var fileGuid = pbxProj.AddFolderReference(projectPath, projectPath, PBXSourceTree.Source);
                pbxProj.AddFileToBuild(targetGuid, fileGuid);
            }

            pbxProj.WriteToFile(projPath);
        }

        static void EditInfoPlist(string filePath)
        {
            var path = filePath + "/Info.plist";

            var plistDocument = new PlistDocument();
            plistDocument.ReadFromFile(path);

            var dict = plistDocument.root.AsDict();

            var array = dict.CreateArray("CFBundleURLTypes");
            var dict2 = array.AddDict();
            dict2.SetString("CFBundleURLName", PlayerSettings.bundleIdentifier);
            var array2 = dict2.CreateArray("CFBundleURLSchemes");
            array2.AddString(PlayerSettings.bundleIdentifier);

            var wxappid = BuildProductKeys.GetValue("ios_um_wxappid");
            if (!string.IsNullOrEmpty(wxappid))
            {
                dict2 = array.AddDict();
                dict2.SetString("CFBundleURLName", "weixin");
                array2 = dict2.CreateArray("CFBundleURLSchemes");
                array2.AddString(wxappid);
            }

            var qqappid = BuildProductKeys.GetValue("ios_um_qqappid");
            if (!string.IsNullOrEmpty(qqappid))
            {
                dict2 = array.AddDict();
                dict2.SetString("CFBundleURLName", "");
                array2 = dict2.CreateArray("CFBundleURLSchemes");
                array2.AddString("tencent" + qqappid);

                dict2 = array.AddDict();
                dict2.SetString("CFBundleURLName", "");
                array2 = dict2.CreateArray("CFBundleURLSchemes");
                array2.AddString("QQ" + int.Parse(qqappid).ToString("X"));
            }

            var sinakey = BuildProductKeys.GetValue("ios_um_sinakey");
            if (!string.IsNullOrEmpty(sinakey))
            {
                dict2 = array.AddDict();
                dict2.SetString("CFBundleURLName", "");
                array2 = dict2.CreateArray("CFBundleURLSchemes");
                array2.AddString("wb" + sinakey);
            }

            //[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];
            dict2 = array.AddDict();
            dict2.SetString("CFBundleURLName", "");
            array2 = dict2.CreateArray("CFBundleURLSchemes");
            array2.AddString("prefs");

            dict.SetString("CFBundleIdentifier", Application.bundleIdentifier);

            var lines = File.ReadAllText("iOS产品白名单").Split('\n');

            array = dict.CreateArray("LSApplicationQueriesSchemes");

            foreach (var line in lines)
            {
                array.AddString(line.Replace("\r", "").Replace("\n", ""));
            }

            dict.SetString("View controller-based status bar appearance", "NO");

            plistDocument.WriteToFile(path);
        }
    }
}

xcodebuild.sh

#!/bin/sh

xcodePath=$1
projectPath=$2

archivePath="build/Unity-iPhone.xcarchive"
exportPath=$3 #Unity-iPhone.ipa
provisioningProfile=$4 #iOS_Distribution

cd $projectPath

${xcodePath}/Contents/Developer/usr/bin/xcodebuild -scheme Unity-iPhone clean archive -archivePath $archivePath
${xcodePath}/Contents/Developer/usr/bin/xcodebuild -exportArchive -exportFormat ipa -archivePath $archivePath -exportPath $exportPath -exportProvisioningProfile "$provisioningProfile"


# ${xcodePath}/Contents/Developer/usr/bin/xcodebuild build

# cd ${projectPath}/build/Release-iphoneos/

# ${xcodePath}/Contents/Developer/usr/bin/xcrun -sdk iphoneos packageapplication -v *.app -o $exportPath

exit $?

你可能感兴趣的:(Unity iOS 省心打包(二))