Three20 - TTStyledTextLabel遇到base64图像数据而不是URL - 崩溃
问题描述:
我正在使用TTStyledTextLabel和来自XHTML数据的TTStyledText来显示新闻文章。 它工作正常,除了img是数据而不是链接,在这种情况下它崩溃!Three20 - TTStyledTextLabel遇到base64图像数据而不是URL - 崩溃
代码
TTStyledTextLabel *storyLabel = [[TTStyledTextLabel alloc] init];
[storyLabel setText: [TTStyledText textFromXHTML:[articleContents objectForKey:@"storyText"]]];
正常工作与正常的图像网址XML,
但是当它遇到这样的图像数据:
img class="alignleft" src="data:image/jpg;base64,/9j/4AAQSkZJRgA...
(lots more in here)...1HhI0T//2Q==" alt="" width="267" height="189"/
它与输出崩溃:
-[NSURLResponse allHeaderFields]: unrecognized selector
sent to instance 0xb83b370
这只发生在遇到图像数据时,否则如果是正常的img链接,它会加载正常。
谢谢!
答
在这里回答我自己的问题。
这似乎是一个罕见的情况发生(在我的具体情况)。我解决这个问题的方式是通过手动检查来查看img链接(它可能是图像数据)是否具有常见的图像文件类型扩展名(jpg,png,gif等)。如果不存在并丢弃数据,我只是无视它。
我对Web标准不太了解,以及是否认为可以将图像数据嵌入到链接应该存在的地方,但是现在我意识到它存在并可能导致使用此类的崩溃。希望这可以帮助任何有此问题的人。
答
问题是Three20 TTRequestLoader在NSURLConnectionDataDelegate方法中使用NSHTTPURLResponse而不是NSURLResponse。 NSURLResponse没有allHeaderFields方法,所以应用程序崩溃。
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response {
_response = [response retain];
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSDictionary* headers = [response allHeaderFields];
int contentLength = [[headers objectForKey:@"Content-Length"] intValue];
// If you hit this assertion it's because a massive file is about to be downloaded.
// If you're sure you want to do this, add the following line to your app delegate startup
// method. Setting the max content length to zero allows anything to go through. If you just
// want to raise the limit, set it to any positive byte size.
// [[TTURLRequestQueue mainQueue] setMaxContentLength:0]
TTDASSERT(0 == _queue.maxContentLength || contentLength <=_queue.maxContentLength);
if (contentLength > _queue.maxContentLength && _queue.maxContentLength) {
TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"MAX CONTENT LENGTH EXCEEDED (%d) %@",
contentLength, _urlPath);
[self cancel];
}
_responseData = [[NSMutableData alloc] initWithCapacity:contentLength];
}
else if ([response isKindOfClass:[NSURLResponse class]]) {
_responseData = [[NSMutableData alloc] init];
}
else {
[self cancel];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
TTNetworkRequestStopped();
if ([_response isKindOfClass:[NSHTTPURLResponse class]]) {
TTDCONDITIONLOG(TTDFLAG_ETAGS, @"Response status code: %d", _response.statusCode);
// We need to accept valid HTTP status codes, not only 200.
if (_response.statusCode >= 200 && _response.statusCode < 300) {
[_queue loader:self didLoadResponse:_response data:_responseData];
} else if (_response.statusCode == 304) {
[_queue loader:self didLoadUnmodifiedResponse:_response];
} else {
TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @" FAILED LOADING (%d) %@",
_response.statusCode, _urlPath);
NSError* error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode
userInfo:nil];
[_queue loader:self didFailLoadWithError:error];
}
}
else if ([_response isKindOfClass:[NSURLResponse class]]) {
[_queue loader:self didLoadResponse:_response data:_responseData];
}
TT_RELEASE_SAFELY(_responseData);
TT_RELEASE_SAFELY(_connection);
}
:
您可以通过检查类修复