WebView のカスタマイズ
Xamarin.Forms の WebView
は、アプリに Web コンテンツと HTML コンテンツを表示するビューです。 この記事では、JavaScript から C# コードを呼び出せるように WebView
を拡張するカスタム レンダラーを作成する方法について説明します。
すべての Xamarin.Forms ビューには、ネイティブ コントロールのインスタンスを作成する各プラットフォーム用のレンダラーが付属しています。 Xamarin.Forms アプリケーションによって WebView
がレンダリングされると、iOS では WkWebViewRenderer
クラスがインスタンス化され、それによってネイティブの WkWebView
コントロールもインスタンス化されます。 Android プラットフォーム上では、WebViewRenderer
クラスによってネイティブの WebView
コントロールがインスタンス化されます。 ユニバーサル Windows プラットフォーム (UWP) 上では、WebViewRenderer
クラスによってネイティブの WebView
コントロールがインスタンス化されます。 Xamarin.Forms コントロールによってマップされるレンダラーとネイティブ コントロール クラスの詳細については、「Renderer Base Classes and Native Controls」(レンダラーの基底クラスおよびネイティブ コントロール) を参照してください。
次の図に、View
と、それを実装する、対応するネイティブ コントロールの関係を示します。
レンダリング プロセスを使用して各プラットフォーム上の WebView
にカスタム レンダラーを作成することで、プラットフォームのカスタマイズを実装することができます。 これを行うための実行プロセスは次のとおりです。
HybridWebView
カスタム コントロールを作成します。- Xamarin.Forms から
HybridWebView
を使用します。 - 各プラットフォーム上で
HybridWebView
のカスタム レンダラーを作成します。
Xamarin.FormsWebView
を強化して、JavaScript から C# コードを呼び出すことができる HybridWebView
レンダラーを実装するために、各項目について順番に説明します。 HybridWebView
インスタンスは、ユーザーに名前の入力を求める HTML ページを表示するために使用されます。 それからユーザーが HTML ボタンをクリックすると、JavaScript 関数によって、ユーザー名を含むポップアップを表示する C# Action
が呼び出されます。
JavaScript から C# を呼び出すプロセスの詳細については、「JavaScript から C# を呼び出す」を参照してください。 HTML ページの詳細については、「Web ページの作成」を参照してください。
Note
WebView
は、C# から JavaScript 関数を呼び出して、呼び出し元の C# コードに結果を返すことができます。 詳細については、「JavaScript の呼び出し」を参照してください。
HybridWebView の作成
HybridWebView
カスタム コントロールは、WebView
クラスをサブクラス化することによって作成できます。
public class HybridWebView : WebView
{
Action<string> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
HybridWebView
カスタム コントロールは、.NET Standard ライブラリ プロジェクトで作成され、コントロール用に次の API を定義します。
- 読み込まれる Web ページのアドレスを指定する
Uri
プロパティ。 Action
をコントロールに登録するRegisterAction
メソッド。 登録済みのアクションは、Uri
プロパティで参照される HTML ファイルに含まれる JavaScript から呼び出されます。- 登録済みの
Action
への参照を削除するCleanUp
メソッド。 - 登録済みの
Action
を呼び出すInvokeAction
メソッド。 このメソッドは、各プラットフォームのプロジェクトのカスタム レンダラーから呼び出されます。
HybridWebView の使用
HybridWebView
カスタム コントロールは、その場所の名前空間を宣言し、カスタム コントロール上で名前空間プレフィックスを使用することで .NET Standard ライブラリ プロジェクトの XAML で参照することができます。 次のコード例は、XAML ページがどのように HybridWebView
カスタム コントロールを使用できるかを示しています。
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
x:Class="CustomRenderer.HybridWebViewPage"
Padding="0,40,0,0">
<local:HybridWebView x:Name="hybridWebView"
Uri="index.html" />
</ContentPage>
local
名前空間プレフィックスには任意の名前を付けることができます。 ただし、clr-namespace
と assembly
の値は、カスタム コントロールの詳細と一致させる必要があります。 名前空間が宣言されると、プレフィックスを使用してカスタム コントロールが参照されます。
次のコード例は、C# ページがどのように HybridWebView
カスタム コントロールを使用できるかを示しています。
public HybridWebViewPageCS()
{
var hybridWebView = new HybridWebView
{
Uri = "index.html"
};
// ...
Padding = new Thickness(0, 40, 0, 0);
Content = hybridWebView;
}
HybridWebView
インスタンスは、各プラットフォーム上でネイティブ Web コントロールを表示するために使用されます。 Uri
プロパティは、各プラットフォームのプロジェクトに格納されている HTML ファイルに設定され、ネイティブの Web コントロールによって表示されます。 レンダリングされた HTML は、HTML ボタンのクリックに応答して C# Action
を呼び出す JavaScript 関数を使用して、ユーザーに名前を入力するように求めます。
HybridWebViewPage
は、次のコード例に示すように、JavaScript から呼び出されるアクションを登録します。
public partial class HybridWebViewPage : ContentPage
{
public HybridWebViewPage()
{
// ...
hybridWebView.RegisterAction(data => DisplayAlert("Alert", "Hello " + data, "OK"));
}
}
このアクションから、モーダル ポップアップを表示する DisplayAlert
メソッドが呼び出されます。このポップアップには、HybridWebView
インスタンスによって表示される HTML ページに入力された名前が示されます。
カスタム レンダラーを各アプリケーション プロジェクトに追加して、C# コードを JavaScript から呼び出すことで、プラットフォームの Web コントロールを強化することができます。
各プラットフォーム上でのカスタム レンダラーの作成
カスタム レンダラー クラスを作成するプロセスは次のとおりです。
- iOS で
WkWebViewRenderer
クラスのサブクラス、Android と UWP でWebViewRenderer
クラスを作成して、カスタム コントロールをレンダリングします。 WebView
をレンダリングするOnElementChanged
メソッドをオーバーライドし、ロジックを書き込んでカスタマイズします。 このメソッドは、HybridWebView
オブジェクトが作成されるときに呼び出されます。ExportRenderer
属性をカスタム レンダラー クラスまたは AssemblyInfo.cs に追加して、Xamarin.Forms カスタム コントロールのレンダリングに使用されるように指定します。 この属性は、Xamarin.Forms にカスタム レンダラーを登録するために使用されます。
Note
ほとんどの Xamarin.Forms 要素では、プラットフォーム プロジェクトごとにカスタム レンダラーを指定するかどうかは任意です。 カスタム レンダラーが登録されていない場合は、コントロールの基底クラスの既定のレンダラーが使用されます。 ただし、View 要素をレンダリングするときは、各プラットフォーム プロジェクトにカスタム レンダラーが必要です。
次の図に、サンプル アプリケーション内の各プロジェクトの役割と、それらの関係を示します。
HybridWebView
カスタム コントロールはプラットフォームのレンダラー クラスによってレンダリングされます。このクラスは iOS では WkWebViewRenderer
クラスから、Android と UWP では WebViewRenderer
クラスから派生します。 この結果、次のスクリーンショットに示すように、ネイティブの Web コントロールを使用してそれぞれの HybridWebView
カスタム コントロールがレンダリングされます。
WkWebViewRenderer
クラスと WebViewRenderer
クラスは OnElementChanged
メソッドを公開します。このメソッドは、該当するネイティブ Web コントロールをレンダリングするために、Xamarin.Forms カスタム コントロールの作成時に呼び出されます。 このメソッドでは、OldElement
および NewElement
プロパティを含む VisualElementChangedEventArgs
パラメーターを受け取ります。 これらのプロパティは、レンダラーがアタッチされていた Xamarin.Forms 要素と、レンダラーが現在アタッチされている Xamarin.Forms 要素をそれぞれ表しています。 サンプル アプリケーションでは、OldElement
プロパティが null
になり、NewElement
プロパティに HybridWebView
インスタンスへの参照が含まれます。
各プラットフォームのレンダラー クラス内の、オーバーライドされたバージョンの OnElementChanged
メソッドは、ネイティブの Web コントロールのカスタマイズを行う場所です。 レンダリングされている Xamarin.Forms コントロールへの参照は、Element
プロパティを使用して取得することができます。
各カスタム レンダラー クラスは、レンダラーを Xamarin.Forms に登録する ExportRenderer
属性で修飾されます。 この属性は、レンダリングされている Xamarin.Forms カスタム コントロールの型名と、カスタム レンダラーの型名という 2 つのパラメーターを受け取ります。 属性の assembly
プレフィックスにより、属性がアセンブリ全体に適用されることが指定されます。
以下のセクションでは、各ネイティブ Web コントロールによって読み込まれる Web ページの構造、JavaScript から C# を呼び出すプロセス、各プラットフォームのカスタム レンダラー クラスでこれを実装する方法について説明します。
Web ページの作成
次のコード例は、HybridWebView
カスタム コントロールによって表示される Web ページを示しています。
<html>
<body>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<h1>HybridWebView Test</h1>
<br />
Enter name: <input type="text" id="name">
<br />
<br />
<button type="button" onclick="javascript: invokeCSCode($('#name').val());">Invoke C# Code</button>
<br />
<p id="result">Result:</p>
<script type="text/javascript">function log(str) {
$('#result').text($('#result').text() + " " + str);
}
function invokeCSCode(data) {
try {
log("Sending Data:" + data);
invokeCSharpAction(data);
}
catch (err) {
log(err);
}
}</script>
</body>
</html>
この Web ページでは、ユーザーは input
要素に名前を入力することができます。また、クリックすると C# コードを呼び出すbutton
要素が用意されています。 これを実現するプロセスは次のとおりです。
- ユーザーが
button
要素をクリックすると、invokeCSCode
JavaScript 関数が呼び出され、input
要素の値が関数に渡されます。 invokeCSCode
関数からは、C#Action
に送信されているデータを表示するlog
関数が呼び出されます。 次に、C#Action
を呼び出すinvokeCSharpAction
メソッドが呼び出され、input
要素から受け取ったパラメーターが渡されます。
invokeCSharpAction
JavaScript 関数は Web ページで定義されておらず、各カスタム レンダラーによって挿入されます。
iOS の場合、この HTML ファイルは、BundleResource のビルド アクションと一緒に、プラットフォーム プロジェクトの Content フォルダーに置かれます。 Android の場合、この HTML ファイルは、AndroidAsset のビルド アクションと一緒にプラットフォーム プロジェクトの Assets/Content フォルダーに置かれます。
JavaScript から C# を呼び出す
JavaScript から C# を呼び出すプロセスは、各プラットフォームで同じです。
- カスタム レンダラーによってネイティブ Web コントロールが作成され、
HybridWebView.Uri
プロパティに指定された HTML ファイルが読み込まれます。 - Web ページが読み込まれると、カスタム レンダラーによって
invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。 - ユーザーが名前を入力して HTML
button
要素をクリックすると、invokeCSCode
関数が呼び出され、次にinvokeCSharpAction
関数が呼び出されます。 invokeCSharpAction
関数によってカスタム レンダラーのメソッドが呼び出され、次にHybridWebView.InvokeAction
メソッドが呼び出されます。- 登録済みの
Action
を呼び出すHybridWebView.InvokeAction
メソッド。
以下のセクションでは、各プラットフォームでこのプロセスがどのように実装されるかについて説明します。
iOS 上でのカスタム レンダラーの作成
次のコード例は、iOS プラットフォーム用のカスタム レンダラーを示します。
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.iOS
{
public class HybridWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
WKUserContentController userController;
public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
{
}
public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
{
userController = config.UserContentController;
var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
userController.AddScriptMessageHandler(this, "invokeAction");
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
HybridWebView hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
string filename = Path.Combine(NSBundle.MainBundle.BundlePath, $"Content/{((HybridWebView)Element).Uri}");
LoadRequest(new NSUrlRequest(new NSUrl(filename, false)));
}
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
((HybridWebView)Element).InvokeAction(message.Body.ToString());
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
HybridWebViewRenderer
クラスによって、HybridWebView.Uri
プロパティに指定された Web ページがネイティブの WKWebView
コントロールに読み込まれ、invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。 ユーザーが名前を入力して HTML button
要素をクリックすると、invokeCSharpAction
JavaScript 関数が実行され、Web ページからメッセージが受信された後に DidReceiveScriptMessage
メソッドが呼び出されます。 さらに、このメソッドによって HybridWebView.InvokeAction
メソッドが呼び出され、ポップアップを表示する登録済みのアクションが呼び出されます。
この関数は、次のように実現されます。
- レンダラー コンストラクターによって
WkWebViewConfiguration
オブジェクトが作成され、そのWKUserContentController
オブジェクトが取得されます。WkUserContentController
オブジェクトにより、メッセージの投稿とユーザー スクリプトの Web ページへの挿入が可能になります。 - レンダラー コンストラクターにより
WKUserScript
オブジェクトが作成されます。これにより、Web ページが読み込まれた後に、invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。 - レンダラー コンストラクターによって、
WKUserContentController.AddUserScript
メソッドが呼び出され、WKUserScript
オブジェクトがコンテンツ コントローラーに追加されます。 - レンダラー コンストラクターによって
WKUserContentController.AddScriptMessageHandler
メソッドが呼び出され、WKUserContentController
オブジェクトにinvokeAction
というスクリプト メッセージ ハンドラーが追加されます。その結果、WKUserContentController
オブジェクトを使用するすべてのWebView
インスタンス内のすべてのフレームで JavaScript 関数window.webkit.messageHandlers.invokeAction.postMessage(data)
が定義されます。 - カスタム レンダラーが新しい Xamarin.Forms 要素にアタッチされている場合:
WKWebView.LoadRequest
メソッドによって、HybridWebView.Uri
プロパティに指定された HTML ファイルが読み込まれます。 このコードにより、ファイルがプロジェクトのContent
フォルダーに格納されることが指定されます。 Web ページが表示されると、invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。
- レンダラーがアタッチされている要素が変更されると、リソースが解放されます。
- レンダラーが破棄されると、Xamarin.Forms 要素がクリーンアップされます。
Note
WKWebView
クラスは、iOS 8 以降でのみサポートされています。
さらに、次の値を含むように、Info.plist を更新する必要があります。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Android 上でのカスタム レンダラーの作成
次のコード例は、Android プラットフォーム用のカスタム レンダラーを示します。
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.Droid
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
((HybridWebView)Element).Cleanup();
}
if (e.NewElement != null)
{
Control.SetWebViewClient(new JavascriptWebViewClient(this, $"javascript: {JavascriptFunction}"));
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl($"file:///android_asset/Content/{((HybridWebView)Element).Uri}");
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
HybridWebViewRenderer
クラスによって、HybridWebView.Uri
プロパティに指定された Web ページがネイティブの WebView
コントロールに読み込まれます。また、Web ページの読み込みが完了した後に、JavascriptWebViewClient
クラスの OnPageFinished
オーバーライドを使用して、invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。
public class JavascriptWebViewClient : FormsWebViewClient
{
string _javascript;
public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript) : base(renderer)
{
_javascript = javascript;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript(_javascript, null);
}
}
ユーザーが名前を入力して HTML button
要素をクリックすると、invokeCSharpAction
JavaScript 関数が実行されます。 この関数は、次のように実現されます。
- カスタム レンダラーが新しい Xamarin.Forms 要素にアタッチされている場合:
SetWebViewClient
メソッドによりWebViewClient
の実装として新しいJavascriptWebViewClient
オブジェクトが設定されます。WebView.AddJavascriptInterface
メソッドによって、新しいJSBridge
インスタンスが WebView の JavaScript コンテキストのメイン フレームに挿入され、jsBridge
と名前が付けられます。 これにより、JavaScript からJSBridge
クラスのメソッドにアクセスできるようになります。WebView.LoadUrl
メソッドによって、HybridWebView.Uri
プロパティに指定された HTML ファイルが読み込まれます。 このコードにより、ファイルがプロジェクトのContent
フォルダーに格納されることが指定されます。JavascriptWebViewClient
クラスでは、Web ページの読み込みが完了すると、invokeCSharpAction
JavaScript 関数がページに挿入されます。
- レンダラーがアタッチされている要素が変更されると、リソースが解放されます。
- レンダラーが破棄されると、Xamarin.Forms 要素がクリーンアップされます。
invokeCSharpAction
JavaScript 関数が実行されると、次に JSBridge.InvokeAction
メソッドが呼び出されます。これを次のコード例に示します。
public class JSBridge : Java.Lang.Object
{
readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
public JSBridge(HybridWebViewRenderer hybridRenderer)
{
hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
}
[JavascriptInterface]
[Export("invokeAction")]
public void InvokeAction(string data)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
{
((HybridWebView)hybridRenderer.Element).InvokeAction(data);
}
}
}
このクラスは Java.Lang.Object
から派生する必要があります。また、JavaScript に公開されるメソッドは [JavascriptInterface]
および [Export]
属性で修飾する必要があります。 そのため、invokeCSharpAction
JavaScript 関数が Web ページに挿入され、実行されると、[JavascriptInterface]
および [Export("invokeAction")]
属性で修飾されているため、JSBridge.InvokeAction
メソッドが呼び出されます。 さらに、InvokeAction
メソッドによって HybridWebView.InvokeAction
メソッドが呼び出され、ポップアップを表示する登録済みのアクションが呼び出されます。
重要
[Export]
属性を使用する Android プロジェクトには、Mono.Android.Export
への参照が含まれている必要があります。含まれていない場合は、コンパイラ エラーが発生します。
JSBridge
クラスは WeakReference
を HybridWebViewRenderer
クラスに保持する点に注意してください。 これは、2 つのクラス間に循環参照を作成しないようにするためです。 詳細については、「弱い参照」を参照してください。
UWP 上でのカスタム レンダラーの作成
次のコード例は、UWP 用のカスタム レンダラーを示します。
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.UWP
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.external.notify(data);}";
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.NavigationCompleted -= OnWebViewNavigationCompleted;
Control.ScriptNotify -= OnWebViewScriptNotify;
}
if (e.NewElement != null)
{
Control.NavigationCompleted += OnWebViewNavigationCompleted;
Control.ScriptNotify += OnWebViewScriptNotify;
Control.Source = new Uri($"ms-appx-web:///Content//{((HybridWebView)Element).Uri}");
}
}
async void OnWebViewNavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
{
if (args.IsSuccess)
{
// Inject JS script
await Control.InvokeScriptAsync("eval", new[] { JavaScriptFunction });
}
}
void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
{
((HybridWebView)Element).InvokeAction(e.Value);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
HybridWebViewRenderer
クラスによって、HybridWebView.Uri
プロパティに指定された Web ページがネイティブの WebView
コントロールに読み込まれます。また、Web ページの読み込みが完了した後に、WebView.InvokeScriptAsync
メソッドを使用して invokeCSharpAction
JavaScript 関数が Web ページに挿入されます。 ユーザーが名前を入力して HTML button
要素をクリックすると、invokeCSharpAction
JavaScript 関数が実行され、Web ページから通知が受信された後に OnWebViewScriptNotify
メソッドが呼び出されます。 さらに、このメソッドによって HybridWebView.InvokeAction
メソッドが呼び出され、ポップアップを表示する登録済みのアクションが呼び出されます。
この関数は、次のように実現されます。
- カスタム レンダラーが新しい Xamarin.Forms 要素にアタッチされている場合:
NavigationCompleted
およびScriptNotify
イベントのイベント ハンドラーが登録されています。NavigationCompleted
イベントは、ネイティブのWebView
コントロールが現在のコンテンツの読み込みを完了したとき、またはナビゲーションが失敗したときに発生します。ScriptNotify
イベントは、ネイティブのWebView
コントロールのコンテンツが JavaScript を使用して文字列をアプリケーションに渡したときに発生します。 Web ページは、string
パラメーターを渡しながらwindow.external.notify
を呼び出してScriptNotify
イベントを発生させます。WebView.Source
プロパティは、HybridWebView.Uri
プロパティに指定された HTML ファイルの URI に設定されます。 このコードでは、ファイルがプロジェクトのContent
フォルダーに格納されることを想定しています。 Web ページが表示されると、NavigationCompleted
イベントが発生し、OnWebViewNavigationCompleted
メソッドが呼び出されます。 ナビゲーションが正常に完了した場合、WebView.InvokeScriptAsync
メソッドを使用してinvokeCSharpAction
JavaScript 関数が Web ページに挿入されます。
- レンダラーがアタッチされている要素が変更されると、イベントのサブスクライブが解除されます。
- レンダラーが破棄されると、Xamarin.Forms 要素がクリーンアップされます。