プラグインを使って、Unity が WWW クラスのリクエスト制御に使用しているデフォルトのコードを置き換える事ができます。例えは、デフォルトのキャッシングで、URL を単独でキャッシュする動作を変更したい場合などに行います。
以下のコードは(詳細も以下で説明)、デフォルトのキャッシング方法を無効にし、 “secret” という名のヘッダーフィールドをリクエストします。ヘッダーは、ゲームのスクリプトコードから設定します。
// Code placed at Plugins/iOS/CustomConnection.mm within the Assets folder.
#include "Unity/WWWConnection.h"
@interface UnityWWWCustomRequestProvider : UnityWWWRequestDefaultProvider
{
}
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers;
@end
@implementation UnityWWWCustomRequestProvider
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers
{
NSMutableURLRequest* request = [super allocRequestForHTTPMethod:method url:url headers:headers];
// let's pretend for security reasons we dont want ANY cache nor cookies
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPShouldHandleCookies:NO];
// let's pretend we want special secret info in header
[request setValue:@"123456789"forHTTPHeaderField:@"Secret"];
return request;
}
@end
@interface UnityWWWCustomConnectionDelegate : UnityWWWConnectionDelegate
{
}
@end
@implementation UnityWWWCustomConnectionDelegate
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
// we dont want caching
return nil;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
// let's just print something here for test
[super connection:connection didReceiveResponse:response];
if([response isMemberOfClass:[NSHTTPURLResponse class]])
::printf_console("We've got response with status: %d\n", [(NSHTTPURLResponse*)response statusCode]);
}
@end
IMPL_WWW_DELEGATE_SUBCLASS(UnityWWWCustomConnectionDelegate);
IMPL_WWW_REQUEST_PROVIDER(UnityWWWCustomRequestProvider);
先ほどのコードを分解して説明していきます。まず、接続するための編集された NSURLRequest オブジェクトを提供するための UnityWWWRequestDefaultProvider のサブクラスを作成します。他のオプションは UnityWWWRequestProvider プロトコルをシンプルに実装する最低限のものです。しかしこの場合、Unityの既存コードを使用します。
@interface UnityWWWCustomRequestProvider : UnityWWWRequestDefaultProvider
{
}
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers;
@end
allocRequestForHTTPMethod
のアクションは、スーパークラス上の同じメソッドを呼び出すことで開始されます。
@implementation UnityWWWCustomRequestProvider
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers
{
NSMutableURLRequest* request = [super allocRequestForHTTPMethod:method url:url headers:headers];
そして、iOS によってデフォルトデータのキャッシングとクッキーを無効にします。
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPShouldHandleCookies:NO];
次に、 “Secret” という名の、いくらかデータを追加できるヘッダーフィールドを追加します。実際のゲーム中は、接続のソースが正しいかどうかを確かめるために、サーバーから値がチェックされる事があります。
[request setValue:@"123456789"forHTTPHeaderField:@"Secret"];
カスタムリクエストのハンドリングクラスを作成します。また、UnityWWWConnectionDelegate
のサブクラスを作成して接続のハンドリングをカスタマイズする必要があります。
@interface UnityWWWCustomConnectionDelegate : UnityWWWConnectionDelegate
{
}
@end
connection:willCacheResponse:
メソッドから nil を返すことにより、データのキャッシュを向こうにすることができます。
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
// we dont want caching
return nil;
}
接続を処理できる connection:didReceiveResponse:
から実際のデータを取得するためにスーパークラスの同じメソッドを呼び出す必要があります。ここでは、接続が発生したときに、単にメッセージをコンソールに出力しているだけですが、自由に実装を行うことができます。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// let's just print something here for test
[super connection:connection didReceiveResponse:response];
if([response isMemberOfClass:[NSHTTPURLResponse class]])
::printf_console("We've got response with status: %d\n", [(NSHTTPURLResponse*)response statusCode]);
}
最後に、新しい接続のデリゲートとリクエストプロバイダーをUnityに登録します。そうすることでスクリプトからWWWリクエストを呼び出すことができるようになります。
IMPL_WWW_DELEGATE_SUBCLASS(UnityWWWCustomConnectionDelegate);
IMPL_WWW_REQUEST_PROVIDER(UnityWWWCustomRequestProvider);
カスタムコードは WWW クラスをUnityで使用することに対して透過的です。余分な C#/JS スクリプトを追加する必要はありません。