我正在尝试从存储在XML Feed中的网址下载多个图片。从XML获取图像URL正常工作。但是,NSURLConnection正在创建空文件,但是如NSLog中所述接收数据。在connectionDidFinishLoading:(NSURLConnection *)connection
中,接收到数据和正确的字节,问题是如何将receivedData写入正确的文件。
-(void)parsingComplete:(XMLDataSource*)theParser
{
/* iterate through the Categories and create the
sub-directory if it does not exist
*/
for (int i = 0; i < [categories count]; i++) {
NSString *cat = [NSString stringWithFormat:@"%@/%@",BASE_DIR,[[categories objectAtIndex:i] objectForKey:@"name"]];
NSString *catName = [[categories objectAtIndex:i] objectForKey:@"name"];
NSArray *catArray = [[categories objectAtIndex:i] objectForKey:@"images"];
/* create the sub-direcotry naming it the #category# key */
if (![FILEMANAGER fileExistsAtPath:cat]) {
[FILEMANAGER createDirectoryAtPath:cat withIntermediateDirectories:NO attributes:nil error:nil];
}
//NSLog(@"\n\nCategory: %@",cat);
for (int x = 0; x < [catArray count]; x++) {
//NSLog(@"Image: %@",[[catArray objectAtIndex:x] objectForKey:@"imageUrl"]);
/* download each file to the corresponding category sub-directory */
fileOut = [NSString stringWithFormat:@"%@/%@_0%i.jpg",cat,catName,x];
NSURLRequest *imageRequest =
[NSURLRequest requestWithURL:[NSURL URLWithString:[[catArray objectAtIndex:x] objectForKey:@"imageUrl"]]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
NSURLConnection *imageConnection = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self];
int counter = 0;
//BOOL result = NO;
if(imageConnection)
{
NSLog(@"Counter: %i",counter++);
receivedData = [[NSMutableData data] retain];
/*result = */[receivedData writeToFile:fileOut atomically:YES];
}
/*
if (!result) NSLog(@"Failed"); else NSLog(@"Successful");
*/
}
}
}
#pragma mark NSURLConenction
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
// release the connection, and the data object
//[receivedData release];
}
答案 0 :(得分:3)
您必须等到连接告诉您已完成,然后才能写入数据。连接在另一个线程上处理;如果您尝试在原始线程上立即访问数据,则不会有任何内容。
您应该将writeToFile:
电话移至connectionDidFinishLoading:
的结尾,或转到您从那里拨打的其他方法。这是您知道所有数据都已收集的第一点。
我还建议在NSMutableData
中创建didRecieveResponse:
实例,以便您知道它在正确的时间可用。这将更具可读性/可理解性。您可以将委托方法视为集合“范围” - 数据仅在其中使用,因此应在其中一个内部创建。
回复你的评论:
一种可能性,因为你需要围绕这一次下载做很多事情,并且似乎没有触及GUI,就是在后台线程上运行整个parsingComplete:
方法,并使用+[NSURLConnection sendSynchronousRequest:returningResponse:error:]
。通过这种方式,您的代码将等待数据返回,然后在sendSynchronous...
调用返回后立即编写。
NSError * err;
NSURLResponse * response;
NSData * receivedData = [NSURLConnection sendSynchronousRequest:imageRequest
returningResponse:&response
error:&err];
if( !receivedData ){
/* Handle error */
}
/* Check response */
BOOL result = [receivedData writeToFile:fileOut atomically:YES];
/* check result, etc. */
答案 1 :(得分:1)
您可以使用带有标记的CustomURLConnection
在下载之前为其命名。
使用此代码,您可以制作customURLConnection
,在发出请求时为其命名,并在connectionDidFinishLoading:
#import <Foundation/Foundation.h>
@interface CustomURLConnection : NSURLConnection
{
NSString *tag;
}
@property (nonatomic, retain) NSString *tag;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)aTag;
@end
#import "CustomURLConnection.h"
@implementation CustomURLConnection
@synthesize tag;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)aTag
{
self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately];
if (self) {
self.tag = aTag;
}
return self;
}
- (void)dealloc
{
[tag release];
[super dealloc];
}
@end
然后在parsingComplete中创建连接,自定义url连接:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourURL];
[request setTimeoutInterval:3000.0];
CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:imageTag];
现在,您可以将imageName
与CustomURLConnection
标记一起使用,并将其保存在connectionDidFinishLoading:
CustomURLConnection *urlConec = (CustomURLConnection*)connection;
NSMutableData *dataFromConnection = [self dataForConnection:urlConec];
这是函数dataForConnection:
- (NSMutableData*)dataForConnection:(CustomURLConnection*)connection
{
NSMutableData *data = [receivedData objectForKey:connection.tag];
return data;
}
希望有所帮助。