WWW クラスでリクエストを処理するときに Unity が使うデフォルトのコードを置き換えるには、プラグインを使いきます。 例えは、URL だけに基づいてキャッシュするデフォルトのキャッシュの挙動を変えることができます。
以下のコードは (詳細は後述を参照)、デフォルトのキャッシュの方法を無効にし、ゲームのスクリプトコードから特定したヘッダーに加え、「秘密」のヘッダーフィールドをリクエストに追加します。
// Asset フォルダー内の Plugins/iOS/CustomConnection.mm のコード
#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];
// 安全上の理由でキャッシュ、クッキーをまったく使いたくない、としましょう
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPShouldHandleCookies:NO];
// ヘッダーに特別な秘密の (secret) 情報が必要だということにしましょう
[request setValue:@"123456789"forHTTPHeaderField:@"Secret"];
return request;
}
@end
@interface UnityWWWCustomConnectionDelegate : UnityWWWConnectionDelegate
{
}
@end
@implementation UnityWWWCustomConnectionDelegate
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
// キャッシュは必要ありません
return nil;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
// テストのために、ここに何かをプリントしてみましょう
[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);
先ほどのコードを詳しく説明していきます。まず、UnityWWWRequestDefaultProvider のサブクラスを作成し、接続のための変更した NSURLRequest オブジェクトを提供します。他の方法は単に、クラスに 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
{
// キャッシュは必要ありません
return nil;
}
connection:didReceiveResponse:
から接続自体を処理することができます。connection:didReceiveResponse:
は実際のデータを取得するためにスーパークラスの同じメソッドを呼び出します。ここでは、接続が発生したときに、単にメッセージをコンソールに出力するだけですが、任意に実装できます。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// テストのために、ここに何かをプリントしてみましょう
[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);
カスタムコードは、Unity内で WWW クラスを使用することに対して影響を与えません。そのため、余分な C# スクリプトを追加する必要はありません。