Version: 5.3 (switch to 5.4b)
Подготовка вашего приложения для "In App Purchases" (внутриигровые покупки)
Features currently not supported by Unity iOS

Настройка WWW запросов на iOS

Вы можете использовать плагин, чтобы заменить стандартный код, который 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);

Код распределяется следующим образом. Сначала мы создаём подкласс от 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

Мы можем отключить кэширование данных вернув нулевое (nil) значение из метода connection:willCacheResponse::

    - (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 скрипт добавлять не надо.

Подготовка вашего приложения для "In App Purchases" (внутриигровые покупки)
Features currently not supported by Unity iOS