LoginSignup
9
3

More than 5 years have passed since last update.

UnityのiOSビルド時のplist設定の自動化

Posted at

はじめに

UnityもC#も知らないのにUnityプロジェクトのiOSビルドの設定の自動化やってと言われたときの備忘録。

Unity iOS ビルド設定 とかでググればいっぱい出てきたので楽勝やん!と思ったのですがわりと苦労したので同じ境遇の方の助けになれば...

やりたいこと

  • iOSのビルド後にCapabilitiesのBackground ModesをONにする
  • Background Modesにaudioとbluetoothを設定する
  • plistのRequired device capabilitiesにbluetooth-leを設定する

u_capability

u_blue

とりあえず試したこと(失敗)

下記のファイルをUnityのプロジェクトのAssets/Editor配下に入れてビルドする。
plistのキーとかは一度適当なXcodeプロジェクトで設定したものをコピペ。

using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.iOS.Xcode;
using UnityEditor.Callbacks;
using System.Collections;

public class XcodeSettingsPostProcesser
{
    [PostProcessBuildAttribute (0)]
    public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
    {
        if (buildTarget != BuildTarget.iOS) return; 

        var projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";

        SetCapability(projectPath); 
        SetPlist(projectPath); 
    }

    public static void SetCapability(string path) 
    {
        var proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(path));

        string targetName = "Unity-iPhone";
        string target = proj.TargetGuidByName(targetName);
        proj.AddCapability(target, PBXCapabilityType.BackgroundModes);

        File.WriteAllText(projPath, proj.WriteToString());
    }

    public static void SetPlist(string path) 
    {
        var plistPath = Path.Combine (path, "Info.plist");
        var plist = new PlistDocument ();
        plist.ReadFromFile (plistPath);

        var capabilities = plist.root.CreateArray("Required device capabilities");
        capabilities.AddString("bluetooth-le");

        var backgroundModes = plist.root.CreateArray("Required background modes");
        backgroundModes.AddString("App plays audio or streams audio/video using AirPlay");
        backgroundModes.AddString("App communicates using CoreBluetooth");      
        plist.WriteToFile (plistPath);
    }
}

その結果がこれ

u_capability_no

u_plist

できてるようで何もできていない。
Required device capabilitiesもRequired background modesも2つあるしCapabilitiesタブのBackground Modesには何もチェックがついていない。

ちょっと工夫(失敗)

2つできるのはplistのところでCreateArrayしてるからだと思う。ここをみると普通にthis[string]でDictionaryみたいにアクセスできるっぽい。
下記のように修正。

    public static void SetPlist(string path) 
    {
        var plistPath = Path.Combine (path, "Info.plist");
        var plist = new PlistDocument ();
        plist.ReadFromFile (plistPath);

        var capabilities = plist.root["Required device capabilities"].toArray();
        capabilities.AddString("bluetooth-le");

        var backgroundModes = plist.root["Required background modes"].toArray();
        backgroundModes.AddString("App plays audio or streams audio/video using AirPlay");
        backgroundModes.AddString("App communicates using CoreBluetooth");      
        plist.WriteToFile (plistPath);
    }

ビルドするとplistに何も追加されなかった...

plistに値が追加された1個目のやつをあらためて確認。コピペしたけど綴りが違う?と思い検索をかけてみた。すると下記のようにRequired device capabilitiesが一件しか引っかからない!!

u_search

とりあえず下記のようにInfo.plistを開いてみた。

u_plist_code

u_plist_result

Required device capabilitiesとUIRequiredDeviceCapabilitiesがある?キーが違う!!

修正

キーと値を下記のように修正し、keyがある場合とない場合の処理のチェックも入れた。

    public static void SetPlist(string path) 
    {
        var plistPath = Path.Combine (path, "Info.plist");
        var plist = new PlistDocument ();
        plist.ReadFromFile (plistPath);

        PlistElementArray capabilities;
        if (plist.root.values.ContainsKey("UIRequiredDeviceCapabilities")) {
            capabilities = plist.root["UIRequiredDeviceCapabilities"].toArray();
        } else {
            capabilities = plist.root.CreateArray("UIRequiredDeviceCapabilities");
        }
        capabilities.AddString("bluetooth-le");

        PlistElementArray backgroundModes;
        if (plist.root.values.ContainsKey("UIBackgroundModes")) {
            backgroundModes = plist.root["UIBackgroundModes"].toArray();
        } else {
            backgroundModes = plist.root.CreateArray("UIBackgroundModes");
        }
        backgroundModes.AddString("audio");
        backgroundModes.AddString("bluetooth-central");     
        plist.WriteToFile (plistPath);
    }

できた!!

下記に表示されているキーと実際のキーは違うっていうのは何となく知っていたけど今まで気にしたことがなかった。
ちなみに下記にRequired device capabilitiesと打つと勝手にUIRequiredDeviceCapabilitiesに変換してくれるらしい。

u_plist

よくみると参考サイトもCFBundleURLSchemesとか使ってた...

さいごに

とりあえずはできましたがもっとスマートなやり方があれば教えてください。

Info.plistにそんな変換機能があるとは知らなかった新しいことをやるのは勉強になるな〜。

参考

UnityでXcodeの設定を自動化する方法まとめ

Unity iOSビルド時にURLスキームを追加するだけのPostProcessBuild

Unity5のPostProcessBuildでXcode Capabilityの設定する方法

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3