从远程 url 从 ios 应用程序下载 PDF
Posted
技术标签:
【中文标题】从远程 url 从 ios 应用程序下载 PDF【英文标题】:Downloading PDF from an ios app from remote url 【发布时间】:2014-04-21 06:57:34 【问题描述】:我正在使用下面的代码从 URL 下载 PDF,但我得到以下输出以及通知和错误。
我的 AppDelegate.h
@interface FileDownload2AppDelegate : UIResponder <UIApplicationDelegate , NSURLConnectionDataDelegate>
NSMutableData *receivedData;
@property (strong, nonatomic) UIWindow *window;
@end
我的 AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Override point for customization after application launch.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
[NSURLConnection connectionWithRequest:request delegate:self];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"/Users/awsuser8/1.txt"];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
[thedata writeToFile:localFilePath atomically:YES];
NSLog(@"PDF downloaded");
return YES;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse.
// It can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is an instance variable declared elsewhere.
[receivedData setLength:0];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
[receivedData setData:data];
[receivedData appendData:data];
NSLog(@"receivedData : %@", receivedData);
- (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:NSURLErrorFailingURLStringErrorKey]);
- (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]);
// release the connection, and the data object
// [connection release];
// [receivedData release];
获取输出:
lockdownd[53] <Notice>: 00281000 __copy_itunes_value_block_invoke: com.apple.mobile.iTunes.store/downloaded-apps -> (null)
lockdownd[53] <Notice>: 01a63000 __copy_itunes_value_block_invoke: com.apple.mobile.iTunes.store/downloaded-apps -> (null)
networkd[79] <Warning>: Analytics Engine: double ON for app: com.aasare.FileDownload2
backboardd[28] <Error>: HID: The 'Passive' connection 'FileDownload2' access to protected services is denied.
PDF downloaded
receivedData : (null)
receivedData : (null)
Succeeded! Received 0 bytes of data
【问题讨论】:
在“didReceiveData”方法中,您同时使用了 set 和 appendData。仅使用 appendData 并检查 @user2071152 尝试但得到相同的输出 下载数据是否需要任何身份验证?我们可以观察到错误“backboardd[28]您可能应该在某处实例化receivedData
。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
receivedData = [NSMutableData data];
并且您应该附加接收到的数据。
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
[receivedData appendData:data];
并且您正在下载文件两次,但您完全放弃了第二次下载。
这个代码块已经下载并保存了数据:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
[NSURLConnection connectionWithRequest:request delegate:self];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"/Users/awsuser8/1.txt"];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
[thedata writeToFile:localFilePath atomically:YES];
这在主线程上以同步方式发生。在下载过程中,该应用程序不执行任何其他操作。如果您的下载量很大,或者您的连接速度很慢,您的应用程序可能在启动之前就被终止了。
不要这样做。将文件保存代码放入connectionDidFinishLoading:
。这是处理网络请求的异步方式。这就是您应该如何处理与网络相关的所有事情。
另外,您要写入的文件不存在。 writeData:
不创建目录。您可能应该删除整个 /Users...
路径组件。或者自己创建。
例如:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Override point for customization after application launch.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://code.google.com/p/androidnetworktester/downloads/detail?name=1mb.txt"]];
[NSURLConnection connectionWithRequest:request delegate:self];
return YES;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
receivedData = [NSMutableData data];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
[receivedData appendData:data];
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *directoyPath = [documentsDirectory stringByAppendingPathComponent:@"Users/awsuser8"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:directoyPath])
if (![[NSFileManager defaultManager] createDirectoryAtPath:directoyPath withIntermediateDirectories:YES attributes:nil error:&error])
NSLog(@"Can't create directoy %@", error);
NSString *localFilePath = [directoyPath stringByAppendingPathComponent:@"1.txt"];
if (![receivedData writeToFile:localFilePath options:NSDataWritingAtomic error:&error])
NSLog(@"Can't write file. %@", error);
【讨论】:
如何摆脱这个错误尝试更改为 didReceiveData 如下:
if(!receivedData)
[receivedData setData:data];
else
[receivedData appendData:data];
【讨论】:
我没有投反对票,但如果您设置receivedData = nil
,您的代码将归结为[nil setData:data];
。有点没用。
好的,我明白了。如果答案错误或没有用,投反对票是正确的。但我只想知道提高自己的原因。谢谢以上是关于从远程 url 从 ios 应用程序下载 PDF的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用Ajax从远程服务器下载文件,而Codeigniter无法正常工作
Android 从 URL 下载 PDF,然后使用 PDF 阅读器打开它
从远程 url 加载 pdf 以作为 Mandrill 附件发送