iOS 从 url 下载 html 文件

Posted

技术标签:

【中文标题】iOS 从 url 下载 html 文件【英文标题】:iOS Download html file from url 【发布时间】:2014-09-01 08:01:55 【问题描述】:

我需要从服务器 url 下载 html 文件并替换为本地 html 文件。我正在使用 AFNetworking 下载文件并存储到 Documents 文件夹。它正在下载视频和音频文件。但是当我尝试下载 html 文件时,我遇到了错误Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x83d0730 NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
 NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"solarhtml"];

 if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath])
 [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

 [manager.requestSerializer setValue:@"application/x-www-form-urlencoded"
 forHTTPHeaderField:@"Content-Type"];

 [manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
 manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];


 [manager GET:@"http://server.net/projects/index.html"
 parameters:nil
 success:^(AFHTTPRequestOperation *operation, id responseObject) 
 [operation.responseData writeToFile:[dataPath stringByAppendingPathComponent:@"index.html"] atomically:YES];


 NSLog(@"Successfully downloaded file to %@", [NSURL fileURLWithPath:dataPath]);
 NSLog(@"THE RESPONSE: %@", responseObject);


 
 failure:^(AFHTTPRequestOperation *operation, NSError *error1) 
 NSLog(@"%@", error1);
 ];

访问html文件:

  -(void)estimatesavings:(id)sender


      if(updateclick==YES)

        web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"index.html"];

        NSURL *targetURL = [NSURL fileURLWithPath:filePath];
        NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
        [web_estimate loadRequest:request];

        web_estimate.delegate=self;

        [self.view addSubview:web_estimate];

    else


    NSString *pathToBundle = [[NSBundle mainBundle] bundlePath];
    NSURL *baseURL = [NSURL fileURLWithPath:pathToBundle];
    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
    //CGRect fullScreenRect=[[UIScreen mainScreen]applicationFrame];
    web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];
    [web_estimate loadHTMLString:htmlString baseURL:baseURL];



    web_estimate.delegate=self;
    [self.view addSubview:web_estimate];

    


    

错误:

copy failed: Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)" UserInfo=0x83c8b50 NSSourceFilePathErrorKey=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/ActewAGL.app/index.html, NSUserStringVariant=(
    Copy
), NSFilePath=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/ActewAGL.app/index.html, NSDestinationFilePath=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/Documents/solarhtml/index.html, NSUnderlyingError=0x83c89c0 "The operation couldn’t be completed. No such file or directory"c

【问题讨论】:

如果您的答案不是 JSON,为什么还要对 JSON 使用 AFJSONResponseSerializer 但我使用相同的方法从 Internet 下载 .mp4 文件。它正在工作..但为什么它不适用于 html 文件? 它正在工作..但它没有替换我的本地 html 文件。成功下载文件到file://localhost/Users/ranganathagv/Library/Application%20Support/iPhone%20Simulator/6.1/Applications/0DFCC406-FAF9-4F12-9F25-3EAE12CF7B9F/Documents/solarhtml/ 这个不需要AFNetwork,试试stringWithContentsOfURL: NSString *content = [NSString stringWithContentsOfURL:[NSURL URLWithString:requestString] encoding:NSUTF8StringEncoding error:error]; @user3743552 很难调和“它正在工作”和“它没有替换我的本地 html 文件”。这究竟是哪里失败了?你看过那个位置的那个文件吗?实际文件内容是否发生了变化(即您无法再次加载本地副本的问题)?或者文件没有​​改变(即问题是缓存还是保存失败)?它必须是其中之一。 (顺便说一句,感谢您删除重复的问题!) 【参考方案1】:

有两个问题:

    尝试使用AFJSONResponseSerializer 并更改acceptableContentTypes 将不起作用,因为AFJSONResponseSerializer 将接受响应,但仍会尝试解析JSON。相反,您应该只使用AFHTTPResponseSerializer。请参阅https://***.com/a/21621530/1271826 了解更多信息。

    另一个问题在于您的开放式例程。您应该在 Documents 文件夹中打开该文件,而不是只打开捆绑包中的文件。您甚至可能希望将文件从捆绑包复制到 Documents 文件夹(以防它尚未下载)。

    例如:

    NSString *documentsFolder  = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *solarFolder      = [documentsFolder stringByAppendingPathComponent:@"solarhtml"];
    NSString *documentsPath    = [solarFolder stringByAppendingPathComponent:@"index.html"];
    NSString *bundlePath       = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if (![fileManager fileExistsAtPath:documentsPath]) 
        NSError *error;
        if (![fileManager fileExistsAtPath:solarFolder]) 
            if (![fileManager createDirectoryAtPath:solarFolder withIntermediateDirectories:YES attributes:nil error:&error]) 
                NSLog(@"create folder failed: %@", error);
            
        
        if (![fileManager copyItemAtPath:bundlePath toPath:documentsPath error:&error]) 
            NSLog(@"copy failed: %@", error);
        
    
    
    NSString *htmlString = [NSString stringWithContentsOfFile:documentsPath encoding:NSUTF8StringEncoding error:nil];
    web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];
    [web_estimate loadHTMLString:htmlString baseURL:baseURL];
    

    这样,如果文件根本没有下载,这将在尝试打开之前从包中复制文件,如有必要。

【讨论】:

您是否创建了solarhtml 文件夹?我调整了我的代码示例来说明你可以如何做到这一点。您还需要在下载例程中使用类似的“如果 solarhtml 文件夹没有,请创建它”逻辑。

以上是关于iOS 从 url 下载 html 文件的主要内容,如果未能解决你的问题,请参考以下文章

从 URL 下载音频文件并在 iOS 应用程序中播放

如何从 Flutter 中的 URL 下载文件并将其保存在 iOS 共享文件夹中?

从 Xamarin ios 中的 url 下载图像的最佳方法是啥?

RN从IOS中的URL获取blob下载docx或pdf

如何使用 iOS8+ 的 Objective-C 从 URL 下载照片并添加到特定相册?

IOS开发-UI学习-根据URL显示图片,下载图片的练习(button,textfield,image view,url,data)