我搜索/谷歌了很多,但无法得到关于如何在UIWebview
. 假设我在应用程序启动时将用户重定向到 UIWebview 中的注册网关(它已经处于活动状态),当用户完成注册时,应通知应用程序,并在注册时分配给用户的成功唯一 ID,该 ID 在 HTTP 响应标头中传回.
是否有任何直接的方法可以使用捕获/打印 HTTP 响应标头UIWebview
?
我搜索/谷歌了很多,但无法得到关于如何在UIWebview
. 假设我在应用程序启动时将用户重定向到 UIWebview 中的注册网关(它已经处于活动状态),当用户完成注册时,应通知应用程序,并在注册时分配给用户的成功唯一 ID,该 ID 在 HTTP 响应标头中传回.
是否有任何直接的方法可以使用捕获/打印 HTTP 响应标头UIWebview
?
没有办法从中获取响应对象UIWebView
(为此向苹果提交一个错误,id 说)
1) 通过共享的 NSURLCache
- (void)viewDidAppear:(BOOL)animated {
NSURL *u = [NSURL URLWithString:@"http://www.google.de"];
NSURLRequest *r = [NSURLRequest requestWithURL:u];
[self.webView loadRequest:r];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSCachedURLResponse *resp = [[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request];
NSLog(@"%@",[(NSHTTPURLResponse*)resp.response allHeaderFields]);
}
@end
如果这对你有用,这是理想的
别的
UIWebView
:)这将是一个糟糕的解决方法!(正如理查德在评论中指出的那样。)它确实有很大的缺点,你必须看看它在你的情况下是否是一个有效的解决方案
NSURL *u = [NSURL URLWithString:@"http://www.google.de"];
NSURLRequest *r = [NSURLRequest requestWithURL:u];
[NSURLConnection sendAsynchronousRequest:r queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *resp, NSData *d, NSError *e) {
[self.webView loadData:d MIMEType:nil textEncodingName:nil baseURL:u];
NSLog(@"%@", [(NSHTTPURLResponse*)resp allHeaderFields]);
}];
我喜欢objective-c 运行时。有什么你想做但没有 API 的吗?DM;人力资源部。
好吧,更严肃地说,这是解决方案。它将捕获从 发起的每个CFNetwork
URL 响应,这正是 UIWebView 在幕后使用的。它还将捕获 AJAX 请求、图像加载等。
对此添加过滤器可能就像对标头的内容执行正则表达式一样简单。
@implementation NSURLResponse(webViewHack)
static IMP originalImp;
static char *rot13decode(const char *input)
{
static char output[100];
char *result = output;
// rot13 decode the string
while (*input) {
if (isalpha(*input))
{
int inputCase = isupper(*input) ? 'A' : 'a';
*result = (((*input - inputCase) + 13) % 26) + inputCase;
}
else {
*result = *input;
}
input++;
result++;
}
*result = '\0';
return output;
}
+(void) load {
SEL oldSel = sel_getUid(rot13decode("_vavgJvguPSHEYErfcbafr:"));
Method old = class_getInstanceMethod(self, oldSel);
Method new = class_getInstanceMethod(self, @selector(__initWithCFURLResponse:));
originalImp = method_getImplementation(old);
method_exchangeImplementations(old, new);
}
-(id) __initWithCFURLResponse:(void *) cf {
if ((self = originalImp(self, _cmd, cf))) {
printf("-[%s %s]: %s", class_getName([self class]), sel_getName(_cmd), [[[self URL] description] UTF8String]);
if ([self isKindOfClass:[NSHTTPURLResponse class]])
{
printf(" - %s", [[[(NSHTTPURLResponse *) self allHeaderFields] description] UTF8String]);
}
printf("\n");
}
return self;
}
@end
如果您想要@Richard J. Ross III 所写的更高级的 API 代码,您需要继承 NSURLProtocol。
AnNSURLProtocol
是处理 URL 请求的对象。因此,您可以将它用于特定任务,这些任务在NSHipster和Ray Wenderlich上有更好的描述,其中包括您从响应中获取 HTTP 标头的情况。
从 NSURLProtocol 创建一个新类的子类,你的 .h 文件应该如下所示:
@interface CustomURLProtocol : NSURLProtocol <NSURLConnectionDelegate>
@property (nonatomic, strong) NSURLConnection *connection;
@end
你的 .m 文件应该有这些方法来处理你想要的
@implementation CustomURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
// Here you can add custom filters to init or not specific requests
return YES;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
// Here you can modify your request
return request;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
return [super requestIsCacheEquivalent:a toRequest:b];
}
- (void)startLoading {
// Start request
self.connection = [NSURLConnection connectionWithRequest:self.request delegate:self];
}
- (void) stopLoading {
[self.connection cancel];
self.connection = nil;
}
#pragma mark - Delegation
#pragma mark NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
// Here we go with the headers
NSDictionary *allHeaderFields = [httpResponse allHeaderFields];
}
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.client URLProtocol:self didLoadData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.client URLProtocolDidFinishLoading:self];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self.client URLProtocol:self didFailWithError:error];
}
最后要做的就是将此协议注册到加载系统,这在 AppDelegate 上很容易实现:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[NSURLProtocol registerClass:[CustomURLProtocol class]];
return YES;
}
NSHTTPURLResponse
有类似的方法
- (NSDictionary *)allHeaderFields
编辑:对不起,我没有想到UIWebView
. 如果您使用我的解决方案有效NSURLConnection
但是,如果您向您的 webview 提供 aNSURLConnection
那么您就有机会捕获包括响应标头在内的连接。