我正在尝试将pdf文件从服务器下载到设备。 这是我正在使用的代码

- (id)initwithURL:(NSString*)remoteFileLocation andFileName:(NSString*)fileName{

    //Get path to the documents folder
    NSString *resourcePathDoc = [[NSString alloc] initWithString:[[[[NSBundle mainBundle]resourcePath]stringByDeletingLastPathComponent]stringByAppendingString:@"/Documents/"]];
    localFilePath = [resourcePathDoc stringByAppendingString:fileName];

    BOOL fileExists = [[NSFileManager defaultManager]fileExistsAtPath:localFilePath];
    if (fileExists == NO) {
        NSURL *url = [NSURL URLWithString:remoteFileLocation];
        NSData *data = [[NSData alloc] initWithContentsOfURL: url];

        //Write the data to the local file
        [data writeToFile:localFilePath atomically:YES];
    }
    return self;
}

其中remoteFileLocation是一个NSString,其值为http://topoly.com/optimus/irsocial/Abs/Documents/2009-annual-report.pdf在运行应用程序崩溃时,仅在NSData上发出SIGABRT错误。 它给出的唯一有用的信息是

由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [NSURL长度]:无法识别的选择器发送到实例0xc87b600'

怎么解决这个问题?

===============>>#1 票数:3

由于你的PDF文件太大,所以如果你进行同步下载,下载时间太长,所以我坚持要你创建一个异步下载器并使用它。 我已经把相同的代码。

第1步:创建文件'FileDownloader.h'

#define FUNCTION_NAME   NSLog(@"%s",__FUNCTION__)

#import <Foundation/Foundation.h>

@protocol fileDownloaderDelegate <NSObject>

@optional
- (void)downloadProgres:(NSNumber*)percent forObject:(id)object;

@required

- (void)downloadingStarted;
- (void)downloadingFinishedFor:(NSURL *)url andData:(NSData *)data;
- (void)downloadingFailed:(NSURL *)url;

@end

@interface FileDownloader : NSObject
{

@private
    NSMutableURLRequest *_request;
    NSMutableData *downloadedData;
    NSURL *fileUrl;

    id <fileDownloaderDelegate> delegate;

    double totalFileSize;
}

@property (nonatomic, strong) NSMutableURLRequest *_request;
@property (nonatomic, strong) NSMutableData *downloadedData;
@property (nonatomic, strong) NSURL *fileUrl;

@property (nonatomic, strong) id <fileDownloaderDelegate> delegate;

- (void)downloadFromURL:(NSString *)urlString;

@end

第2步:使用FileDownloader.m创建.m文件

#import "FileDownloader.h"

@implementation FileDownloader

@synthesize _request, downloadedData, fileUrl;
@synthesize delegate;

- (void)downloadFromURL:(NSString *)urlString
{
    [self setFileUrl:[NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];

    self._request = [NSMutableURLRequest requestWithURL:self.fileUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0f];
    NSURLConnection *cn = [NSURLConnection connectionWithRequest:self._request delegate:self];
    [cn start];
}


#pragma mark - NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if([delegate respondsToSelector:@selector(downloadingStarted)])
    {
        [delegate performSelector:@selector(downloadingStarted)];
    }

    totalFileSize = [response expectedContentLength];    
    downloadedData = [NSMutableData dataWithCapacity:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [downloadedData appendData:data];

    if([delegate respondsToSelector:@selector(downloadProgres:forObject:)])
    {
        [delegate performSelector:@selector(downloadProgres:forObject:) withObject:[NSNumber numberWithFloat:([downloadedData length]/totalFileSize)] withObject:self];
    }
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    if([delegate respondsToSelector:@selector(downloadingFailed:)])
    {
        [delegate performSelector:@selector(downloadingFailed:) withObject:self.fileUrl];
    }    
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if([delegate respondsToSelector:@selector(downloadingFinishedFor:andData:)])
    {
        [delegate performSelector:@selector(downloadingFinishedFor:andData:) withObject:self.fileUrl withObject:self.downloadedData];
    }
}

@end

第3步:在fileDownloaderDelegate中导入文件#import "FileDownloader.h"和fileDownloaderDelegate

步骤4:在viewCOntroller的.m文件中定义以下Delegate方法

- (void)downloadingStarted;
- (void)downloadingFinishedFor:(NSURL *)url andData:(NSData *)data;
- (void)downloadingFailed:(NSURL *)url;

步骤5:创建FileDownloader的对象并将URL设置为Download its it。

FileDownloader *objDownloader = [[FileDownloader alloc] init];
[objDownloader setDelegate:self];
[objDownloader downloadFromURL:@"Your PDF Path URL here];

第6步:将文件保存在所需的位置- (void)downloadingFinishedFor:(NSURL *)url andData:(NSData *)data; 方法。

===============>>#2 票数:1

看来你的remoteFileLocation参数值实际上是NSURL对象而不是NSString 仔细检查你如何获得/创建remoteFileLocation并验证它是否真的是一个NSString

此代码还有其他几个问题。 创建Documents目录路径的正确方法如下:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths[0];
NSString *localFilePath = [resourcePathDoc stringByAppendingPathComponent:fileName];

BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:localFilePath];
if (!fileExists) {
    NSURL *url = [NSURL URLWithString:remoteFileLocation];
    NSData *data = [[NSData alloc] initWithContentsOfURL:url];

    //Write the data to the local file
    [data writeToFile:localFilePath atomically:YES];
}

===============>>#3 票数:0

GCD可用于海量文件。 您可以在第二个线程上下载同步文件,如果愿意,可以回发到主线程。 您还可以使用操作队列。

您确实也可以使用NSURLConnection中的委托方法,允许您处理主线程上的回调。 然而,定义自己的委托已经过时,因为您可以从NSURLConnection本身实现委托。

  ask by Ashish Agarwal translate from so

未解决问题?本站智能推荐:

关注微信公众号