はじめに
Androidに引き続き、iOS側でもNativePluginの作成方法をまとめました。
ここでは、UnityでiOSのNativeアラートを表示させるまでの忘却録です。
Unity向けのiOS Pluginは作り方は人によって違うと思いますが、
今回は『UnityのiOSビルド結果であるXcodeプロジェクト上からコードを編集しました。』
もっと効率の良いやり方があればご教授下さい><;
Android版↓
環境
macOS Catalina: 10.15.7
Unity 2018.4.19f
Xcode12.4
Swift4.0
UnityとiOS Pluginの構成
Unityから書き出されるiOS関連のファイルはObjective-CベースなのでSwiftを呼び出す設定が必要です。
SwiftからObjective-Cのクラスに呼ぶには、宣言されてるヘッダーファイルを特定のヘッダーファイルでimportして使用します。
今回はObjective-C++
のコードを経由させます。
呼び出しの簡易図は下記。
UnityのC#がインターフェース(.csファイル)
↑↓
↓↑
iOSネイティブ Objective-C++ Cインターフェース(.mmファイル)
↓↑
↓↑
iOSネイティブ Swiftコード(.swiftファイル)
Unity側の対応(呼び出し方法)サンプル
ボタンを押下してアラート表示は、Androidの時の対応と同様な構成にしています。
ここでのポイントは下記です。
①、[DllImport("__Internal")]
属性を付けること。
ネイティブプラグイン参照
using System.Runtime.InteropServices;
using UnityEngine;
public class ButtonView : MonoBehaviour
{
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void _showAlert();
#endif
public void ShowNativeDialog() {
#if UNITY_IOS && !UNITY_EDITOR
_showAlert();
#endif
}
}
Unity上でSwiftファイル、Objective-C++のファイルを準備
Assets
→Plugin
→iOS
ディレクトリが無ければ作成します。
ここにNativePluginのファイルを置きます。
AlertPlugin.swift
、AlertPlugin.mm
ファイルを作成。中身は空です。
ビルド周りのEditor拡張が必要
やることは下記です。
①、Swiftのバージョン指定する(今回はSwift4.0)
②、Objective-C Bridging Header
の設定
③、Objective-C Generated Interface Header Name
の設定
上記を設定していきますが、便利なPluginが既に用意されてるのでこちらを参考にさせて頂きました。
Assets
→Editer
→PostProcessor.cs
こちらにファイルを作ります。
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;
namespace UnitySwift {
public static class PostProcessor {
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath) {
if(buildTarget == BuildTarget.iOS) {
var projPath = buildPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
var proj = new PBXProject();
proj.ReadFromFile(projPath);
string xcodeTarget = proj.TargetGuidByName("Unity-iPhone");
proj.AddBuildProperty(xcodeTarget, "SWIFT_VERSION", "4.0");
proj.SetBuildProperty(xcodeTarget, "ENABLE_BITCODE", "NO");
proj.SetBuildProperty(xcodeTarget, "SWIFT_OBJC_BRIDGING_HEADER", "Libraries/Plugins/iOS/UnitySwift-Bridging-Header.h");
proj.SetBuildProperty(xcodeTarget, "SWIFT_OBJC_INTERFACE_HEADER_NAME", "Unity-iPhone-Swift.h");
proj.AddBuildProperty(xcodeTarget, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks");
proj.WriteToFile(projPath);
}
}
}
}
UnitySwift-Bridging-Header.h
Swiftから呼び出すObjファイルをimportします。
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "UnityInterface.h"
ビルドしてiOSプロジェクトを書き出す
File
→Build Settings
→Build
で書き出されるディレクトリ名を決めて作成。
Unity-iPhone.xcodeproj
をXcodeで展開します。
Xcode上での作業
Xcodeを開くと下記のようなディレクトリ構造になっています。
AlertのコードはUnity-iPhone
→Libraries
→Plugins
→iOS
に内包されてます。
Unityで追加したファイルはLibraries
に入るみたいです。
先程、ビルド周りのEditer拡張で指定した下記はこちらに設定されていますので、確認します。
①、Swiftのバージョン指定する(今回はSwift4.0)
②、Objective-C Bridging Header
の設定
③、Objective-C Generated Interface Header Name
の設定
Swiftコードは下記です。ここで必要なことは下記です。
①、クラスは NSObject を継承する
②、クラスのスコープを public にする
※ public
にするのは、Objective-C++
から直接呼び出したいクラスおよびメソッドだけでも良い。
③、メソッドに@objcを付ける
public class AlertPlugin : NSObject {
@objc static func showAlert() {
let alertView = UIAlertController(title: "Title", message: "AlertMessage", preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler:nil)
let cancelButton = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler:nil)
alertView.addAction(okAction)
alertView.addAction(cancelButton)
UIApplication.shared.keyWindow?.rootViewController?.present(alertView, animated: true, completion: nil)
}
}
Objective-C++コードです。ここでのポイントは、下記です。
①、extern "C"
宣言でCインターフェイスを作成。
②、Objective-C Generated Interface Header Name
で設定しているUnity-iPhone-Swift.h
をimportすること。
これをimportするとObjective-C++
のクラスのように呼び出すことができる。
#import "Unity-iPhone-Swift.h"
extern "C"
{
void _showAlert()
{
[AlertPlugin showAlert];
}
}
実機確認
成果物
参考