Version: 2019.1
인앱 구매(IAP)를 위한 애플리케이션 준비
앱 감량

iOS에서 WWW 요청 커스터마이즈

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# 스크립트에 코드를 더 추가하지 않아도 됩니다.


  • 2018–06–14 일부 편집 리뷰를 거쳐 페이지 수정됨
인앱 구매(IAP)를 위한 애플리케이션 준비
앱 감량