可以使用插件替换 Unity 在处理 WWW 类请求时使用的默认代码。例如,通过这种方式可以更改默认缓存行为(默认情况下仅基于 URL 进行缓存)。
以下代码(在下面有更详细的描述)禁用默认缓存方法,并且除了从游戏的脚本代码指定的标头之外,还向请求添加“secret”标头字段。
// 代码放置于 Assets 文件夹中的 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];
// 假设我们出于安全原因不希望有任何缓存和 Cookie
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPShouldHandleCookies:NO];
// 假设我们希望标头中包含特殊秘密信息
[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
“action”发生在 allocRequestForHTTPMethod
中,这是通过调用超类上的同一方法启动的:
@implementation UnityWWWCustomRequestProvider
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers
{
NSMutableURLRequest* request = [super allocRequestForHTTPMethod:method url:url headers:headers];
在此处,我们禁用 iOS 完成的默认数据缓存,并禁用 Cookie:
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:
处理连接本身,它应该调用超类上的同一方法来实际获取数据。在此处,我们只是在进行连接时向控制台输出一条消息,但您可以在此处实现所需的任何东西:
- (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# 脚本中添加额外的代码。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.