WWW 클래스가 포함된 요청을 처리할 때 플러그인을 사용하여 Unity가 사용하는 디폴트 코드를 대체할 수 있습니다. 예를 들어, 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);
코드는 다음과 같이 분석할 수 있습니다. 첫째, 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
{
// 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);
커스텀 코드는 Unity 의 WWW 클래스 사용에 영향을 미치지 않습니다. 즉, C# 스크립트에 코드를 더 추가하지 않아도 됩니다.